Binary Reading in C#

15

Transcript of Binary Reading in C#

Page 1: Binary Reading in C#
Page 2: Binary Reading in C#

https://github.com/neuecc/Messag

ePack-CSharp/

Page 3: Binary Reading in C#

Int32 Read(byte[] bytes, int offset){

return (bytes[offset + 0] << 24)| (bytes[offset + 1] << 16)| (bytes[offset + 2] << 8)| (bytes[offset + 3]);

}

Int32 Read(byte[] bytes, int offset){

return (bytes[offset + 0])| (bytes[offset + 1] << 8)| (bytes[offset + 2] << 16)| (bytes[offset + 3] << 24);

}

unsafe int ReadInt32(byte[] bytes, intoffset){

fixed (byte* ptr = bytes){

return *(int*)(ptr + offset);}

}

Page 4: Binary Reading in C#

[StructLayout(LayoutKind.Explicit)]internal struct Float32Bits{

[FieldOffset(0)]public float Value;

[FieldOffset(0)]public Byte Byte0;

[FieldOffset(1)]public Byte Byte1;

[FieldOffset(2)]public Byte Byte2;

[FieldOffset(3)]public Byte Byte3;

}

Page 5: Binary Reading in C#

https://github.com/msgpack/msgpack/blob/master/spec.md

Page 6: Binary Reading in C#

public MessagepackType ReadMessagePackType(byte[] bytes, int offset){

var code = bytes[offset];if (0 <= code && code <= MessagePackRange.MaxFixPositiveInt){

return FixInt;}if (MessagePackRange.MinFixNegativeInt <= code){

return NegativeInt;}switch (code){

case Int8:return Int8;

case Int16:return Int16;

case Int32:return Int32;

// 以下略}

}

Page 7: Binary Reading in C#

static readonly MessagePackType[] typeLookupTable = new MessagePackType[256];

static MessagePackCode(){

for (int i = MinFixInt; i <= MaxFixInt; i++){

typeLookupTable[i] = MessagePackType.Integer;}for (int i = MinFixMap; i <= MaxFixMap; i++){

typeLookupTable[i] = MessagePackType.Map;}typeLookupTable[Nil] = MessagePackType.Nil;typeLookupTable[False] = MessagePackType.Boolean;typeLookupTable[True] = MessagePackType.Boolean;typeLookupTable[Bin8] = MessagePackType.Binary;typeLookupTable[Bin16] = MessagePackType.Binary;

// 以下略....}

Page 8: Binary Reading in C#

static readonly IMapHeaderDecoder[] mapHeaderDecoders = new IMapHeaderDecoder[MaxSize];static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize];static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize];static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize];static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize];static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize];static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize];static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize];static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize];static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize];static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize];static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize];static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize];static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize];static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize];static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize];static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize];static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize];static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize];

Page 9: Binary Reading in C#

static readonly IMapHeaderDecoder[] mapHeaderDecoders = new IMapHeaderDecoder[MaxSize];static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize];static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize];static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize];static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize];static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize];static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize];static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize];static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize];static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize];static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize];static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize];static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize];static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize];static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize];static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize];static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize];static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize];static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize];

internal interface IInt32Decoder{

Int32 Read(byte[] bytes, int offset, out int readSize);}

Page 10: Binary Reading in C#

デリゲートは楽

が、Fastestではない

Page 11: Binary Reading in C#

void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)

Page 12: Binary Reading in C#

byte[] WriteVector3(Vector3[] collection){

var bytes = new byte[collection.Length * 12];foreach (var item in collection){

WriteFloat(bytes, item.x);WriteFloat(bytes, item.y);WriteFloat(bytes, item.z);

}return bytes;

}

Page 13: Binary Reading in C#
Page 14: Binary Reading in C#

public static unsafe void SimpleMemoryCopy(void* dest, void* src, int byteCount){

var pDest = (byte*)dest;var pSrc = (byte*)src;for (int i = 0; i < byteCount; i++){

*pDest = *pSrc;pDest++;pSrc++;

}}

Page 15: Binary Reading in C#

Vector3[]を一応UnityネイティブのJsonUtilityの50倍高速にコピー可能

MessagePackの仕様内を逸脱しないように、Extension Formatを先頭識別子に埋め込むことで互換性を保ちつつ

高速化