Esempio n. 1
0
        public static void IntArraySegmentAsSpan()
        {
            int[] a = { 91, 92, -93, 94 };
            ArraySegment <int> segmentInt = new ArraySegment <int>(a, 1, 2);
            Span <int>         spanInt    = segmentInt.AsSpan();

            spanInt.Validate(92, -93);
        }
Esempio n. 2
0
        public static void LongArraySegmentAsSpan()
        {
            long[] b = { 91, -92, 93, 94, -95 };
            ArraySegment <long> segmentLong = new ArraySegment <long>(b, 1, 3);
            Span <long>         spanLong    = segmentLong.AsSpan();

            spanLong.Validate(-92, 93, 94);
        }
 public bool TryCopyOctetStringBytes(
     ArraySegment <byte> destination,
     out int bytesWritten)
 {
     return(TryCopyOctetStringBytes(
                Asn1Tag.PrimitiveOctetString,
                destination.AsSpan(),
                out bytesWritten));
 }
Esempio n. 4
0
        private static int GetLength(ArraySegment <byte> compressedData)
        {
            var lastFour = compressedData.AsSpan(compressedData.Count - 4, 4);
            var lastFourDerivedLength = BitConverter.ToInt32(lastFour);
            // little endian reversal
            var rfcDerivedLengthBytes = (lastFour[3] << 24) | (lastFour[2] << 24) + (lastFour[1] << 8) + lastFour[0];

            return((((((lastFour[4 - 1] << 8) | lastFour[3 - 1]) << 8) | lastFour[2 - 1]) << 8) | lastFour[1 - 1]);
        }
Esempio n. 5
0
        public void Dispose()
        {
            if (_segment != null)
            {
                _segment.AsSpan().Clear();
                ArrayPool <byte> .Shared.Return(_segment.Array);

                _segment = null;
            }
        }
 public bool TryCopyOctetStringBytes(
     Asn1Tag expectedTag,
     ArraySegment <byte> destination,
     out int bytesWritten)
 {
     return(TryCopyOctetStringBytes(
                expectedTag,
                destination.AsSpan(),
                out bytesWritten));
 }
        public override async Task <int> ReceiveAsync(Socket s, ArraySegment <byte> buffer)
        {
            using (var m = new NativeMemoryManager(buffer.Count))
            {
                int bytesReceived = await s.ReceiveAsync(m.Memory, SocketFlags.None).ConfigureAwait(false);

                m.Memory.Span.Slice(0, bytesReceived).CopyTo(buffer.AsSpan());
                return(bytesReceived);
            }
        }
Esempio n. 8
0
 public void SetData(ArraySegment <byte> data)
 {
     m_data = data;
     if (m_dataOffsets is null)
     {
         m_dataOffsets = new int[ResultSet.ColumnDefinitions.Length];
         m_dataLengths = new int[ResultSet.ColumnDefinitions.Length];
     }
     GetDataOffsets(m_data.AsSpan(), m_dataOffsets, m_dataLengths);
 }
 protected override TCollection AddRange(TCollection values, ref ArraySegment <T> newValues, ISerializationContext context)
 {
     foreach (var item in newValues.AsSpan())
     {
         if (!values.TryAdd(item))
         {
             ThrowHelper.ThrowInvalidOperationException("Unable to add to the collection: " + values.GetType().NormalizeName());
         }
     }
     return(values);
 }
Esempio n. 10
0
        public Guid SpanAndMemoryMarshal()
        {
            Span <byte> guidBytes = stackalloc byte[16];

            data.AsSpan().CopyTo(guidBytes);
            if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var lockTokenGuid))
            {
                lockTokenGuid = new Guid(guidBytes.ToArray());
            }
            return(lockTokenGuid);
        }
Esempio n. 11
0
        internal BufferWriter(SequencePool sequencePool, byte[] array)
        {
            buffered          = 0;
            bytesCommitted    = 0;
            this.sequencePool = sequencePool;
            rental            = default;
            output            = null;

            segment   = new ArraySegment <byte>(array);
            innerSpan = segment.AsSpan();
        }
        => values ?? TypeModel.ActivatorCreate <TCollection>();    // we *are* the factory

        protected override TCollection AddRange(TCollection values, ref ArraySegment <KeyValuePair <TKey, TValue> > newValues, ISerializationContext context)
        {
            foreach (var pair in newValues.AsSpan())
            {
                if (!values.TryAdd(pair.Key, pair.Value))
                {
                    ThrowHelper.ThrowArgumentException("duplicate key");
                }
            }
            return(values);
        }
Esempio n. 13
0
        internal BufferWriter(SequencePool sequencePool, byte[] array)
        {
            _buffered       = 0;
            _bytesCommitted = 0;
            _sequencePool   = sequencePool ?? throw new ArgumentNullException(nameof(sequencePool));
            _rental         = default;
            _output         = null;

            _segment = new ArraySegment <byte>(array);
            _span    = _segment.AsSpan();
        }
Esempio n. 14
0
 /// <summary>
 ///   Reads the next value as character string with a UNIVERSAL tag appropriate to the specified
 ///   encoding type, copying the value into a provided destination buffer.
 /// </summary>
 /// <param name="encodingType">
 ///   A <see cref="UniversalTagNumber"/> corresponding to the value type to process.
 /// </param>
 /// <param name="destination">The buffer in which to write.</param>
 /// <param name="bytesWritten">
 ///   On success, receives the number of bytes written to <paramref name="destination"/>.
 /// </param>
 /// <returns>
 ///   <c>true</c> and advances the reader if <paramref name="destination"/> had sufficient
 ///   length to receive the value, otherwise
 ///   <c>false</c> and the reader does not advance.
 /// </returns>
 /// <remarks>
 ///   This method does not determine if the string used only characters defined by the encoding.
 /// </remarks>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   <paramref name="encodingType"/> is not a known character string type.
 /// </exception>
 /// <exception cref="CryptographicException">
 ///   the next value does not have the correct tag --OR--
 ///   the length encoding is not valid under the current encoding rules --OR--
 ///   the contents are not valid under the current encoding rules
 /// </exception>
 /// <seealso cref="TryReadPrimitiveCharacterStringBytes(UniversalTagNumber,out ReadOnlyMemory{byte})"/>
 /// <seealso cref="ReadCharacterString(UniversalTagNumber)"/>
 /// <seealso cref="TryCopyCharacterString(UniversalTagNumber,Span{char},out int)"/>
 public bool TryCopyCharacterStringBytes(
     UniversalTagNumber encodingType,
     ArraySegment <byte> destination,
     out int bytesWritten)
 {
     return(this.TryCopyCharacterStringBytes(
                new Asn1Tag(encodingType),
                encodingType,
                destination.AsSpan(),
                out bytesWritten));
 }
Esempio n. 15
0
 public bool TryCopyBitStringBytes(
     ArraySegment <byte> destination,
     out int unusedBitCount,
     out int bytesWritten)
 {
     return(TryCopyBitStringBytes(
                Asn1Tag.PrimitiveBitString,
                destination.AsSpan(),
                out unusedBitCount,
                out bytesWritten));
 }
Esempio n. 16
0
 /// <summary>
 ///   Reads the next value as character string with a UNIVERSAL tag appropriate to the specified
 ///   encoding type, copying the decoded value into a provided destination buffer.
 /// </summary>
 /// <param name="encodingType">
 ///   A <see cref="UniversalTagNumber"/> corresponding to the value type to process.
 /// </param>
 /// <param name="destination">The buffer in which to write.</param>
 /// <param name="charsWritten">
 ///   On success, receives the number of chars written to <paramref name="destination"/>.
 /// </param>
 /// <returns>
 ///   <c>true</c> and advances the reader if <paramref name="destination"/> had sufficient
 ///   length to receive the value, otherwise
 ///   <c>false</c> and the reader does not advance.
 /// </returns>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   <paramref name="encodingType"/> is not a known character string type.
 /// </exception>
 /// <exception cref="CryptographicException">
 ///   the next value does not have the correct tag --OR--
 ///   the length encoding is not valid under the current encoding rules --OR--
 ///   the contents are not valid under the current encoding rules --OR--
 ///   the string did not successfully decode
 /// </exception>
 /// <seealso cref="TryReadPrimitiveCharacterStringBytes(UniversalTagNumber,out ReadOnlyMemory{byte})"/>
 /// <seealso cref="ReadCharacterString(UniversalTagNumber)"/>
 /// <seealso cref="TryCopyCharacterStringBytes(UniversalTagNumber,ArraySegment{byte},out int)"/>
 /// <seealso cref="TryCopyCharacterString(Asn1Tag,UniversalTagNumber,ArraySegment{char},out int)"/>
 public bool TryCopyCharacterString(
     UniversalTagNumber encodingType,
     ArraySegment <char> destination,
     out int charsWritten)
 {
     return(TryCopyCharacterString(
                new Asn1Tag(encodingType),
                encodingType,
                destination.AsSpan(),
                out charsWritten));
 }
Esempio n. 17
0
 /// <summary>
 ///   Reads the next value as character string with the specified tag and
 ///   encoding type, copying the decoded value into a provided destination buffer.
 /// </summary>
 /// <param name="expectedTag">The tag to check for before reading.</param>
 /// <param name="encodingType">
 ///   A <see cref="UniversalTagNumber"/> corresponding to the value type to process.
 /// </param>
 /// <param name="destination">The buffer in which to write.</param>
 /// <param name="charsWritten">
 ///   On success, receives the number of chars written to <paramref name="destination"/>.
 /// </param>
 /// <returns>
 ///   <c>true</c> and advances the reader if <paramref name="destination"/> had sufficient
 ///   length to receive the value, otherwise
 ///   <c>false</c> and the reader does not advance.
 /// </returns>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   <paramref name="encodingType"/> is not a known character string type.
 /// </exception>
 /// <exception cref="CryptographicException">
 ///   the next value does not have the correct tag --OR--
 ///   the length encoding is not valid under the current encoding rules --OR--
 ///   the contents are not valid under the current encoding rules --OR--
 ///   the string did not successfully decode
 /// </exception>
 /// <exception cref="ArgumentException">
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is
 ///   <see cref="TagClass.Universal"/>, but
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not the same as
 ///   <paramref name="encodingType"/>.
 /// </exception>
 /// <seealso cref="TryReadPrimitiveCharacterStringBytes(Asn1Tag,UniversalTagNumber,out ReadOnlyMemory{byte})"/>
 /// <seealso cref="TryCopyCharacterStringBytes(Asn1Tag,UniversalTagNumber,ArraySegment{byte},out int)"/>
 /// <seealso cref="ReadCharacterString(Asn1Tag,UniversalTagNumber)"/>
 public bool TryCopyCharacterString(
     Asn1Tag expectedTag,
     UniversalTagNumber encodingType,
     ArraySegment <char> destination,
     out int charsWritten)
 {
     return(this.TryCopyCharacterString(
                expectedTag,
                encodingType,
                destination.AsSpan(),
                out charsWritten));
 }
Esempio n. 18
0
 /// <summary>
 ///   Reads the next value as character string with the specified tag and
 ///   encoding type, copying the value into a provided destination buffer.
 /// </summary>
 /// <param name="expectedTag">The tag to check for before reading.</param>
 /// <param name="encodingType">
 ///   A <see cref="UniversalTagNumber"/> corresponding to the value type to process.
 /// </param>
 /// <param name="destination">The buffer in which to write.</param>
 /// <param name="bytesWritten">
 ///   On success, receives the number of bytes written to <paramref name="destination"/>.
 /// </param>
 /// <returns>
 ///   <c>true</c> and advances the reader if <paramref name="destination"/> had sufficient
 ///   length to receive the value, otherwise
 ///   <c>false</c> and the reader does not advance.
 /// </returns>
 /// <remarks>
 ///   This method does not determine if the string used only characters defined by the encoding.
 /// </remarks>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   <paramref name="encodingType"/> is not a known character string type.
 /// </exception>
 /// <exception cref="CryptographicException">
 ///   the next value does not have the correct tag --OR--
 ///   the length encoding is not valid under the current encoding rules --OR--
 ///   the contents are not valid under the current encoding rules
 /// </exception>
 /// <exception cref="ArgumentException">
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is
 ///   <see cref="TagClass.Universal"/>, but
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not the same as
 ///   <paramref name="encodingType"/>.
 /// </exception>
 /// <seealso cref="TryReadPrimitiveCharacterStringBytes(Asn1Tag,UniversalTagNumber,out ReadOnlyMemory{byte})"/>
 /// <seealso cref="ReadCharacterString(Asn1Tag,UniversalTagNumber)"/>
 /// <seealso cref="TryCopyCharacterString(Asn1Tag,UniversalTagNumber,Span{char},out int)"/>
 public bool TryCopyCharacterStringBytes(
     Asn1Tag expectedTag,
     UniversalTagNumber encodingType,
     ArraySegment <byte> destination,
     out int bytesWritten)
 {
     return(TryCopyCharacterStringBytes(
                expectedTag,
                encodingType,
                destination.AsSpan(),
                out bytesWritten));
 }
Esempio n. 19
0
        public IMetricsWriter WriteHelp(string help)
        {
            ValidateState(nameof(WriteHelp), WriterState.MetricStarted);

            Write(_helpPrefix);
            if (_currentMetricEncoded == default)
            {
                _currentMetricEncoded = Write(_currentMetricName);
            }
            else
            {
                Write(_currentMetricEncoded.AsSpan());
            }

            Write(_tokenSeparator);
            Write(EscapeValue(help));
            Write(_newLine);
            _state = WriterState.HelpWritten;

            return(this);
        }
Esempio n. 20
0
 /// <summary>
 ///   Reads the next value as a BIT STRING with a specified tag, copying the value
 ///   into a provided destination buffer.
 /// </summary>
 /// <param name="expectedTag">The tag to check for before reading.</param>
 /// <param name="destination">The buffer in which to write.</param>
 /// <param name="unusedBitCount">
 ///   On success, receives the number of bits in the last byte which were reported as
 ///   "unused" by the writer.
 /// </param>
 /// <param name="bytesWritten">
 ///   On success, receives the number of bytes written to <paramref name="destination"/>.
 /// </param>
 /// <returns>
 ///   <c>true</c> and advances the reader if <paramref name="destination"/> had sufficient
 ///   length to receive the value, otherwise
 ///   <c>false</c> and the reader does not advance.
 /// </returns>
 /// <exception cref="CryptographicException">
 ///   the next value does not have the correct tag --OR--
 ///   the length encoding is not valid under the current encoding rules --OR--
 ///   the contents are not valid under the current encoding rules
 /// </exception>
 /// <exception cref="ArgumentException">
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is
 ///   <see cref="TagClass.Universal"/>, but
 ///   <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not correct for
 ///   the method
 /// </exception>
 /// <seealso cref="TryReadPrimitiveBitStringValue(Asn1Tag,out int,out ReadOnlyMemory{byte})"/>
 /// <seealso cref="ReadBitString(Asn1Tag,out int)"/>
 public bool TryCopyBitStringBytes(
     Asn1Tag expectedTag,
     ArraySegment <byte> destination,
     out int unusedBitCount,
     out int bytesWritten)
 {
     return(this.TryCopyBitStringBytes(
                expectedTag,
                destination.AsSpan(),
                out unusedBitCount,
                out bytesWritten));
 }
Esempio n. 21
0
 public void Write(ArraySegment <byte> value)
 {
     if (value == null)
     {
         Unsafe.As <byte, int>(ref Unsafe.Add(ref span[0], _position)) = -1;
         _position += sizeof(int);
     }
     else
     {
         Write(value.AsSpan());
     }
 }
Esempio n. 22
0
        internal static ArraySegment <byte> Decompress(ArraySegment <byte> compressed, int headerSize, int frameSizeMax)
        {
            Debug.Assert(IsLoaded);
            int decompressedSize = compressed.AsReadOnlySpan(headerSize, 4).ReadInt();

            if (decompressedSize <= headerSize)
            {
                throw new InvalidDataException(
                          $"received compressed ice1 frame with a decompressed size of only {decompressedSize} bytes");
            }
            if (decompressedSize > frameSizeMax)
            {
                throw new InvalidDataException(
                          $"decompressed size of {decompressedSize} bytes is greater than Ice.IncomingFrameSizeMax value");
            }

            byte[] decompressed = new byte[decompressedSize];

            // Prevent GC from moving the byte array, this allow to take the object address and pass it to bzip2 calls.
            var decompressedHandle = GCHandle.Alloc(decompressed, GCHandleType.Pinned);
            var compressedHandle   = GCHandle.Alloc(compressed.Array, GCHandleType.Pinned);
            var bzStream           = new BZStream(decompressedHandle.AddrOfPinnedObject() + headerSize,
                                                  (uint)(decompressedSize - headerSize));

            BzStatus rc;

            try
            {
                rc = (BzStatus)BZ2_bzDecompressInit(ref bzStream, 0, 0);
                if (rc != BzStatus.Ok)
                {
                    throw new TransportException($"bzip2 decompression failed: {rc}");
                }

                bzStream.NextIn  = compressedHandle.AddrOfPinnedObject() + compressed.Offset + headerSize + 4;
                bzStream.AvailIn = (uint)(compressed.Count - headerSize - 4);
                rc = (BzStatus)BZ2_bzDecompress(ref bzStream);
                if (rc != BzStatus.StreamEnd)
                {
                    throw new TransportException($"bzip2 decompression failed: {rc}");
                }
            }
            finally
            {
                rc = (BzStatus)BZ2_bzDecompressEnd(ref bzStream);
                Debug.Assert(rc == BzStatus.Ok);
                decompressedHandle.Free();
                compressedHandle.Free();
            }
            compressed.AsSpan(0, headerSize).CopyTo(decompressed);
            return(decompressed);
        }
Esempio n. 23
0
        public static void ObjectArraySegmentAsSpan()
        {
            object o1 = new object();
            object o2 = new object();
            object o3 = new object();
            object o4 = new object();

            object[] c = { o1, o2, o3, o4 };
            ArraySegment <object> segmentObject = new ArraySegment <object>(c, 1, 2);
            Span <object>         spanObject    = segmentObject.AsSpan();

            spanObject.ValidateReferenceType(o2, o3);
        }
 protected override ImmutableStack <T> AddRange(ImmutableStack <T> values, ref ArraySegment <T> newValues, ISerializationContext context)
 {
     if (newValues.Count == 1)
     {
         return(values.Push(newValues.Singleton()));
     }
     newValues.ReverseInPlace();
     foreach (var value in newValues.AsSpan())
     {
         values = values.Push(value);
     }
     return(values);
 }
Esempio n. 25
0
        public static void ZeroLengthArraySegmentAsSpan()
        {
            int[] empty = Array.Empty <int>();
            ArraySegment <int> segmentEmpty = new ArraySegment <int>(empty);
            Span <int>         spanEmpty    = segmentEmpty.AsSpan();

            spanEmpty.ValidateNonNullEmpty();

            int[] a = { 91, 92, -93, 94 };
            ArraySegment <int> segmentInt = new ArraySegment <int>(a, 0, 0);
            Span <int>         spanInt    = segmentInt.AsSpan();

            spanInt.ValidateNonNullEmpty();
        }
Esempio n. 26
0
        public static void ArraySegmentAsSpanWithStartAndLength(int length, int start, int subLength)
        {
            const int segmentOffset = 5;

            int[] a = new int[length + segmentOffset];
            ArraySegment <int> segment = new ArraySegment <int>(a, segmentOffset, length);
            Span <int>         s       = segment.AsSpan(start, subLength);

            Assert.Equal(subLength, s.Length);
            if (subLength != 0)
            {
                s[0] = 42;
                Assert.Equal(42, a[segmentOffset + start]);
            }
        }
Esempio n. 27
0
        public static unsafe Task?UnsafeSendSync(JSObject jsWs, ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage)
        {
            if (buffer.Count == 0)
            {
                return(WebSocketSend(jsWs, IntPtr.Zero, 0, (int)messageType, endOfMessage));
            }

            var span = buffer.AsSpan();

            // we can do this because the bytes in the buffer are always consumed synchronously (not later with Task resolution)
            fixed(void *spanPtr = span)
            {
                return(WebSocketSend(jsWs, (IntPtr)spanPtr, buffer.Count, (int)messageType, endOfMessage));
            }
        }
Esempio n. 28
0
        public bool TryDecompress(ArraySegment <byte> compressed, MemoryStream decompressed)
        {
            var zlib = this.CompressionLevel == GatewayCompressionLevel.Stream
                ? this.DecompressorStream
                : new DeflateStream(this.CompressedStream, CompressionMode.Decompress, true);

            if (compressed.Array[0] == ZlibPrefix)
            {
                this.CompressedStream.Write(compressed.Array, compressed.Offset + 2, compressed.Count - 2);
            }
            else
            {
                this.CompressedStream.Write(compressed.Array, compressed.Offset, compressed.Count);
            }

            this.CompressedStream.Flush();
            this.CompressedStream.Position = 0;

            var cspan  = compressed.AsSpan();
            var suffix = BinaryPrimitives.ReadUInt32BigEndian(cspan.Slice(cspan.Length - 4));

            if (this.CompressionLevel == GatewayCompressionLevel.Stream && suffix != ZlibFlush)
            {
                if (this.CompressionLevel == GatewayCompressionLevel.Payload)
                {
                    zlib.Dispose();
                }

                return(false);
            }

            try
            {
                zlib.CopyTo(decompressed);
                return(true);
            }
            catch { return(false); }
            finally
            {
                this.CompressedStream.Position = 0;
                this.CompressedStream.SetLength(0);

                if (this.CompressionLevel == GatewayCompressionLevel.Payload)
                {
                    zlib.Dispose();
                }
            }
        }
        /// <summary>
        /// Gets densities for segments with size equal to <paramref name="segmentSize"/>
        /// </summary>
        /// <param name="buckets">Array of buckets</param>
        /// <param name="start">Start timestamp of the event range we want to find. If null, then it is a first event time in the first bucket of the buckets array.</param>
        /// <param name="segmentSize">Length/duration of one segment</param>
        /// <param name="finalize">Flag indicating that density should be calculated for the last incomplete segment if there is one</param>
        /// <param name="nextBatchStartTime">Next start time</param>
        /// <returns></returns>
        public static double[] GetDensities(ArraySegment <Bucket> bucketsArray, long?start, long segmentSize, bool finalize, out long nextBatchStartTime)
        {
            var buckets = bucketsArray.AsSpan();

            if (buckets.Length < 1)
            {
                throw new ArgumentException("Empty array of buckets is not allowed");
            }

            if (!start.HasValue)
            {
                start = buckets[0].GetAbsoluteTimeForEvent(buckets[0].GetFirstEvent());
            }

            long end = buckets[buckets.Length - 1].GetAbsoluteTimeForEvent(buckets[buckets.Length - 1].GetLastEvent()) + 1;

            ushort totalSegments = 0;

            try
            {
                if (finalize)
                {
                    totalSegments = checked ((ushort)Math.Ceiling((end - start.Value) / (double)segmentSize));
                }
                else
                {
                    totalSegments = checked ((ushort)Math.Floor((end - start.Value) / (double)segmentSize));
                }
            }
            catch (OverflowException)
            {
                throw new ArgumentException("Too small segment size for such a big range", nameof(segmentSize));
            }

            var densitiesBuf = new double[totalSegments];

            DensityCalculator.CalculateDensities(
                bucketsArray.AsMemory(),
                new DensityCalculationRequest(start.Value, end, segmentSize),
                densitiesBuf,
                finalize,
                out long processedRange
                );

            nextBatchStartTime = start.Value + processedRange;

            return(densitiesBuf);
        }
Esempio n. 30
0
        internal static JsonDocument ParseValue(Stream utf8Json, JsonDocumentOptions options)
        {
            Debug.Assert(utf8Json != null);

            ArraySegment <byte> drained = ReadToEnd(utf8Json);

            Debug.Assert(drained.Array != null);

            byte[] owned = new byte[drained.Count];
            Buffer.BlockCopy(drained.Array, 0, owned, 0, drained.Count);

            // Holds document content, clear it before returning it.
            drained.AsSpan().Clear();
            ArrayPool <byte> .Shared.Return(drained.Array);

            return(ParseUnrented(owned.AsMemory(), options.GetReaderOptions()));
        }