Shay Shilo
Shay Shilo

Reputation: 11

Highly customized serializing

I have an object I'd like to serialize to a memory buffer, which is then sent via UART to an embedded device. I'm working in a C# environment on windows.

What I'd like to do is to create two classes that look like this:

class StatusElement
{
    byte statusPart1;
    byte statusPart2;
}

class DeviceCommand
{
    byte Address;
    byte Length;
    StatusElement[] statusElements; // Can have an arbitrary number of elements in it
}

I'd like to use a serialize, preferably something based on c# serialization, to convert the second class to a byte stream.

The problem is that the embedded device is hard-coded to accept an exact sequence (AddressByte, LengthByte .... ErrorCorrectionByte) so I cannot use the regular C# serialization, which adds serialization metadata in the stream. This also rules out other serializes like Protobuf.

So my question is: Is it possible to customize the c# serialization to get the output I need? How?

--- Update ---

Thanks everyone for the help. After consideration I’ve decided to implement my own mini-serializer, using reflection and per-type handler. More complex but gives me more flexibility and automation capabilities.

Upvotes: 0

Views: 149

Answers (2)

Renaud Bancel
Renaud Bancel

Reputation: 21

If you need only to write bytes or byte arrays, you can use the MemoryStream directly. If you want to use other .NET base types, access your Stream with a System.IO.BinaryWriter / BinaryReader. This class is used by the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter for binary serialization and deserialization.

Upvotes: 0

Rotem
Rotem

Reputation: 21947

use a MemoryStream to manully serialize your object.

private byte[] Serialize()
{
    using (var ms = new MemoryStream())
    {
        ms.WriteByte(Address);
        ms.WriteByte(Length);
        foreach (var element in statusElements)
        {
            ms.WriteByte(element.statusPart1);
            ms.WriteByte(element.statusPart2);
        }
        return ms.ToArray();
    }
}

Likewise for deserialization:

private static DeviceCommand Deserialize(byte[] input)
{
    DeviceCommand result = new DeviceCommand();
    using (var ms = new MemoryStream(input))
    {
        result.Address = ms.ReadByte();
        result.Length = ms.ReadByte();

        //assuming .Length contains the number of statusElements:
        result.statusElemetns = new StatusElement[result.Length];
        for (int i = 0; i < result.Length; i++)
        {
            result.statusElements[i] = new StatusElement();
            result.statusElements[i].statusPart1 = ms.ReadByte();
            result.statusElements[i].statusPart2 = ms.ReadByte();
        }
    }
    return result;
}

Upvotes: 1

Related Questions