private static object Deserialize(byte[] serializedContent) { var code = MessagePackBinary.GetMessagePackType(serializedContent, 0); if (code == MessagePackType.Extension) { // The message was added to the queue using Picton's QueueManager. // Therefore we know exactly how to deserialize the content. var header = MessagePackBinary.ReadExtensionFormatHeader(serializedContent, 0, out var readSize); if (header.TypeCode == LZ4_MESSAGEPACK_SERIALIZATION || header.TypeCode == TYPELESS_MESSAGEPACK_SERIALIZATION) { var envelope = (MessageEnvelope)LZ4MessagePackSerializer.Typeless.Deserialize(serializedContent); return(envelope.Content); } else { throw new Exception($"Picton is unable to deserialize content using serialization method '{header.TypeCode}'"); } } else { // The message was added to the queue using the CloudQueue class in Microsoft's Azure Storage nuget package // Therefore we can't be sure if the content is a string or binary. try { return(UTF8_ENCODER.GetString(serializedContent, 0, serializedContent.Length)); } catch { return(serializedContent); } } }
public static byte[] UnpackDataIfRequired(byte[] bytes) { if (MessagePackBinary.GetMessagePackType(bytes, 0) == MessagePackType.Extension) { var header = MessagePackBinary.ReadExtensionFormatHeader(bytes, 0, out var readSize); if (header.TypeCode == ExtensionTypeCode) { // decode lz4 int offset = readSize; int length = MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; byte[] buffer = GetLz4Buffer(); if (buffer.Length < length) { buffer = new byte[length]; } // LZ4 Decode int len = bytes.Length - offset; LZ4Codec.Decode(bytes, offset, len, buffer, 0, length); return(buffer); } } return(bytes); }
public object Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { if (MessagePackBinary.IsNil(bytes, offset)) { readSize = 1; return(null); } int startOffset = offset; var packType = MessagePackBinary.GetMessagePackType(bytes, offset); switch (packType) { case MessagePackType.Extension: { var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (ext.TypeCode == TypelessFormatter.ExtensionTypeCode) { // it has type name serialized offset += readSize; var typeName = MessagePackBinary.ReadString(bytes, offset, out readSize); offset += readSize; var result = DeserializeByTypeName(typeName, bytes, offset, formatterResolver, out readSize); offset += readSize; readSize = offset - startOffset; return(result); } break; } } // fallback return(DynamicObjectTypeFallbackFormatter.Instance.Deserialize(bytes, startOffset, formatterResolver, out readSize)); }
public object Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { if (MessagePackBinary.IsNil(bytes, offset)) { readSize = 1; return(null); } int startOffset = offset; var packType = MessagePackBinary.GetMessagePackType(bytes, offset); if (packType == MessagePackType.Extension) { var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (ext.TypeCode == TypelessFormatter.ExtensionTypeCode) { // it has type name serialized offset += readSize; var typeName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); offset += readSize; var result = DeserializeByTypeName(typeName, bytes, offset, formatterResolver, out readSize); offset += readSize; readSize = offset - startOffset; return(result); } } // fallback return(Resolvers.ContractlessStandardResolver.Instance.GetFormatter <object>().Deserialize(bytes, startOffset, formatterResolver, out readSize)); }
public unsafe T[] Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { if (MessagePackBinary.IsNil(bytes, offset)) { readSize = 1; return(null); } var startOffset = offset; var header = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); offset += readSize; if (header.TypeCode != TypeCode) { throw new InvalidOperationException("Invalid typeCode."); } var byteLength = MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; var isLittleEndian = MessagePackBinary.ReadBoolean(bytes, offset, out readSize); offset += readSize; if (isLittleEndian != BitConverter.IsLittleEndian) { Array.Reverse(bytes, offset, byteLength); } var result = new T[byteLength / StructLength]; ulong handle1; var dstPointer = UnsafeUtility.PinGCArrayAndGetDataAddress(result, out handle1); try { fixed(void *srcPointer = &bytes[offset]) { UnsafeUtility.MemCpy(dstPointer, srcPointer, byteLength); } } finally { UnsafeUtility.ReleaseGCObject(handle1); } offset += byteLength; readSize = offset - startOffset; return(result); }
public void CompressionData() { var originalData = Enumerable.Range(1, 1000).Select(x => x).ToArray(); var lz4Data = LZ4MessagePackSerializer.Serialize(originalData); MessagePackBinary.GetMessagePackType(lz4Data, 0).Is(MessagePackType.Extension); int r; var header = MessagePackBinary.ReadExtensionFormatHeader(lz4Data, 0, out r); header.TypeCode.Is((sbyte)LZ4MessagePackSerializer.ExtensionTypeCode); var decompress = LZ4MessagePackSerializer.Deserialize <int[]>(lz4Data); decompress.IsCollection(originalData); }
/// <summary> /// Database diagnostics. If allowDump = true, can use MemoryAnalysis.DumpRows(but if true, holds the raw byte[] in memory). /// </summary> public static MemoryAnalysis[] ReportDiagnostics(byte[] bytes, bool allowDump = false) { var list = new List <MemoryAnalysis>(); var db = Database.Open(bytes); foreach (var item in db.memories) { var offset = 0; int readSize; var rawMemory = item.Value as InternalRawMemory; // is LZ4 or plain msgpack? byte[] decodedBytes; int count; var type = MessagePackBinary.GetMessagePackType(rawMemory.RawMemory, offset); if (type == MessagePackType.Extension) { var extensionOffset = offset; var ext = MessagePackBinary.ReadExtensionFormatHeader(rawMemory.RawMemory, offset, out readSize); if (ext.TypeCode == LZ4MessagePackSerializer.ExtensionTypeCode) { var extHeader = MessagePackBinary.ReadExtensionFormatHeader(rawMemory.RawMemory, 0, out readSize); offset += readSize; var decodedLength = MessagePackBinary.ReadInt32(rawMemory.RawMemory, offset, out readSize); offset += readSize; decodedBytes = new byte[decodedLength]; MessagePack.LZ4.LZ4Codec.Decode(rawMemory.RawMemory, offset, rawMemory.RawMemory.Length - offset, decodedBytes, 0, decodedBytes.Length); count = MessagePackBinary.ReadArrayHeader(decodedBytes, 0, out readSize); goto END; } } decodedBytes = rawMemory.RawMemory; count = MessagePackBinary.ReadArrayHeader(decodedBytes, offset, out readSize); END: var analysis = new MemoryAnalysis(item.Key, count, rawMemory.RawMemory.Length, allowDump ? decodedBytes : null); list.Add(analysis); } return(list.ToArray()); }
public void NonGenericAPI() { var originalData = Enumerable.Range(1, 100).Select(x => new FirstSimpleData { Prop1 = x * x, Prop2 = "hoge", Prop3 = x }).ToArray(); var lz4Data = LZ4MessagePackSerializer.NonGeneric.Serialize(typeof(FirstSimpleData[]), originalData); MessagePackBinary.GetMessagePackType(lz4Data, 0).Is(MessagePackType.Extension); int r; var header = MessagePackBinary.ReadExtensionFormatHeader(lz4Data, 0, out r); header.TypeCode.Is((sbyte)LZ4MessagePackSerializer.ExtensionTypeCode); var decompress = LZ4MessagePackSerializer.NonGeneric.Deserialize(typeof(FirstSimpleData[]), lz4Data); decompress.IsStructuralEqual(originalData); }
static T DeserializeWithLengthPrefixExt <T>(Stream stream, IFormatterResolver resolver) { const int ExtTypeCode = 111; // sample ext code var header = MessagePackBinary.ReadExtensionFormatHeader(stream); if (header.TypeCode == ExtTypeCode) { // memo, read fully var buffer = new byte[1024]; stream.Read(buffer, 0, (int)header.Length); return(resolver.GetFormatter <T>().Deserialize(buffer, 0, resolver, out var _)); } else { throw new Exception(); } }
/// <summary> /// Get the war memory pool byte[]. The result can not share across thread and can not hold and can not call LZ4Deserialize before use it. /// </summary> public static byte[] DecodeUnsafe(ArraySegment <byte> bytes) { int readSize; if (MessagePackBinary.GetMessagePackType(bytes.Array, bytes.Offset) == MessagePackType.Extension) { var header = MessagePackBinary.ReadExtensionFormatHeader(bytes.Array, bytes.Offset, out readSize); if (header.TypeCode == ExtensionTypeCode) { // decode lz4 var offset = bytes.Offset + readSize; var length = MessagePackBinary.ReadInt32(bytes.Array, offset, out readSize); offset += readSize; var buffer = LZ4MemoryPool.GetBuffer(); // use LZ4 Pool(Unsafe) if (buffer.Length < length) { buffer = new byte[length]; } // LZ4 Decode var len = bytes.Count + bytes.Offset - offset; LZ4Codec.Decode(bytes.Array, offset, len, buffer, 0, length); return(buffer); // return pooled bytes. } } if (bytes.Offset == 0 && bytes.Array.Length == bytes.Count) { // return same reference return(bytes.Array); } else { var result = new byte[bytes.Count]; Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length); return(result); } }
public T[] Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { if (MessagePackBinary.IsNil(bytes, offset)) { readSize = 1; return(null); } var startOffset = offset; var header = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); offset += readSize; if (header.TypeCode != TypeCode) { throw new InvalidOperationException("Invalid typeCode."); } var byteLength = MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; var isLittleEndian = MessagePackBinary.ReadBoolean(bytes, offset, out readSize); offset += readSize; if (isLittleEndian != BitConverter.IsLittleEndian) { Array.Reverse(bytes, offset, byteLength); } var result = new T[byteLength / StructLength]; Unsafe.CopyBlockUnaligned(ref Unsafe.As <T, byte>(ref result[0]), ref bytes[offset], (uint)byteLength); offset += byteLength; readSize = offset - startOffset; return(result); }
/// <summary> /// Dump message-pack binary to JSON string. /// </summary> public static string ToJson(byte[] bytes) { if (bytes == null || bytes.Length == 0) { return(""); } int readSize; if (MessagePackBinary.GetMessagePackType(bytes, 0) == MessagePackType.Extension) { var header = MessagePackBinary.ReadExtensionFormatHeader(bytes, 0, out readSize); if (header.TypeCode == ExtensionTypeCode) { // decode lz4 var offset = readSize; var length = MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; var buffer = LZ4MemoryPool.GetBuffer(); if (buffer.Length < length) { buffer = new byte[length]; } // LZ4 Decode LZ4Codec.Decode(bytes, offset, bytes.Length - offset, buffer, 0, length); bytes = buffer; // use LZ4 bytes } } var sb = new StringBuilder(); ToJsonCore(bytes, 0, sb); return(sb.ToString()); }
static T DeserializeCore <T>(ArraySegment <byte> bytes, IFormatterResolver resolver) { if (resolver == null) { resolver = MessagePackSerializer.DefaultResolver; } var formatter = resolver.GetFormatterWithVerify <T>(); int readSize; if (MessagePackBinary.GetMessagePackType(bytes.Array, bytes.Offset) == MessagePackType.Extension) { var header = MessagePackBinary.ReadExtensionFormatHeader(bytes.Array, bytes.Offset, out readSize); if (header.TypeCode == ExtensionTypeCode) { // decode lz4 var offset = bytes.Offset + readSize; var length = MessagePackBinary.ReadInt32(bytes.Array, offset, out readSize); offset += readSize; var buffer = LZ4MemoryPool.GetBuffer(); // use LZ4 Pool if (buffer.Length < length) { buffer = new byte[length]; } // LZ4 Decode var len = bytes.Count + bytes.Offset - offset; LZ4Codec.Decode(bytes.Array, offset, len, buffer, 0, length); return(formatter.Deserialize(buffer, 0, resolver, out readSize)); } } return(formatter.Deserialize(bytes.Array, bytes.Offset, resolver, out readSize)); }
public object Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { var type = MessagePackBinary.GetMessagePackType(bytes, offset); switch (type) { case MessagePackType.Integer: var code = bytes[offset]; if (MessagePackCode.MinNegativeFixInt <= code && code <= MessagePackCode.MaxNegativeFixInt) { return(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (MessagePackCode.MinFixInt <= code && code <= MessagePackCode.MaxFixInt) { return(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int8) { return(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int16) { return(MessagePackBinary.ReadInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int32) { return(MessagePackBinary.ReadInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int64) { return(MessagePackBinary.ReadInt64(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt8) { return(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt16) { return(MessagePackBinary.ReadUInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt32) { return(MessagePackBinary.ReadUInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt64) { return(MessagePackBinary.ReadUInt64(bytes, offset, out readSize)); } throw new InvalidOperationException("Invalid primitive bytes."); case MessagePackType.Boolean: return(MessagePackBinary.ReadBoolean(bytes, offset, out readSize)); case MessagePackType.Float: if (MessagePackCode.Float32 == bytes[offset]) { return(MessagePackBinary.ReadSingle(bytes, offset, out readSize)); } else { return(MessagePackBinary.ReadDouble(bytes, offset, out readSize)); } case MessagePackType.String: return(MessagePackBinary.ReadString(bytes, offset, out readSize)); case MessagePackType.Binary: return(MessagePackBinary.ReadBytes(bytes, offset, out readSize)); case MessagePackType.Extension: var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (ext.TypeCode == ReservedMessagePackExtensionTypeCode.DateTime) { return(MessagePackBinary.ReadDateTime(bytes, offset, out readSize)); } throw new InvalidOperationException("Invalid primitive bytes."); case MessagePackType.Array: { var length = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); var startOffset = offset; offset += readSize; var objectFormatter = formatterResolver.GetFormatter <object>(); var array = new object[length]; for (int i = 0; i < length; i++) { array[i] = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize); offset += readSize; } readSize = offset - startOffset; return(array); } case MessagePackType.Map: { var length = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); var startOffset = offset; offset += readSize; var objectFormatter = formatterResolver.GetFormatter <object>(); var hash = new Dictionary <object, object>(length); for (int i = 0; i < length; i++) { var key = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize); offset += readSize; var value = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize); offset += readSize; hash.Add(key, value); } readSize = offset - startOffset; return(hash); } case MessagePackType.Nil: readSize = 1; return(null); default: throw new InvalidOperationException("Invalid primitive bytes."); } }
static int ToJsonCore(byte[] bytes, int offset, StringBuilder builder) { var readSize = 0; var type = MessagePackBinary.GetMessagePackType(bytes, offset); switch (type) { case MessagePackType.Integer: var code = bytes[offset]; if (MessagePackCode.MinNegativeFixInt <= code && code <= MessagePackCode.MaxNegativeFixInt) { builder.Append(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (MessagePackCode.MinFixInt <= code && code <= MessagePackCode.MaxFixInt) { builder.Append(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int8) { builder.Append(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int16) { builder.Append(MessagePackBinary.ReadInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int32) { builder.Append(MessagePackBinary.ReadInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int64) { builder.Append(MessagePackBinary.ReadInt64(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt8) { builder.Append(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt16) { builder.Append(MessagePackBinary.ReadUInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt32) { builder.Append(MessagePackBinary.ReadUInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt64) { builder.Append(MessagePackBinary.ReadUInt64(bytes, offset, out readSize)); } break; case MessagePackType.Boolean: builder.Append(MessagePackBinary.ReadBoolean(bytes, offset, out readSize) ? "true" : "false"); break; case MessagePackType.Float: var floatCode = bytes[offset]; if (floatCode == MessagePackCode.Float32) { builder.Append(MessagePackBinary.ReadSingle(bytes, offset, out readSize).ToString(System.Globalization.CultureInfo.InvariantCulture)); } else { builder.Append(MessagePackBinary.ReadDouble(bytes, offset, out readSize).ToString(System.Globalization.CultureInfo.InvariantCulture)); } break; case MessagePackType.String: WriteJsonString(MessagePackBinary.ReadString(bytes, offset, out readSize), builder); break; case MessagePackType.Binary: builder.Append("\"" + Convert.ToBase64String(MessagePackBinary.ReadBytes(bytes, offset, out readSize)) + "\""); break; case MessagePackType.Array: { var length = MessagePackBinary.ReadArrayHeaderRaw(bytes, offset, out readSize); var totalReadSize = readSize; offset += readSize; builder.Append("["); for (int i = 0; i < length; i++) { readSize = ToJsonCore(bytes, offset, builder); offset += readSize; totalReadSize += readSize; if (i != length - 1) { builder.Append(","); } } builder.Append("]"); return(totalReadSize); } case MessagePackType.Map: { var length = MessagePackBinary.ReadMapHeaderRaw(bytes, offset, out readSize); var totalReadSize = readSize; offset += readSize; builder.Append("{"); for (int i = 0; i < length; i++) { // write key { var keyType = MessagePackBinary.GetMessagePackType(bytes, offset); if (keyType == MessagePackType.String || keyType == MessagePackType.Binary) { readSize = ToJsonCore(bytes, offset, builder); } else { builder.Append("\""); readSize = ToJsonCore(bytes, offset, builder); builder.Append("\""); } offset += readSize; totalReadSize += readSize; } builder.Append(":"); // write body { readSize = ToJsonCore(bytes, offset, builder); offset += readSize; totalReadSize += readSize; } if (i != length - 1) { builder.Append(","); } } builder.Append("}"); return(totalReadSize); } case MessagePackType.Extension: var extHeader = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (extHeader.TypeCode == ReservedMessagePackExtensionTypeCode.DateTime) { var dt = MessagePackBinary.ReadDateTime(bytes, offset, out readSize); builder.Append("\""); builder.Append(dt.ToString("o", CultureInfo.InvariantCulture)); builder.Append("\""); } else { var ext = MessagePackBinary.ReadExtensionFormat(bytes, offset, out readSize); builder.Append("["); builder.Append(ext.TypeCode); builder.Append(","); builder.Append("\""); builder.Append(Convert.ToBase64String(ext.Data)); builder.Append("\""); builder.Append("]"); } break; case MessagePackType.Unknown: case MessagePackType.Nil: default: readSize = 1; builder.Append("null"); break; } return(readSize); }
static int ToJsonCore(byte[] bytes, int offset, StringBuilder builder) { var readSize = 0; var type = MessagePackBinary.GetMessagePackType(bytes, offset); switch (type) { case MessagePackType.Integer: var code = bytes[offset]; if (MessagePackCode.MinNegativeFixInt <= code && code <= MessagePackCode.MaxNegativeFixInt) { builder.Append(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (MessagePackCode.MinFixInt <= code && code <= MessagePackCode.MaxFixInt) { builder.Append(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int8) { builder.Append(MessagePackBinary.ReadSByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int16) { builder.Append(MessagePackBinary.ReadInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int32) { builder.Append(MessagePackBinary.ReadInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.Int64) { builder.Append(MessagePackBinary.ReadInt64(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt8) { builder.Append(MessagePackBinary.ReadByte(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt16) { builder.Append(MessagePackBinary.ReadUInt16(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt32) { builder.Append(MessagePackBinary.ReadUInt32(bytes, offset, out readSize)); } else if (code == MessagePackCode.UInt64) { builder.Append(MessagePackBinary.ReadUInt64(bytes, offset, out readSize)); } break; case MessagePackType.Boolean: builder.Append(MessagePackBinary.ReadBoolean(bytes, offset, out readSize) ? "true" : "false"); break; case MessagePackType.Float: var floatCode = bytes[offset]; if (floatCode == MessagePackCode.Float32) { builder.Append(MessagePackBinary.ReadSingle(bytes, offset, out readSize).ToString(System.Globalization.CultureInfo.InvariantCulture)); } else { builder.Append(MessagePackBinary.ReadDouble(bytes, offset, out readSize).ToString(System.Globalization.CultureInfo.InvariantCulture)); } break; case MessagePackType.String: WriteJsonString(MessagePackBinary.ReadString(bytes, offset, out readSize), builder); break; case MessagePackType.Binary: builder.Append("\"" + Convert.ToBase64String(MessagePackBinary.ReadBytes(bytes, offset, out readSize)) + "\""); break; case MessagePackType.Array: { var length = MessagePackBinary.ReadArrayHeaderRaw(bytes, offset, out readSize); var totalReadSize = readSize; offset += readSize; builder.Append("["); for (int i = 0; i < length; i++) { readSize = ToJsonCore(bytes, offset, builder); offset += readSize; totalReadSize += readSize; if (i != length - 1) { builder.Append(","); } } builder.Append("]"); return(totalReadSize); } case MessagePackType.Map: { var length = MessagePackBinary.ReadMapHeaderRaw(bytes, offset, out readSize); var totalReadSize = readSize; offset += readSize; builder.Append("{"); for (int i = 0; i < length; i++) { // write key { var keyType = MessagePackBinary.GetMessagePackType(bytes, offset); if (keyType == MessagePackType.String || keyType == MessagePackType.Binary) { readSize = ToJsonCore(bytes, offset, builder); } else { builder.Append("\""); readSize = ToJsonCore(bytes, offset, builder); builder.Append("\""); } offset += readSize; totalReadSize += readSize; } builder.Append(":"); // write body { readSize = ToJsonCore(bytes, offset, builder); offset += readSize; totalReadSize += readSize; } if (i != length - 1) { builder.Append(","); } } builder.Append("}"); return(totalReadSize); } case MessagePackType.Extension: var extHeader = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (extHeader.TypeCode == ReservedMessagePackExtensionTypeCode.DateTime) { var dt = MessagePackBinary.ReadDateTime(bytes, offset, out readSize); builder.Append("\""); builder.Append(dt.ToString("o", CultureInfo.InvariantCulture)); builder.Append("\""); } #if NETSTANDARD || NETFRAMEWORK else if (extHeader.TypeCode == TypelessFormatter.ExtensionTypeCode) { int startOffset = offset; // prepare type name token offset += 6; var typeNameToken = new StringBuilder(); var typeNameReadSize = ToJsonCore(bytes, offset, typeNameToken); offset += typeNameReadSize; int startBuilderLength = builder.Length; if (extHeader.Length > typeNameReadSize) { // object map or array var typeInside = MessagePackBinary.GetMessagePackType(bytes, offset); if (typeInside != MessagePackType.Array && typeInside != MessagePackType.Map) { builder.Append("{"); } offset += ToJsonCore(bytes, offset, builder); // insert type name token to start of object map or array if (typeInside != MessagePackType.Array) { typeNameToken.Insert(0, "\"$type\":"); } if (typeInside != MessagePackType.Array && typeInside != MessagePackType.Map) { builder.Append("}"); } if (builder.Length - startBuilderLength > 2) { typeNameToken.Append(","); } builder.Insert(startBuilderLength + 1, typeNameToken.ToString()); } else { builder.Append("{\"$type\":\"" + typeNameToken.ToString() + "}"); } readSize = offset - startOffset; } #endif else { var ext = MessagePackBinary.ReadExtensionFormat(bytes, offset, out readSize); builder.Append("["); builder.Append(ext.TypeCode); builder.Append(","); builder.Append("\""); builder.Append(Convert.ToBase64String(ext.Data)); builder.Append("\""); builder.Append("]"); } break; case MessagePackType.Unknown: case MessagePackType.Nil: default: readSize = 1; builder.Append("null"); break; } return(readSize); }
/// <summary> /// Open the database. /// </summary> public static Database Open(byte[] bytes) { var offset = 0; int readSize; var memoryCount = MessagePackBinary.ReadArrayHeader(bytes, 0, out readSize); offset += readSize; var memories = new KeyValuePair <string, IInternalMemory> [memoryCount]; for (int i = 0; i < memoryCount; i++) { var len = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); offset += readSize; if (len != 2) { throw new InvalidOperationException("Invalid MsgPack Binary of Database."); } var keyName = MessagePackBinary.ReadString(bytes, offset, out readSize); offset += readSize; // is LZ4 or plain msgpack? byte[] rawData; var type = MessagePackBinary.GetMessagePackType(bytes, offset); if (type == MessagePackType.Extension) { var extensionOffset = offset; var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize); if (ext.TypeCode == LZ4MessagePackSerializer.ExtensionTypeCode) { offset += readSize; offset += (int)ext.Length; rawData = new byte[offset - extensionOffset]; Buffer.BlockCopy(bytes, extensionOffset, rawData, 0, rawData.Length); goto END; } } { var beginOffset = offset; var arrayLen = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); offset += readSize; for (int j = 0; j < arrayLen; j++) { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } readSize = offset - beginOffset; rawData = new byte[readSize]; Buffer.BlockCopy(bytes, beginOffset, rawData, 0, readSize); } END: var memory = new InternalRawMemory(rawData); memories[i] = new KeyValuePair <string, IInternalMemory>(keyName, memory); } return(new Database(memories)); }