예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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());
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        /// <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));
        }
예제 #14
0
        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.");
            }
        }
예제 #15
0
        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);
        }
예제 #17
0
        /// <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));
        }