コード例 #1
0
        // returns the length of serialized value when successful
        unsafe static int?CheckBoundary <T>(T value, int maxLength = 64)
        {
            const byte init   = 255;
            var        nJSON  = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(value));
            var        buffer = new byte[maxLength + 2];
            var        emit   = DelegateBuilder.CreatePointer <T>(Schema.Reflect(typeof(T)));
            string     instructions;
            var        del           = (Serializer.WriteToPointer <T>)emit.CreateDelegate(typeof(Serializer.WriteToPointer <T>), out instructions);
            int?       successLength = null;

            for (int i = 1; i <= maxLength; i++)
            {
                for (int j = 0; j < buffer.Length; j++)
                {
                    buffer[j] = init;
                }

                int result;
                fixed(byte *ptr = buffer)
                {
                    result = del.Invoke(ref value, ptr + 1, i);
                }

                // make sure we didn't go past the boundary
                Assert.Equal(init, buffer[0]);
                Assert.Equal(init, buffer[i + 1]);
                Assert.True(result <= i, "Don't exceed length");

                if (result > 0)
                {
                    Assert.Equal(nJSON, buffer.Skip(1).Take(result));
                    if (successLength == null)
                    {
                        successLength = i;
                    }
                }
            }

            if (successLength.HasValue)
            {
                emit = DelegateBuilder.CreateStream <T>(Schema.Reflect(typeof(T)));
                var streamer = (Serializer.WriteToStream <T>)emit.CreateDelegate(typeof(Serializer.WriteToStream <T>), out instructions);
                var min      = Math.Max(nJSON.Length / 2, 32);
                var ms       = new MemoryStream(nJSON.Length);

                // do stuff with the stream version now
                for (int i = nJSON.Length; i >= min; i--)
                {
                    ms.SetLength(0);
                    buffer = new byte[i];
                    fixed(byte *ptr = buffer)
                    {
                        streamer.Invoke(ref value, ptr, ms, buffer);
                    }

                    Assert.Equal(nJSON, ms.GetBuffer().Take((int)ms.Length));
                }
            }

            return(successLength);
        }