Exemple #1
0
        private static async Task WriteAsyncInternal(object value, Type type, Stream utf8Stream, JsonSerializerOptions options, CancellationToken cancellationToken)
        {
            if (options == null)
            {
                options = s_defaultSettings;
            }

            var writerState = new JsonWriterState(options.WriterOptions);

            using (var bufferWriter = new ArrayBufferWriter <byte>(options.EffectiveBufferSize))
            {
                if (value == null)
                {
                    WriteNull(ref writerState, bufferWriter);
#if BUILDING_INBOX_LIBRARY
                    await utf8Stream.WriteAsync(bufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false);
#else
                    // todo: stackalloc?
                    await utf8Stream.WriteAsync(bufferWriter.WrittenMemory.ToArray(), 0, bufferWriter.WrittenMemory.Length, cancellationToken).ConfigureAwait(false);
#endif
                    return;
                }

                if (type == null)
                {
                    type = value.GetType();
                }

                JsonClassInfo    classInfo = options.GetOrAddClass(type);
                WriteObjectState current   = default;
                current.ClassInfo    = classInfo;
                current.CurrentValue = value;
                if (classInfo.ClassType != ClassType.Object)
                {
                    current.PropertyInfo = classInfo.GetPolicyProperty();
                }

                List <WriteObjectState> previous = null;
                int  arrayIndex = 0;
                bool isFinalBlock;

                int flushThreshold;
                do
                {
                    flushThreshold = (int)(bufferWriter.Capacity * .9); //todo: determine best value here

                    isFinalBlock = Write(ref writerState, bufferWriter, flushThreshold, options, ref current, ref previous, ref arrayIndex);
#if BUILDING_INBOX_LIBRARY
                    await utf8Stream.WriteAsync(bufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false);
#else
                    // todo: stackalloc?
                    await utf8Stream.WriteAsync(bufferWriter.WrittenMemory.ToArray(), 0, bufferWriter.WrittenMemory.Length, cancellationToken).ConfigureAwait(false);
#endif
                    bufferWriter.Clear();
                } while (!isFinalBlock);
            }

            // todo: do we want to call FlushAsync here (or above)? It seems like leaving it to the caller would be better.
            //await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
        }
        private static void WriteCore(ArrayBufferWriter <byte> output, object value, Type type, JsonSerializerOptions options)
        {
            Debug.Assert(type != null || value == null);

            var writerState = new JsonWriterState(options.GetWriterOptions());
            var writer      = new Utf8JsonWriter(output, writerState);

            if (value == null)
            {
                writer.WriteNullValue();
            }
            else
            {
                //  We treat typeof(object) special and allow polymorphic behavior.
                if (type == typeof(object))
                {
                    type = value.GetType();
                }

                WriteStack state = default;
                state.Current.Initialize(type, options);
                state.Current.CurrentValue = value;

                Write(ref writer, -1, options, ref state);
            }

            writer.Flush(isFinalBlock: true);
        }
        private static void WriteCore(ArrayBufferWriter <byte> output, object value, Type type, JsonSerializerOptions options)
        {
            Debug.Assert(type != null || value == null);

            var writerState = new JsonWriterState(options.WriterOptions);
            var writer      = new Utf8JsonWriter(output, writerState);

            if (value == null)
            {
                writer.WriteNullValue();
            }
            else
            {
                //  We treat typeof(object) special and allow polymorphic behavior.
                if (type == typeof(object))
                {
                    type = value.GetType();
                }

                WriteStack    state     = default;
                JsonClassInfo classInfo = options.GetOrAddClass(type);
                state.Current.JsonClassInfo = classInfo;
                state.Current.CurrentValue  = value;
                if (classInfo.ClassType != ClassType.Object)
                {
                    state.Current.JsonPropertyInfo = classInfo.GetPolicyProperty();
                }

                Write(ref writer, -1, options, ref state);
            }

            writer.Flush(isFinalBlock: true);
        }
Exemple #4
0
        private static void WriteComplexValue(
            bool indented,
            string jsonIn,
            string expectedIndent,
            string expectedMinimal)
        {
            using (ArrayBufferWriter buffer = new ArrayBufferWriter(1024))
                using (JsonDocument doc = JsonDocument.Parse($" [  {jsonIn}  ]", s_readerOptions))
                {
                    JsonElement target = doc.RootElement[0];

                    var state = new JsonWriterState(
                        new JsonWriterOptions
                    {
                        Indented = indented,
                    });

                    var writer = new Utf8JsonWriter(buffer, state);

                    target.WriteAsValue(ref writer);
                    writer.Flush();

                    if (indented && s_replaceNewlines)
                    {
                        AssertContents(
                            expectedIndent.Replace(CompiledNewline, Environment.NewLine),
                            buffer);
                    }

                    AssertContents(indented ? expectedIndent : expectedMinimal, buffer);
                }
        }
        private static void WriterSystemJsonBasic(bool formatted, bool skipValidation, ArrayFormatterWrapper output, ReadOnlySpan <int> data)
        {
            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = formatted, SkipValidation = skipValidation
            });

            var json = new Utf8JsonWriter2(output, state);

            json.WriteStartObject();
            json.WriteNumber("age", 42);
            json.WriteString("first", "John");
            json.WriteString("last", "Smith");
            json.WriteStartArray("phoneNumbers");
            json.WriteStringValue("425-000-1212");
            json.WriteStringValue("425-000-1213");
            json.WriteEndArray();
            json.WriteStartObject("address");
            json.WriteString("street", "1 Microsoft Way");
            json.WriteString("city", "Redmond");
            json.WriteNumber("zip", 98052);
            json.WriteEndObject();

            json.WriteStartArray("ExtraArray");
            for (var i = 0; i < data.Length; i++)
            {
                json.WriteNumberValue(data[i]);
            }
            json.WriteEndArray();

            json.WriteEndObject();

            json.Flush();
        }
Exemple #6
0
        public void WriteToPipeUsingSpan()
        {
            string actual     = "";
            var    taskReader = Task.Run(async() =>
            {
                Json.JsonReaderState state = default;
                string str = "";
                while (true)
                {
                    ReadResult result            = await _pipe.Reader.ReadAsync();
                    ReadOnlySequence <byte> data = result.Buffer;
                    bool isFinalBlock            = result.IsCompleted;
                    (state, str) = ProcessData(data, isFinalBlock, state);
                    _pipe.Reader.AdvanceTo(state.Position);
                    actual += str;
                    if (isFinalBlock)
                    {
                        break;
                    }
                }
            });

            var taskWriter = Task.Run(async() =>
            {
                JsonWriterState state = default;
                long bytesCommitted   = 0;
                while (true)
                {
                    Memory <byte> memory    = new byte [4_000];
                    (state, bytesCommitted) = WriteData(memory, isFinalBlock: true, state);
                    FlushResult result      = await _pipe.Writer.WriteAsync(memory.Slice(0, (int)bytesCommitted));
                    break;
                }
Exemple #7
0
        public static void WritePropertyOutsideObject(bool skipValidation)
        {
            using (ArrayBufferWriter buffer = new ArrayBufferWriter(1024))
                using (var doc = JsonDocument.Parse("[ null, false, true, \"hi\", 5, {}, [] ]", s_readerOptions))
                {
                    JsonElement     root  = doc.RootElement;
                    JsonWriterState state = new JsonWriterState(
                        new JsonWriterOptions
                    {
                        SkipValidation = skipValidation,
                    });

                    const string   CharLabel = "char";
                    byte[]         byteUtf8  = Encoding.UTF8.GetBytes("byte");
                    Utf8JsonWriter writer    = new Utf8JsonWriter(buffer, state);

                    if (skipValidation)
                    {
                        foreach (JsonElement val in root.EnumerateArray())
                        {
                            val.WriteAsProperty(CharLabel.AsSpan(), ref writer);
                            val.WriteAsProperty(byteUtf8, ref writer);
                        }

                        writer.Flush();

                        AssertContents(
                            "\"char\":null,\"byte\":null," +
                            "\"char\":false,\"byte\":false," +
                            "\"char\":true,\"byte\":true," +
                            "\"char\":\"hi\",\"byte\":\"hi\"," +
                            "\"char\":5,\"byte\":5," +
                            "\"char\":{},\"byte\":{}," +
                            "\"char\":[],\"byte\":[]",
                            buffer);
                    }
                    else
                    {
                        foreach (JsonElement val in root.EnumerateArray())
                        {
                            JsonTestHelper.AssertThrows <InvalidOperationException>(
                                ref writer,
                                (ref Utf8JsonWriter w) => val.WriteAsProperty(CharLabel.AsSpan(), ref w));

                            JsonTestHelper.AssertThrows <InvalidOperationException>(
                                ref writer,
                                (ref Utf8JsonWriter w) => val.WriteAsProperty(byteUtf8, ref w));
                        }

                        JsonTestHelper.AssertThrows <InvalidOperationException>(
                            ref writer,
                            (ref Utf8JsonWriter w) => w.Flush());

                        writer.Flush(isFinalBlock: false);

                        AssertContents("", buffer);
                    }
                }
        }
Exemple #8
0
        private static async Task WriteAsyncCore(object value, Type type, Stream utf8Json, JsonSerializerOptions options, CancellationToken cancellationToken)
        {
            if (options == null)
            {
                options = s_defaultSettings;
            }

            var writerState = new JsonWriterState(options.WriterOptions);

            using (var bufferWriter = new ArrayBufferWriter <byte>(options.EffectiveBufferSize))
            {
                if (value == null)
                {
                    WriteNull(ref writerState, bufferWriter);
#if BUILDING_INBOX_LIBRARY
                    await utf8Json.WriteAsync(bufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false);
#else
                    // todo: stackalloc or pool here?
                    await utf8Json.WriteAsync(bufferWriter.WrittenMemory.ToArray(), 0, bufferWriter.WrittenMemory.Length, cancellationToken).ConfigureAwait(false);
#endif
                    return;
                }

                if (type == null)
                {
                    type = value.GetType();
                }

                JsonClassInfo classInfo = options.GetOrAddClass(type);
                WriteStack    state     = default;
                state.Current.JsonClassInfo = classInfo;
                state.Current.CurrentValue  = value;
                if (classInfo.ClassType != ClassType.Object)
                {
                    state.Current.JsonPropertyInfo = classInfo.GetPolicyProperty();
                }

                bool isFinalBlock;

                int flushThreshold;
                do
                {
                    flushThreshold = (int)(bufferWriter.Capacity * .9); //todo: determine best value here

                    isFinalBlock = Write(ref writerState, bufferWriter, flushThreshold, options, ref state);
#if BUILDING_INBOX_LIBRARY
                    await utf8Json.WriteAsync(bufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false);
#else
                    // todo: use pool here to avod extra alloc?
                    await utf8Json.WriteAsync(bufferWriter.WrittenMemory.ToArray(), 0, bufferWriter.WrittenMemory.Length, cancellationToken).ConfigureAwait(false);
#endif
                    bufferWriter.Clear();
                } while (!isFinalBlock);
            }

            // todo: verify that we do want to call FlushAsync here (or above). It seems like leaving it to the caller would be best.
        }
        private static void WriteNull(
            ref JsonWriterState writerState,
            IBufferWriter <byte> bufferWriter)
        {
            Utf8JsonWriter writer = new Utf8JsonWriter(bufferWriter, writerState);

            writer.WriteNullValue();
            writer.Flush(true);
        }
Exemple #10
0
        private static async Task WriteAsyncInternal(object value, Type type, PipeWriter utf8Writer, JsonSerializerOptions options, CancellationToken cancellationToken)
        {
            if (options == null)
            {
                options = s_defaultSettings;
            }

            var writerState = new JsonWriterState(options.WriterOptions);

            // Allocate the initial buffer. We don't want to use the existing buffer as there may be very few bytes left
            // and we won't be able to calculate flushThreshold appropriately.
            Memory <byte> memory = utf8Writer.GetMemory(options.EffectiveBufferSize);

            if (value == null)
            {
                WriteNull(ref writerState, utf8Writer);
                await utf8Writer.FlushAsync(cancellationToken).ConfigureAwait(false);

                return;
            }

            if (type == null)
            {
                type = value.GetType();
            }

            JsonClassInfo    classInfo = options.GetOrAddClass(type);
            WriteObjectState current   = default;

            current.ClassInfo    = classInfo;
            current.CurrentValue = value;
            if (classInfo.ClassType != ClassType.Object)
            {
                current.PropertyInfo = classInfo.GetPolicyProperty();
            }
            List <WriteObjectState> previous = null;
            int arrayIndex = 0;

            bool isFinalBlock;

            // For Pipes there is not a way to get current buffer total size, so we just use the initial memory size.
            int flushThreshold = (int)(memory.Length * .9); //todo: determine best value here (extensible?)

            do
            {
                isFinalBlock = Write(ref writerState, utf8Writer, flushThreshold, options, ref current, ref previous, ref arrayIndex);
                await utf8Writer.FlushAsync(cancellationToken).ConfigureAwait(false);
            } while (!isFinalBlock);
        }
Exemple #11
0
        //[Benchmark]
        public void WriteArray()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            json.WriteNumberArray(Message, _longs, suppressEscaping: true);
            json.WriteEndObject();
            json.Flush();
        }
Exemple #12
0
        //[Benchmark]
        public void WriterSystemTextJsonArrayValues()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            json.WriteNumberArray(Encoding.UTF8.GetBytes("numbers"), dataArray, suppressEscaping: true);
            json.WriteEndObject();
            json.Flush();
        }
Exemple #13
0
        public static void JsonWriterStateDefaultCtor()
        {
            var state = new JsonWriterState();

            Assert.Equal(0, state.BytesCommitted);
            Assert.Equal(0, state.BytesWritten);

            var expectedOption = new JsonWriterOptions
            {
                Indented       = false,
                SkipValidation = false
            };

            Assert.Equal(expectedOption, state.Options);
        }
Exemple #14
0
        private static byte[] WriteInternal(object value, Type type, JsonSerializerOptions options)
        {
            if (options == null)
            {
                options = s_defaultSettings;
            }

            byte[] result;
            var    state = new JsonWriterState(options.WriterOptions);

            using (var output = new ArrayBufferWriter <byte>(options.EffectiveBufferSize))
            {
                var writer = new Utf8JsonWriter(output, state);

                if (value == null)
                {
                    writer.WriteNullValue();
                }
                else
                {
                    if (type == null)
                    {
                        type = value.GetType();
                    }

                    WriteObjectState current = default;

                    JsonClassInfo classInfo = options.GetOrAddClass(type);
                    current.ClassInfo    = classInfo;
                    current.CurrentValue = value;
                    if (classInfo.ClassType != ClassType.Object)
                    {
                        current.PropertyInfo = classInfo.GetPolicyProperty();
                    }

                    List <WriteObjectState> previous = null;
                    int arrayIndex = 0;

                    Write(ref writer, -1, options, ref current, ref previous, ref arrayIndex);
                }

                writer.Flush(isFinalBlock: true);
                result = output.WrittenMemory.ToArray();
            }

            return(result);
        }
Exemple #15
0
            public string ToJson()
            {
                var state = new JsonWriterState(options: new JsonWriterOptions {
                    Indented = true
                });

                using (var arrayBufferWriter = new ArrayBufferWriter <byte>())
                {
                    var writer = new Utf8JsonWriter(arrayBufferWriter, state);

                    writer.WriteStartObject();

                    if (Version.HasValue)
                    {
                        writer.WriteNumber(propertyName: JsonPropertyVersion, value: Version.Value);
                    }

                    if (IsRoot.HasValue)
                    {
                        writer.WriteBoolean(JsonPropertyIsRoot, IsRoot.Value);
                    }

                    writer.WriteStartObject(JsonPropertyTools);

                    foreach (var tool in Tools)
                    {
                        writer.WriteStartObject(tool.Key);
                        writer.WriteString(JsonPropertyVersion, tool.Value.Version);
                        writer.WriteStartArray(JsonPropertyCommands);
                        foreach (var toolCommandName in tool.Value.Commands)
                        {
                            writer.WriteStringValue(toolCommandName);
                        }

                        writer.WriteEndArray();
                        writer.WriteEndObject();
                    }

                    writer.WriteEndObject();
                    writer.WriteEndObject();
                    writer.Flush(true);

                    return(Encoding.UTF8.GetString(arrayBufferWriter.WrittenMemory.ToArray()));
                }
            }
Exemple #16
0
        public static void WriteValueInsideObject(bool skipValidation)
        {
            using (ArrayBufferWriter buffer = new ArrayBufferWriter(1024))
                using (var doc = JsonDocument.Parse("[ null, false, true, \"hi\", 5, {}, [] ]", s_readerOptions))
                {
                    JsonElement     root  = doc.RootElement;
                    JsonWriterState state = new JsonWriterState(
                        new JsonWriterOptions
                    {
                        SkipValidation = skipValidation,
                    });

                    Utf8JsonWriter writer = new Utf8JsonWriter(buffer, state);
                    writer.WriteStartObject();

                    if (skipValidation)
                    {
                        foreach (JsonElement val in root.EnumerateArray())
                        {
                            val.WriteAsValue(ref writer);
                        }

                        writer.WriteEndObject();
                        writer.Flush();

                        AssertContents(
                            "{null,false,true,\"hi\",5,{},[]}",
                            buffer);
                    }
                    else
                    {
                        foreach (JsonElement val in root.EnumerateArray())
                        {
                            JsonTestHelper.AssertThrows <InvalidOperationException>(
                                ref writer,
                                (ref Utf8JsonWriter w) => val.WriteAsValue(ref w));
                        }

                        writer.WriteEndObject();
                        writer.Flush();

                        AssertContents("{}", buffer);
                    }
                }
        }
Exemple #17
0
        //[Benchmark]
        public void WritePropertyValueEscapingRequired()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            for (int i = 0; i < 100; i++)
            {
                json.WriteString("fir\nst", "Joh\nn");
            }
            json.WriteEndObject();
            json.Flush();
        }
Exemple #18
0
        //[Benchmark]
        public void WriteDateTimeUnescapedOverheadUtf16()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            for (int i = 0; i < 100; i++)
            {
                json.WriteString("first", MyDate, suppressEscaping: false);
            }
            json.WriteEndObject();
            json.Flush();
        }
Exemple #19
0
        //[Benchmark]
        public void WriterSystemTextJsonBasicUtf8NoDefault()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            for (int i = 0; i < 100; i++)
            {
                json.WriteString(First, John);
            }
            json.WriteEndObject();
            json.Flush();
        }
Exemple #20
0
        //[Benchmark]
        public void WriteNumberUnescapedUtf16()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            for (int i = 0; i < 100; i++)
            {
                json.WriteNumber("first", value: 123456, suppressEscaping: true);
            }
            json.WriteEndObject();
            json.Flush();
        }
Exemple #21
0
        //[Benchmark]
        public void WritePropertyValueEscapeUnnecessarily()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            for (int i = 0; i < 100; i++)
            {
                json.WriteString("first", "John", suppressEscaping: false);
            }
            json.WriteEndObject();
            json.Flush();
        }
Exemple #22
0
        private static bool Write(
            ref JsonWriterState writerState,
            IBufferWriter <byte> bufferWriter,
            int flushThreshold,
            JsonSerializerOptions options,
            ref WriteStack state)
        {
            Utf8JsonWriter writer = new Utf8JsonWriter(bufferWriter, writerState);

            bool isFinalBlock = Write(
                ref writer,
                flushThreshold,
                options,
                ref state);

            writer.Flush(isFinalBlock: isFinalBlock);
            writerState = writer.GetCurrentState();

            return(isFinalBlock);
        }
Exemple #23
0
        //[Benchmark]
        public void WriteArrayLoop()
        {
            _arrayFormatterWrapper.Clear();

            var state = new JsonWriterState(options: new JsonWriterOptions {
                Indented = Formatted, SkipValidation = SkipValidation
            });

            var json = new Utf8JsonWriter2(_arrayFormatterWrapper, state);

            json.WriteStartObject();
            json.WriteStartArray(Message, suppressEscaping: true);
            for (int i = 0; i < _longs.Length; i++)
            {
                json.WriteNumberValue(_longs[i]);
            }
            json.WriteEndArray();
            json.WriteEndObject();
            json.Flush();
        }
Exemple #24
0
 public void Write(DependencyContext context, Stream stream)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (stream == null)
     {
         throw new ArgumentNullException(nameof(stream));
     }
     using (var bufferWriter = new ArrayBufferWriter())
     {
         var state = new JsonWriterState(options: new JsonWriterOptions {
             Indented = true
         });
         var jsonWriter = new Utf8JsonWriter(bufferWriter, state);
         WriteCore(context, new UnifiedJsonWriter(jsonWriter));
         bufferWriter.CopyTo(stream);
     }
 }
Exemple #25
0
        private static void WriteSimpleValue(bool indented, string jsonIn, string jsonOut = null)
        {
            using (ArrayBufferWriter buffer = new ArrayBufferWriter(1024))
                using (JsonDocument doc = JsonDocument.Parse($" [  {jsonIn}  ]", s_readerOptions))
                {
                    JsonElement target = doc.RootElement[0];

                    var state = new JsonWriterState(
                        new JsonWriterOptions
                    {
                        Indented = indented,
                    });

                    var writer = new Utf8JsonWriter(buffer, state);

                    target.WriteAsValue(ref writer);
                    writer.Flush();

                    AssertContents(jsonOut ?? jsonIn, buffer);
                }
        }
        private static bool Write(
            ref JsonWriterState writerState,
            IBufferWriter <byte> bufferWriter,
            int flushThreshold,
            JsonSerializerOptions options,
            ref WriteObjectState current,
            ref List <WriteObjectState> previous,
            ref int arrayIndex)
        {
            Utf8JsonWriter writer = new Utf8JsonWriter(bufferWriter, writerState);

            bool isFinalBlock = Write(
                ref writer,
                flushThreshold,
                options,
                ref current,
                ref previous,
                ref arrayIndex);

            writer.Flush(isFinalBlock: isFinalBlock);
            writerState = writer.GetCurrentState();

            return(isFinalBlock);
        }
Exemple #27
0
        public override ValueTask Serialize(PipeWriter pipe, string instance, JsonWriterState state = default, CancellationToken cancellationToken = default)
        {
            var writer = new Utf8JsonWriter(pipe, state);

            writer.WriteStringValue(instance, true);
            return(default);