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 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. }