private static void UnpackExt8(SAXInfo info) { byte length = info.binary[info.currIdx]; sbyte type = (sbyte)info.binary[info.currIdx + 1]; if (length != 12 || type != -1) { throw new UnsupportedTypeException("Unsupported msgPack ext8 format. type " + type + ", data length: " + length); } info.currIdx += 2; byte[] secondsBuffer = new byte[8]; byte[] nanosecondsBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, nanosecondsBuffer, 0, 4); Array.Copy(info.binary, info.currIdx + 4, secondsBuffer, 0, 8); info.currIdx += 12; if (BitConverter.IsLittleEndian) { Array.Reverse(secondsBuffer); Array.Reverse(nanosecondsBuffer); } UInt32 nanoseconds = BitConverter.ToUInt32(nanosecondsBuffer, 0); Int64 seconds = BitConverter.ToInt64(secondsBuffer, 0); DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); TimeSpan offset = new TimeSpan(seconds * 1000 * 1000 * 10 + nanoseconds / 100); info.Add(origin.Add(offset)); }
public static Dictionary <Object, Object> Unpack(byte[] binary, int offset, int length = 0) { SAXInfo info = new SAXInfo(binary) { currIdx = offset }; int endIndx = info.binary.Length; if (length > 0) { endIndx = Math.Min(offset + length, info.binary.Length); } try { while (endIndx > info.currIdx) { UnpackNext(info); } } catch (ArgumentOutOfRangeException e) { throw new InvalidDataException("Incomplete msgPack binary data.", e); } if (info.GetRootObject() is Dictionary <Object, Object> dict) { return(dict); } throw new InvalidDataException("MsgPack binary is not dictionary."); }
private static void UnpackFixExt4(SAXInfo info) { sbyte type = (sbyte)info.binary[info.currIdx]; if (type != -1) { throw new UnsupportedTypeException("Unsupported msgPack fix ext 4 format. type " + type); } info.currIdx++; UInt32 seconds; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 4); Array.Reverse(lengthBuffer); seconds = BitConverter.ToUInt32(lengthBuffer, 0); } else { seconds = BitConverter.ToUInt32(info.binary, info.currIdx); } info.currIdx += 4; DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); TimeSpan offset = new TimeSpan(seconds * 1000 * 1000 * 10); info.Add(origin.Add(offset)); }
public static Object Unpack(byte[] binary, int offset, out int endOffset) { if (binary == null || binary.Length == 0) { throw new InvalidDataException("MsgPack binary is empty."); } SAXInfo info = new SAXInfo(binary) { currIdx = offset }; try { UnpackNext(info); } catch (ArgumentOutOfRangeException e) { throw new InvalidDataException("Incomplete msgPack binary data.", e); } endOffset = info.currIdx; return(info.GetRootObject()); }
private static void UnpackNext(SAXInfo info) { byte sign = info.binary[info.currIdx]; info.currIdx++; if (_unpackDict.TryGetValue(sign, out UnpackItem unpacker)) { unpacker(info); } else if (sign <= 0x7f) { UnpackPositiveFixInt(info); } else if (sign <= 0x8f) { UnpackFixMap(info); } else if (sign <= 0x9f) { UnpackFixArray(info); } else if (sign <= 0xbf) { UnpackFixStr(info); } else if (sign <= 0xff) { UnpackNegativeFixInt(info); } else { throw new UnrecognizedDataException("Msgpack first byte: 0x" + sign.ToString("X2")); } }
private static void UnpackMap32(SAXInfo info) { UInt32 length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 4); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt32(lengthBuffer, 0); } else { length = BitConverter.ToUInt32(info.binary, info.currIdx); } info.currIdx += 4; ContainerInfo container = new ContainerInfo(true, (int)length); info.AddContainer(container); for (UInt32 i = 0; i < length * 2; i++) { UnpackNext(info); } info.PopContainer(); }
private static void UnpackArray16(SAXInfo info) { ushort length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[2]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 2); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt16(lengthBuffer, 0); } else { length = BitConverter.ToUInt16(info.binary, info.currIdx); } info.currIdx += 2; ContainerInfo container = new ContainerInfo(false, (int)length); info.AddContainer(container); for (ushort i = 0; i < length; i++) { UnpackNext(info); } info.PopContainer(); }
private static void UnpackBin32(SAXInfo info) { UInt32 length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 4); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt32(lengthBuffer, 0); } else { length = BitConverter.ToUInt32(info.binary, info.currIdx); } info.currIdx += 4; byte[] data = new byte[length]; Array.Copy(info.binary, info.currIdx, data, 0, length); info.currIdx += (int)length; info.Add(data); }
private static void UnpackString(SAXInfo info, int length) { UTF8Encoding utf8Encoding = new UTF8Encoding(false, true); //-- NO BOM. try { string str = utf8Encoding.GetString(info.binary, info.currIdx, length); info.currIdx += length; info.Add(str); return; } catch (ArgumentNullException ex) { throw ex; } catch (ArgumentOutOfRangeException ex) { throw ex; } catch (DecoderFallbackException) { //-- Do nothing, through the cache block. } catch (ArgumentException) { //-- Do nothing, through the cache block. } byte[] data = new byte[length]; Array.Copy(info.binary, info.currIdx, data, 0, length); info.currIdx += length; info.Add(data); }
private static void UnpackBin16(SAXInfo info) { ushort length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[2]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 2); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt16(lengthBuffer, 0); } else { length = BitConverter.ToUInt16(info.binary, info.currIdx); } info.currIdx += 2; byte[] data = new byte[length]; Array.Copy(info.binary, info.currIdx, data, 0, length); info.currIdx += length; info.Add(data); }
private static void UnpackStr8(SAXInfo info) { byte length = info.binary[info.currIdx]; info.currIdx++; UnpackString(info, length); }
private static void UnpackInt8(SAXInfo info) { sbyte value = (sbyte)info.binary[info.currIdx]; info.currIdx++; info.Add(value); }
private static void UnpackFixStr(SAXInfo info) { byte length = info.binary[info.currIdx - 1]; length &= 0x1F; UnpackString(info, length); }
private static void UnpackBin8(SAXInfo info) { byte length = info.binary[info.currIdx]; info.currIdx++; byte[] data = new byte[length]; Array.Copy(info.binary, info.currIdx, data, 0, length); info.currIdx += length; info.Add(data); }
private static void UnpackFixMap(SAXInfo info) { byte length = info.binary[info.currIdx - 1]; length &= 0x0F; ContainerInfo container = new ContainerInfo(true, (int)length); info.AddContainer(container); for (ushort i = 0; i < length * 2; i++) { UnpackNext(info); } info.PopContainer(); }
private static void UnpackFixArray(SAXInfo info) { byte length = info.binary[info.currIdx - 1]; length &= 0x0F; ContainerInfo container = new ContainerInfo(false, (int)length); info.AddContainer(container); for (byte i = 0; i < length; i++) { UnpackNext(info); } info.PopContainer(); }
private static void UnpackUInt32(SAXInfo info) { UInt32 value; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 4); Array.Reverse(lengthBuffer); value = BitConverter.ToUInt32(lengthBuffer, 0); } else { value = BitConverter.ToUInt32(info.binary, info.currIdx); } info.currIdx += 4; info.Add(value); }
private static void UnpackInt64(SAXInfo info) { Int64 value; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[8]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 8); Array.Reverse(lengthBuffer); value = BitConverter.ToInt64(lengthBuffer, 0); } else { value = BitConverter.ToInt64(info.binary, info.currIdx); } info.currIdx += 8; info.Add(value); }
private static void UnpackStr32(SAXInfo info) { UInt32 length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[4]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 4); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt32(lengthBuffer, 0); } else { length = BitConverter.ToUInt32(info.binary, info.currIdx); } info.currIdx += 4; UnpackString(info, (int)length); }
private static void UnpackStr16(SAXInfo info) { ushort length; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[2]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 2); Array.Reverse(lengthBuffer); length = BitConverter.ToUInt16(lengthBuffer, 0); } else { length = BitConverter.ToUInt16(info.binary, info.currIdx); } info.currIdx += 2; UnpackString(info, length); }
private static void UnpackFloat64(SAXInfo info) { //-- float in C# memory already is IEEE 754 double value; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[8]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 8); Array.Reverse(lengthBuffer); value = BitConverter.ToDouble(lengthBuffer, 0); } else { value = BitConverter.ToDouble(info.binary, info.currIdx); } info.currIdx += 8; info.Add(value); }
private static void UnpackFixExt8(SAXInfo info) { sbyte type = (sbyte)info.binary[info.currIdx]; if (type != -1) { throw new UnsupportedTypeException("Unsupported msgPack fix ext 8 format. type " + type); } info.currIdx++; UInt64 timeValue; if (BitConverter.IsLittleEndian) { byte[] lengthBuffer = new byte[8]; Array.Copy(info.binary, info.currIdx, lengthBuffer, 0, 8); Array.Reverse(lengthBuffer); timeValue = BitConverter.ToUInt64(lengthBuffer, 0); } else { timeValue = BitConverter.ToUInt64(info.binary, info.currIdx); } info.currIdx += 8; UInt32 nanoseconds = (UInt32)(timeValue >> 34); Int64 seconds = (Int64)(timeValue & 0x00000003FFFFFFFF); DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); TimeSpan offset = new TimeSpan(seconds * 1000 * 1000 * 10 + nanoseconds / 100); info.Add(origin.Add(offset)); }
private static void UnpackNegativeFixInt(SAXInfo info) { byte value = info.binary[info.currIdx - 1]; info.Add(value); }
//------------[ Delegate Methods ]-----------// private static void UnpackNil(SAXInfo info) { info.Add(null); }
private static void UnpackFalse(SAXInfo info) { info.Add(false); }
private static void UnpackTrue(SAXInfo info) { info.Add(true); }
private static void UnpackPositiveFixInt(SAXInfo info) { sbyte value = (sbyte)info.binary[info.currIdx - 1]; info.Add(value); }
private static void UnpackExt32(SAXInfo info) { sbyte type = (sbyte)info.binary[info.currIdx + 4]; throw new UnsupportedTypeException("Unsupported msgPack ext32 format. type " + type); }
private static void UnpackFixExt16(SAXInfo info) { sbyte type = (sbyte)info.binary[info.currIdx]; throw new UnsupportedTypeException("Unsupported msgPack fix ext 16 format. type " + type); }