Ejemplo n.º 1
0
        /// <summary>
        /// Read from the stream until either our buffer is filled or we hit EOF.
        /// Calling ReadCore is relatively expensive, so we minimize the number of times
        /// we need to call it.
        /// </summary>
        internal static async ValueTask <ReadBufferState> ReadFromStreamAsync(
            Stream utf8Json,
            ReadBufferState bufferState,
            CancellationToken cancellationToken)
        {
            while (true)
            {
                int bytesRead = await utf8Json.ReadAsync(
#if BUILDING_INBOX_LIBRARY
                    bufferState.Buffer.AsMemory(bufferState.BytesInBuffer),
#else
                    bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer,
#endif
                    cancellationToken).ConfigureAwait(false);

                if (bytesRead == 0)
                {
                    bufferState.IsFinalBlock = true;
                    break;
                }

                bufferState.BytesInBuffer += bytesRead;

                if (bufferState.BytesInBuffer == bufferState.Buffer.Length)
                {
                    break;
                }
            }

            return(bufferState);
        }
Ejemplo n.º 2
0
            static async IAsyncEnumerable <TValue> CreateAsyncEnumerableDeserializer(
                Stream utf8Json,
                JsonSerializerOptions options,
                [EnumeratorCancellation] CancellationToken cancellationToken)
            {
                var bufferState = new ReadBufferState(options.DefaultBufferSize);
                // Hardcode the queue converter to avoid accidental use of custom converters
                JsonConverter converter    = QueueOfTConverter <Queue <TValue>, TValue> .Instance;
                JsonTypeInfo  jsonTypeInfo = CreateQueueJsonTypeInfo <TValue>(converter, options);
                ReadStack     readStack    = default;

                readStack.Initialize(jsonTypeInfo, supportContinuation: true);
                var jsonReaderState = new JsonReaderState(options.GetReaderOptions());

                try
                {
                    do
                    {
                        bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false);

                        ContinueDeserialize <Queue <TValue> >(ref bufferState, ref jsonReaderState, ref readStack, converter, options);
                        if (readStack.Current.ReturnValue is Queue <TValue> queue)
                        {
                            while (queue.Count > 0)
                            {
                                yield return(queue.Dequeue());
                            }
                        }
                    }while (!bufferState.IsFinalBlock);
                }
                finally
                {
                    bufferState.Dispose();
                }
            }
Ejemplo n.º 3
0
        /// <summary>
        /// Read from the stream until either our buffer is filled or we hit EOF.
        /// Calling ReadCore is relatively expensive, so we minimize the number of times
        /// we need to call it.
        /// </summary>
        internal static ReadBufferState ReadFromStream(
            Stream utf8Json,
            ReadBufferState bufferState)
        {
            while (true)
            {
                int bytesRead = utf8Json.Read(
#if BUILDING_INBOX_LIBRARY
                    bufferState.Buffer.AsSpan(bufferState.BytesInBuffer));
#else
                    bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer);
#endif

                if (bytesRead == 0)
                {
                    bufferState.IsFinalBlock = true;
                    break;
                }

                bufferState.BytesInBuffer += bytesRead;

                if (bufferState.BytesInBuffer == bufferState.Buffer.Length)
                {
                    break;
                }
            }

            return(bufferState);
        }
Ejemplo n.º 4
0
        private void OnRead(IAsyncResult base_ares)
        {
            ReadBufferState       rb   = (ReadBufferState)base_ares.AsyncState;
            HttpStreamAsyncResult ares = rb.Ares;

            try
            {
                int nread = base.EndRead(base_ares);
                _decoder.Write(ares._buffer, ares._offset, nread);
                nread      = _decoder.Read(rb.Buffer, rb.Offset, rb.Count);
                rb.Offset += nread;
                rb.Count  -= nread;
                if (rb.Count == 0 || !_decoder.WantMore || nread == 0)
                {
                    _no_more_data = !_decoder.WantMore && nread == 0;
                    ares._count   = rb.InitialCount - rb.Count;
                    ares.Complete();
                    return;
                }
                ares._offset = 0;
                ares._count  = Math.Min(8192, _decoder.ChunkLeft + 6);
                base.BeginRead(ares._buffer, ares._offset, ares._count, OnRead, rb);
            }
            catch (Exception e)
            {
                _context.Connection.SendError(e.Message, 400);
                ares.Complete(e);
            }
        }
Ejemplo n.º 5
0
        internal static TValue?ReadAll <TValue>(
            Stream utf8Json,
            JsonTypeInfo jsonTypeInfo)
        {
            JsonSerializerOptions options = jsonTypeInfo.Options;
            var       bufferState         = new ReadBufferState(options.DefaultBufferSize);
            ReadStack readStack           = default;

            jsonTypeInfo.EnsureConfigured();
            readStack.Initialize(jsonTypeInfo, supportContinuation: true);
            JsonConverter converter       = readStack.Current.JsonPropertyInfo !.ConverterBase;
            var           jsonReaderState = new JsonReaderState(options.GetReaderOptions());

            try
            {
                while (true)
                {
                    bufferState = ReadFromStream(utf8Json, bufferState);
                    TValue value = ContinueDeserialize <TValue>(ref bufferState, ref jsonReaderState, ref readStack, converter, options);

                    if (bufferState.IsFinalBlock)
                    {
                        return(value !);
                    }
                }
            }
            finally
            {
                bufferState.Dispose();
            }
        }
Ejemplo n.º 6
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            int len = buffer.Length;

            if (offset < 0 || offset > len)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), SR.offset_out_of_range);
            }

            if (count < 0 || offset > len - count)
            {
                throw new ArgumentOutOfRangeException(nameof(count), SR.offset_out_of_range);
            }

            HttpStreamAsyncResult ares = new HttpStreamAsyncResult();

            ares._callback = cback;
            ares._state    = state;
            if (_no_more_data)
            {
                ares.Complete();
                return(ares);
            }
            int nread = _decoder.Read(buffer, offset, count);

            offset += nread;
            count  -= nread;
            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares._count = nread;
                ares.Complete();
                return(ares);
            }
            if (!_decoder.WantMore)
            {
                _no_more_data = nread == 0;
                ares._count   = nread;
                ares.Complete();
                return(ares);
            }
            ares._buffer = new byte[8192];
            ares._offset = 0;
            ares._count  = 8192;
            ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares);

            rb.InitialCount += nread;
            base.BeginRead(ares._buffer, ares._offset, ares._count, OnRead, rb);
            return(ares);
        }
Ejemplo n.º 7
0
        private void OnRead(IAsyncResult base_ares)
        {
            ReadBufferState       readBufferState = (ReadBufferState)base_ares.AsyncState;
            HttpStreamAsyncResult ares            = readBufferState.Ares;

            try
            {
                int size = base.EndRead(base_ares);
                decoder.Write(ares.Buffer, ares.Offset, size);
                size = decoder.Read(readBufferState.Buffer, readBufferState.Offset, readBufferState.Count);
                readBufferState.Offset += size;
                readBufferState.Count  -= size;
                if (readBufferState.Count == 0 || !decoder.WantMore || size == 0)
                {
                    no_more_data = (!decoder.WantMore && size == 0);
                    ares.Count   = readBufferState.InitialCount - readBufferState.Count;
                    ares.Complete();
                }
                else
                {
                    ares.Offset = 0;
                    ares.Count  = Math.Min(8192, decoder.ChunkLeft + 6);
                    base.BeginRead(ares.Buffer, ares.Offset, ares.Count, (AsyncCallback)OnRead, (object)readBufferState);
                }
            }
            catch (Exception ex)
            {
                context.Connection.SendError(ex.Message, 400);
                ares.Complete(ex);
            }
        }
Ejemplo n.º 8
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            int num = buffer.Length;

            if (offset < 0 || offset > num)
            {
                throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");
            }
            if (count < 0 || offset > num - count)
            {
                throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
            }
            HttpStreamAsyncResult httpStreamAsyncResult = new HttpStreamAsyncResult();

            httpStreamAsyncResult.Callback = cback;
            httpStreamAsyncResult.State    = state;
            if (no_more_data)
            {
                httpStreamAsyncResult.Complete();
                return(httpStreamAsyncResult);
            }
            int num2 = decoder.Read(buffer, offset, count);

            offset += num2;
            count  -= num2;
            if (count == 0)
            {
                httpStreamAsyncResult.Count = num2;
                httpStreamAsyncResult.Complete();
                return(httpStreamAsyncResult);
            }
            if (!decoder.WantMore)
            {
                no_more_data = (num2 == 0);
                httpStreamAsyncResult.Count = num2;
                httpStreamAsyncResult.Complete();
                return(httpStreamAsyncResult);
            }
            httpStreamAsyncResult.Buffer = new byte[8192];
            httpStreamAsyncResult.Offset = 0;
            httpStreamAsyncResult.Count  = 8192;
            ReadBufferState readBufferState = new ReadBufferState(buffer, offset, count, httpStreamAsyncResult);

            readBufferState.InitialCount += num2;
            base.BeginRead(httpStreamAsyncResult.Buffer, httpStreamAsyncResult.Offset, httpStreamAsyncResult.Count, (AsyncCallback)OnRead, (object)readBufferState);
            return(httpStreamAsyncResult);
        }
Ejemplo n.º 9
0
        private static async IAsyncEnumerable <TValue> CreateAsyncEnumerableDeserializer <TValue>(
            Stream utf8Json,
            JsonTypeInfo jsonTypeInfo,
            [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            JsonSerializerOptions          options       = jsonTypeInfo.Options;
            JsonTypeInfo <Queue <TValue> > queueTypeInfo =
                JsonMetadataServices.CreateQueueInfo <Queue <TValue>, TValue>(
                    options: options,
                    collectionInfo: new()
            {
                ObjectCreator  = () => new Queue <TValue>(),
                ElementInfo    = jsonTypeInfo,
                NumberHandling = options.NumberHandling
            });

            var       bufferState = new ReadBufferState(options.DefaultBufferSize);
            ReadStack readStack   = default;

            queueTypeInfo.EnsureConfigured();
            readStack.Initialize(queueTypeInfo, supportContinuation: true);
            var jsonReaderState = new JsonReaderState(options.GetReaderOptions());

            try
            {
                do
                {
                    bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false);

                    ContinueDeserialize <Queue <TValue> >(
                        ref bufferState,
                        ref jsonReaderState,
                        ref readStack,
                        queueTypeInfo.PropertyInfoForTypeInfo.ConverterBase,
                        options);

                    if (readStack.Current.ReturnValue is Queue <TValue> queue)
                    {
                        while (queue.Count > 0)
                        {
                            yield return(queue.Dequeue());
                        }
                    }
                }while (!bufferState.IsFinalBlock);
            }
            finally
            {
                bufferState.Dispose();
            }
        }
        protected override IAsyncResult BeginReadCore(byte[] buffer, int offset, int size, AsyncCallback cback, object state)
        {
            HttpStreamAsyncResult ares = new HttpStreamAsyncResult(this);

            ares._callback = cback;
            ares._state    = state;
            if (_no_more_data || size == 0 || _closed)
            {
                ares.Complete();
                return(ares);
            }
            int nread = _decoder.Read(buffer, offset, size);

            offset += nread;
            size   -= nread;
            if (size == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares._count = nread;
                ares.Complete();
                return(ares);
            }
            if (!_decoder.WantMore)
            {
                _no_more_data = nread == 0;
                ares._count   = nread;
                ares.Complete();
                return(ares);
            }
            ares._buffer = new byte[8192];
            ares._offset = 0;
            ares._count  = 8192;
            ReadBufferState rb = new ReadBufferState(buffer, offset, size, ares);

            rb.InitialCount += nread;
            base.BeginReadCore(ares._buffer, ares._offset, ares._count, OnRead, rb);
            return(ares);
        }
Ejemplo n.º 11
0
        internal static TValue ContinueDeserialize <TValue>(
            ref ReadBufferState bufferState,
            ref JsonReaderState jsonReaderState,
            ref ReadStack readStack,
            JsonConverter converter,
            JsonSerializerOptions options)
        {
            if (bufferState.BytesInBuffer > bufferState.ClearMax)
            {
                bufferState.ClearMax = bufferState.BytesInBuffer;
            }

            int start = 0;

            if (bufferState.IsFirstIteration)
            {
                bufferState.IsFirstIteration = false;

                // Handle the UTF-8 BOM if present
                Debug.Assert(bufferState.Buffer.Length >= JsonConstants.Utf8Bom.Length);
                if (bufferState.Buffer.AsSpan().StartsWith(JsonConstants.Utf8Bom))
                {
                    start += JsonConstants.Utf8Bom.Length;
                    bufferState.BytesInBuffer -= JsonConstants.Utf8Bom.Length;
                }
            }

            // Process the data available
            TValue value = ReadCore <TValue>(
                ref jsonReaderState,
                bufferState.IsFinalBlock,
                new ReadOnlySpan <byte>(bufferState.Buffer, start, bufferState.BytesInBuffer),
                options,
                ref readStack,
                converter);

            Debug.Assert(readStack.BytesConsumed <= bufferState.BytesInBuffer);
            int bytesConsumed = checked ((int)readStack.BytesConsumed);

            bufferState.BytesInBuffer -= bytesConsumed;

            // The reader should have thrown if we have remaining bytes.
            Debug.Assert(!bufferState.IsFinalBlock || bufferState.BytesInBuffer == 0);

            if (!bufferState.IsFinalBlock)
            {
                // Check if we need to shift or expand the buffer because there wasn't enough data to complete deserialization.
                if ((uint)bufferState.BytesInBuffer > ((uint)bufferState.Buffer.Length / 2))
                {
                    // We have less than half the buffer available, double the buffer size.
                    byte[] oldBuffer   = bufferState.Buffer;
                    int    oldClearMax = bufferState.ClearMax;
                    byte[] newBuffer   = ArrayPool <byte> .Shared.Rent((bufferState.Buffer.Length < (int.MaxValue / 2))?bufferState.Buffer.Length * 2 : int.MaxValue);

                    // Copy the unprocessed data to the new buffer while shifting the processed bytes.
                    Buffer.BlockCopy(oldBuffer, bytesConsumed + start, newBuffer, 0, bufferState.BytesInBuffer);
                    bufferState.Buffer   = newBuffer;
                    bufferState.ClearMax = bufferState.BytesInBuffer;

                    // Clear and return the old buffer
                    new Span <byte>(oldBuffer, 0, oldClearMax).Clear();
                    ArrayPool <byte> .Shared.Return(oldBuffer);
                }
                else if (bufferState.BytesInBuffer != 0)
                {
                    // Shift the processed bytes to the beginning of buffer to make more room.
                    Buffer.BlockCopy(bufferState.Buffer, bytesConsumed + start, bufferState.Buffer, 0, bufferState.BytesInBuffer);
                }
            }

            return(value);
        }
Ejemplo n.º 12
0
        public new IAsyncResult BeginRead(byte[] buffer, int offset, int count,
            AsyncCallback cback, object state)
        {
            if (_disposed)
                throw new ObjectDisposedException(GetType().ToString());

            if (buffer == null)
                throw new ArgumentNullException(nameof(buffer));

            var len = buffer.Length;
            if (offset < 0 || offset > len)
                throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");

            if (count < 0 || offset > len - count)
                throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");

            var ares = new HttpStreamAsyncResult
            {
                Callback = cback,
                State = state
            };

            if (_noMoreData)
            {
                ares.Complete();
                return ares;
            }

            var nread = Decoder.Read(buffer, offset, count);
            offset += nread;
            count -= nread;
            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares.Count = nread;
                ares.Complete();
                return ares;
            }
            if (!Decoder.WantMore)
            {
                _noMoreData = nread == 0;
                ares.Count = nread;
                ares.Complete();
                return ares;
            }
            ares.Buffer = new byte[8192];
            ares.Offset = 0;
            ares.Count = 8192;
            var rb = new ReadBufferState(buffer, offset, count, ares);
            rb.InitialCount += nread;
            base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
            return ares;
        }
Ejemplo n.º 13
0
        public new IAsyncResult BeginRead(byte[] buffer, int offset, int count,
                                          AsyncCallback cback, object state)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            var len = buffer.Length;

            if (offset < 0 || offset > len)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), "offset exceeds the size of buffer");
            }

            if (count < 0 || offset > len - count)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), "offset+size exceeds the size of buffer");
            }

            var ares = new HttpStreamAsyncResult
            {
                Callback = cback,
                State    = state
            };

            if (_noMoreData)
            {
                ares.Complete();
                return(ares);
            }

            var nread = Decoder.Read(buffer, offset, count);

            offset += nread;
            count  -= nread;
            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares.Count = nread;
                ares.Complete();
                return(ares);
            }
            if (!Decoder.WantMore)
            {
                _noMoreData = nread == 0;
                ares.Count  = nread;
                ares.Complete();
                return(ares);
            }
            ares.Buffer = new byte[8192];
            ares.Offset = 0;
            ares.Count  = 8192;
            var rb = new ReadBufferState(buffer, offset, count, ares);

            rb.InitialCount += nread;
            base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
            return(ares);
        }
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            int len = buffer.Length;

            if (offset < 0 || offset > len)
            {
                throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");
            }

            if (count < 0 || offset > len - count)
            {
                throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
            }

            if (no_more_data)
            {
                return(0);
            }

            int nread = decoder.Read(buffer, offset, count);

            offset += nread;
            count  -= nread;
            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                return(nread);
            }
            if (!decoder.WantMore)
            {
                no_more_data = nread == 0;
                return(nread);
            }
            ReadBufferState rb = new ReadBufferState(buffer, offset, count, null);

            rb.InitialCount += nread;
            var readBuff  = new byte[8192];
            var readCount = 8192;

            try
            {
                while (true)
                {
                    nread = await base.ReadAsync(readBuff, 0, readCount, token);

                    decoder.Write(readBuff, 0, nread);
                    nread      = decoder.Read(rb.Buffer, rb.Offset, rb.Count);
                    rb.Offset += nread;
                    rb.Count  -= nread;
                    if (rb.Count == 0 || !decoder.WantMore || nread == 0)
                    {
                        no_more_data = !decoder.WantMore && nread == 0;
                        return(rb.InitialCount - rb.Count);
                    }
                    readCount = System.Math.Min(8192, decoder.ChunkLeft + 6);
                }
            }
            catch (Exception e)
            {
                context.Connection.SendError(e.Message, 400);
                return(0);
            }
        }
Ejemplo n.º 15
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            int len = buffer.Length;

            if (offset < 0 || offset > len)
            {
                throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");
            }

            if (count < 0 || offset > len - count)
            {
                throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
            }

            HttpStreamAsyncResult ares = new HttpStreamAsyncResult();

            ares.Callback = cback;

            ares.State = state;

            if (no_more_data)
            {
                ares.Complete();

                return ares;
            }
            int nread = decoder.Read(buffer, offset, count);

            offset += nread;

            count -= nread;

            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares.Count = nread;

                ares.Complete();

                return ares;
            }
            if (!decoder.WantMore)
            {
                no_more_data = nread == 0;

                ares.Count = nread;

                ares.Complete();

                return ares;
            }
            ares.Buffer = new byte[8192];

            ares.Offset = 0;

            ares.Count = 8192;

            ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares);

            rb.InitialCount += nread;

            base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);

            return ares;
        }
Ejemplo n.º 16
0
        public override IAsyncResult BeginRead(
            byte [] buffer, int offset, int count, AsyncCallback cback, object state)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            int len = buffer.Length;

            if (offset < 0 || offset > len)
            {
                throw new ArgumentOutOfRangeException("'offset' exceeds the size of buffer.");
            }

            if (count < 0 || offset > len - count)
            {
                throw new ArgumentOutOfRangeException("'offset' + 'count' exceeds the size of buffer.");
            }

            var ares = new HttpStreamAsyncResult();

            ares.Callback = cback;
            ares.State    = state;
            if (no_more_data)
            {
                ares.Complete();
                return(ares);
            }

            int nread = decoder.Read(buffer, offset, count);

            offset += nread;
            count  -= nread;
            if (count == 0)
            {
                // got all we wanted, no need to bother the decoder yet
                ares.Count = nread;
                ares.Complete();
                return(ares);
            }

            if (!decoder.WantMore)
            {
                no_more_data = nread == 0;
                ares.Count   = nread;
                ares.Complete();
                return(ares);
            }

            ares.Buffer = new byte [8192];
            ares.Offset = 0;
            ares.Count  = 8192;
            var rb = new ReadBufferState(buffer, offset, count, ares);

            rb.InitialCount += nread;
            base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
            return(ares);
        }