Ejemplo n.º 1
0
        public void GetEncodedStringBytes(char c, int count)
        {
            var s          = new string(c, count);
            var bin1       = CodeGenHelpers.GetEncodedStringBytes(s);
            var bin2       = MessagePackSerializer.Serialize(s);
            var bin3       = new Sequence <byte>();
            var bin3Writer = new MessagePackWriter(bin3);

            bin3Writer.WriteRaw(bin1);
            bin3Writer.Flush();

            new ReadOnlySpan <byte>(bin1).SequenceEqual(bin2).IsTrue();
            new ReadOnlySpan <byte>(bin1).SequenceEqual(CodeGenHelpers.GetSpanFromSequence(bin3)).IsTrue();
        }
        public void GetEncodedStringBytes(char c, int count)
        {
            var s          = new string(c, count);
            var bin1       = CodeGenHelpers.GetEncodedStringBytes(s);
            var bin2       = MessagePackSerializer.Serialize(s);
            var bin3       = new Sequence <byte>();
            var bin3Writer = new MessagePackWriter(bin3);

            bin3Writer.WriteRaw(bin1);
            bin3Writer.Flush();

            MessagePack.Internal.ByteArrayComparer.Equals(bin1, bin2).IsTrue();
            MessagePack.Internal.ByteArrayComparer.Equals(bin1, CodeGenHelpers.GetSpanFromSequence(bin3)).IsTrue();
        }
        static void EmitSerializeUnionCase(
            ILGenerator il,
            Type type,
            TypeInfo ti,
            UnionSerializationInfo info,
            FieldBuilder stringByteKeysField,
            ArgumentField argWriter,
            ArgumentField argValue,
            ArgumentField argOptions,
            LocalBuilder localResolver
            )
        {
            if (info.IsIntKey)
            {
                // use Array
                var maxKey    = info.Members.Select(x => x.IntKey).DefaultIfEmpty(-1).Max();
                var intKeyMap = info.Members.ToDictionary(x => x.IntKey);

                var len = maxKey + 1;
                argWriter.EmitLoad();
                il.EmitLdc_I4(len);
                il.EmitCall(MessagePackWriterTypeInfo.WriteArrayHeader);

                var index = 0;
                for (int i = 0; i <= maxKey; i++)
                {
                    UnionSerializationInfo.EmittableMember member;
                    if (intKeyMap.TryGetValue(i, out member))
                    {
                        EmitSerializeValue(il, ti, member, index++, argWriter, argValue, argOptions, localResolver);
                    }
                    else
                    {
                        // Write Nil as Blanc
                        argWriter.EmitLoad();
                        il.EmitCall(MessagePackWriterTypeInfo.WriteNil);
                    }
                }
            }
            else
            {
                // use Map
                var writeCount = info.Members.Count();

                argWriter.EmitLoad();
                il.EmitLdc_I4(writeCount);
                ////if (writeCount <= MessagePackRange.MaxFixMapCount)
                ////{
                ////    il.EmitCall(MessagePackWriterTypeInfo.WriteFixedMapHeaderUnsafe);
                ////}
                ////else
                {
                    il.EmitCall(MessagePackWriterTypeInfo.WriteMapHeader);
                }

                var index = 0;
                foreach (UnionSerializationInfo.EmittableMember item in info.Members)
                {
                    argWriter.EmitLoad();
                    il.EmitLoadThis();
                    il.EmitLdfld(stringByteKeysField);
                    il.EmitLdc_I4(index);
                    il.Emit(OpCodes.Ldelem_Ref);
                    il.Emit(OpCodes.Call, ReadOnlySpanFromByteArray); // convert byte[] to ReadOnlySpan<byte>

                    // Optimize, WriteRaw(Unity, large) or UnsafeMemory32/64.WriteRawX
                    var valueLen = CodeGenHelpers.GetEncodedStringBytes(item.StringKey).Length;
                    if (valueLen <= MessagePackRange.MaxFixStringLength)
                    {
                        if (UnsafeMemory.Is32Bit)
                        {
                            il.EmitCall(typeof(UnsafeMemory32).GetRuntimeMethod("WriteRaw" + valueLen, new[] { typeof(MessagePackWriter).MakeByRefType(), typeof(ReadOnlySpan <byte>) }));
                        }
                        else
                        {
                            il.EmitCall(typeof(UnsafeMemory64).GetRuntimeMethod("WriteRaw" + valueLen, new[] { typeof(MessagePackWriter).MakeByRefType(), typeof(ReadOnlySpan <byte>) }));
                        }
                    }
                    else
                    {
                        il.EmitCall(MessagePackWriterTypeInfo.WriteRaw);
                    }

                    EmitSerializeValue(il, type.GetTypeInfo(), item, index, argWriter, argValue, argOptions, localResolver);
                    index++;
                }
            }
        }