From bb48fc0c598c90386e88fd5808771fd13b88e41d Mon Sep 17 00:00:00 2001 From: Rui Maciel Date: Sun, 9 Jun 2024 01:12:36 +0100 Subject: [PATCH] Byte array serialization and deserialization --- MsgPack/MsgPackDeserializer.cs | 10 ++++++++ MsgPack/MsgPackDeserializerConvert.cs | 36 +++++++++++++++++++++++++++ MsgPack/MsgPackSerializer.cs | 16 ++++++++++++ 3 files changed, 62 insertions(+) diff --git a/MsgPack/MsgPackDeserializer.cs b/MsgPack/MsgPackDeserializer.cs index b7e038f..50d7ba8 100644 --- a/MsgPack/MsgPackDeserializer.cs +++ b/MsgPack/MsgPackDeserializer.cs @@ -74,6 +74,16 @@ internal unsafe byte ReadByte() return v; } + internal unsafe byte[] ReadByteArray(uint size) + { + byte* ptr = AdvancePointer(size); + + byte[] array = new byte[size]; + Marshal.Copy((IntPtr)ptr, array, 0, (int)size); + + return array; + } + internal MsgPackCode ReadType() => (MsgPackCode)ReadByte(); internal byte ReadUInt8() => ReadByte(); diff --git a/MsgPack/MsgPackDeserializerConvert.cs b/MsgPack/MsgPackDeserializerConvert.cs index 0a59f78..97c2734 100644 --- a/MsgPack/MsgPackDeserializerConvert.cs +++ b/MsgPack/MsgPackDeserializerConvert.cs @@ -205,6 +205,42 @@ internal void SkipObjects(uint size) SkipObject(); } + internal byte[] ConvertMsgPackedTypesToByteArray(uint size) + { + byte[] array = new byte[size]; + + for (uint i = 0; i < size; ++i) + array[i] = (byte)DeserializeAsUInt32(); + + return array; + } + + public byte[] DeserializeAsByteArray() + { + MsgPackCode type = (MsgPackCode)ReadByte(); + if (type >= MsgPackCode.FixArrayMin && type <= MsgPackCode.FixArrayMax) + return ConvertMsgPackedTypesToByteArray((byte)type % 16u); + + switch (type) + { + case MsgPackCode.Bin8: + return ReadByteArray(ReadUInt8()); + case MsgPackCode.Bin16: + return ReadByteArray(ReadUInt16()); + case MsgPackCode.Bin32: + return ReadByteArray(ReadUInt32()); + case MsgPackCode.Array16: + return ConvertMsgPackedTypesToByteArray(ReadUInt16()); + case MsgPackCode.Array32: + return ConvertMsgPackedTypesToByteArray(ReadUInt16()); + } + + SkipObject(type); + throw new InvalidCastException( + $"MsgPack type {type} could not be deserialized into type {typeof(byte[])}" + ); + } + public unsafe bool DeserializeAsBool() { MsgPackCode type = ReadType(); diff --git a/MsgPack/MsgPackSerializer.cs b/MsgPack/MsgPackSerializer.cs index c58e95f..d1a7233 100644 --- a/MsgPack/MsgPackSerializer.cs +++ b/MsgPack/MsgPackSerializer.cs @@ -90,6 +90,22 @@ public void Serialize(byte v) Write(MsgPackCode.UInt8, v); } + public void Serialize(byte[] v) + { + uint size = (uint)v.Length; + + if (size <= byte.MaxValue) + Write(MsgPackCode.Bin8, unchecked((byte)size)); + else if (size <= ushort.MaxValue) + WriteBigEndian(MsgPackCode.Bin16, unchecked((ushort)size)); + else + WriteBigEndian(MsgPackCode.Bin32, size); + + EnsureCapacity(size); + Array.Copy(v, 0, m_buffer, (int)m_position, size); + m_position += size; + } + public void Serialize(short v) { if (v < 0)