design problem (binary parser)

Hello,
I'm currently

writing a part of an application which must translate a sequence of

bytes (read from a network connection) into an object instance. The

whole sequence is considered as a unique value, except for the first 2

bytes which identify the type of the value (numeric, string, or

structured), and how the value should be parsed (the value itself can

eventually be a list of values).
I was thinking of inheriting from

System.IO.BinaryReader for the parser (using a System.IO.MemoryStream

for the byte sequence), having an abstract base class for the sequence

content representation (class ContentBase), and different concrete

classes which inherit from ContentBase (for example ContentInteger,

ContentString, ContentListString, etc).
However, I can't figure how

to combine those elements to produce the correct object instance and then

parse the sequence the right way (maybe a known design pattern that I'm

missing?)... any suggestion would be appreciated :-)
thanks in advance

[1098 byte] By [Nerick] at [2007-12-27]
# 1

I've seen this problem before.

You could make use of the provider pattern here. You would have an instance of a class that creates different objects and serves them to the caller, based on a type id (in this case the two bytes from your binary stream). That same provider can also contain the logic for parsing the rest of the binary value and place the result in the created object.

JonathanvandeVeen at 2007-9-4 > top of Msdn Tech,Architecture,Architecture General...
# 2

Hi Nerick

can I ask what's wrong with the .NET built-in binary serializer/deserializer?

DiegoDagum at 2007-9-4 > top of Msdn Tech,Architecture,Architecture General...
# 3
I wasn't aware of this concept of object serialization, thanks (I'll have a look in detail later).
Anyway I managed to work it out properly by inheriting from the BinaryReader class of the .NET framework (also the endian order for the 16bits and 32bits value types needed to be changed, wich I could do by overriding BinaryReader.ReadInt16 and BinaryReader.ReadInt32).

In the inherited BinaryParser, I added a method for each concrete type to read:
public ContentInteger ReadContentInteger();
public ContentString ReadContentString();

public ContentListString ReadContentListString();
etc.

The thing that looks dirty with this solution is for the astract class:
public Content ReadContent()
{
ContentType id = (ContentType)ReadInt16();
BaseStream.Seek(StreamPosition.Current, -2);
switch (id)
{
case ContentType.Integer:
return ReadContentInteger();
case ContentType.String:

return ReadContentString();

case ContentType.ListString:

return ReadContentListString();

[...]
}
}

but as a temporary solution I guess it could do (even if it's ugly)

Nerick at 2007-9-4 > top of Msdn Tech,Architecture,Architecture General...