private static void WriteCore(PooledByteBufferWriter output, object value, Type type, JsonSerializerOptions options)
        {
            Debug.Assert(type != null || value == null);

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

            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(writer, -1, options, ref state);
            }

            writer.Flush();
        }
        private static async Task WriteAsyncCore(object value, Type type, Stream utf8Json, JsonSerializerOptions options, CancellationToken cancellationToken)
        {
            if (options == null)
            {
                options = JsonSerializerOptions.s_defaultOptions;
            }

            JsonWriterOptions writerOptions = options.GetWriterOptions();

            using (var bufferWriter = new PooledByteBufferWriter(options.DefaultBufferSize))
                using (var writer = new Utf8JsonWriter(bufferWriter, writerOptions))
                {
                    if (value == null)
                    {
                        writer.WriteNullValue();
                        writer.Flush();

                        await bufferWriter.WriteToStreamAsync(utf8Json, cancellationToken).ConfigureAwait(false);

                        return;
                    }

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

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

                    bool isFinalBlock;

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

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

                        await bufferWriter.WriteToStreamAsync(utf8Json, cancellationToken).ConfigureAwait(false);

                        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 string WriteCoreString(object value, Type type, JsonSerializerOptions options)
        {
            if (options == null)
            {
                options = JsonSerializerOptions.s_defaultOptions;
            }

            string result;

            using (var output = new PooledByteBufferWriter(options.DefaultBufferSize))
            {
                WriteCore(output, value, type, options);
                result = JsonReaderHelper.TranscodeHelper(output.WrittenMemory.Span);
            }

            return(result);
        }
        private static byte[] WriteCoreBytes(object value, Type type, JsonSerializerOptions options)
        {
            if (options == null)
            {
                options = JsonSerializerOptions.s_defaultOptions;
            }

            byte[] result;

            using (var output = new PooledByteBufferWriter(options.DefaultBufferSize))
            {
                WriteCore(output, value, type, options);
                result = output.WrittenMemory.ToArray();
            }

            return(result);
        }