Skip to content

Commit

Permalink
(BreakingChanges) UnsafeBlitResolver write valid msgpack binary
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jan 11, 2019
1 parent c6fafa2 commit 17431b1
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,29 +167,27 @@ public UnsafeDirectBlitFormatter()

public unsafe int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
{
// Note: require byte header? maybe this is not valid msgpack-format.
var headerSize = MessagePackBinaryEx.WriteBytesHeaderWithEnsureCount(ref bytes, offset, size);

MessagePackBinary.EnsureCapacity(ref bytes, offset, size);

fixed (void* p = &bytes[offset])
fixed (void* p = &bytes[offset + headerSize])
{
UnsafeUtility.CopyStructureToPtr(ref value, p);
}

return size;
return headerSize + size;
}

public unsafe T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
{
ValidateRead(bytes, offset);
var segment = MessagePackBinary.ReadBytesSegment(bytes, offset, out readSize);
ValidateRead(segment.Array, segment.Offset);

T value;
fixed (void* p = &bytes[offset])
fixed (void* p = &segment.Array[segment.Offset])
{
UnsafeUtility.CopyPtrToStructure<T>(p, out value);
}

readSize = size;
return value;
}

Expand All @@ -201,6 +199,47 @@ void ValidateRead(byte[] bytes, int offset)
}
}
}

internal static class MessagePackBinaryEx
{
public static int WriteBytesHeaderWithEnsureCount(ref byte[] dest, int dstOffset, int count)
{
if (count <= byte.MaxValue)
{
var size = 2;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
dest[dstOffset] = MessagePackCode.Bin8;
dest[dstOffset + 1] = (byte)count;
return size;
}
else if (count <= UInt16.MaxValue)
{
var size = 3;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
unchecked
{
dest[dstOffset] = MessagePackCode.Bin16;
dest[dstOffset + 1] = (byte)(count >> 8);
dest[dstOffset + 2] = (byte)(count);
}
return size;
}
else
{
var size = 5;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
unchecked
{
dest[dstOffset] = MessagePackCode.Bin32;
dest[dstOffset + 1] = (byte)(count >> 24);
dest[dstOffset + 2] = (byte)(count >> 16);
dest[dstOffset + 3] = (byte)(count >> 8);
dest[dstOffset + 4] = (byte)(count);
}
return size;
}
}
}
}

#endif
56 changes: 47 additions & 9 deletions src/MagicOnion/UnsafeDirectBlitResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,17 @@ public UnsafeDirectBlitFormatter()

public unsafe int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
{
// Note: require byte header? maybe this is not valid msgpack-format.

MessagePackBinary.EnsureCapacity(ref bytes, offset, size);
Unsafe.WriteUnaligned(ref Unsafe.Add(ref bytes[0], offset), value);
return size;
var headerSize = MessagePackBinaryEx.WriteBytesHeaderWithEnsureCount(ref bytes, offset, size);
Unsafe.WriteUnaligned(ref Unsafe.Add(ref bytes[0], offset + headerSize), value);
return headerSize + size;
}

public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
{
ValidateRead(bytes, offset);
var segment = MessagePackBinary.ReadBytesSegment(bytes, offset, out readSize);
ValidateRead(segment.Array, segment.Offset);

var value = Unsafe.ReadUnaligned<T>(ref bytes[offset]);
readSize = size;
return value;
return Unsafe.ReadUnaligned<T>(ref segment.Array[segment.Offset]);
}

void ValidateRead(byte[] bytes, int offset)
Expand All @@ -162,4 +159,45 @@ void ValidateRead(byte[] bytes, int offset)
}
}
}

internal static class MessagePackBinaryEx
{
public static int WriteBytesHeaderWithEnsureCount(ref byte[] dest, int dstOffset, int count)
{
if (count <= byte.MaxValue)
{
var size = 2;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
dest[dstOffset] = MessagePackCode.Bin8;
dest[dstOffset + 1] = (byte)count;
return size;
}
else if (count <= UInt16.MaxValue)
{
var size = 3;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
unchecked
{
dest[dstOffset] = MessagePackCode.Bin16;
dest[dstOffset + 1] = (byte)(count >> 8);
dest[dstOffset + 2] = (byte)(count);
}
return size;
}
else
{
var size = 5;
MessagePackBinary.EnsureCapacity(ref dest, dstOffset, size + count);
unchecked
{
dest[dstOffset] = MessagePackCode.Bin32;
dest[dstOffset + 1] = (byte)(count >> 24);
dest[dstOffset + 2] = (byte)(count >> 16);
dest[dstOffset + 3] = (byte)(count >> 8);
dest[dstOffset + 4] = (byte)(count);
}
return size;
}
}
}
}

0 comments on commit 17431b1

Please sign in to comment.