Ejemplo n.º 1
1
        public static void RentAndReturnManyOfTheSameSize_NoneAreSame(ArrayPool<byte> pool)
        {
            foreach (int length in new[] { 1, 16, 32, 64, 127, 4096, 4097 })
            {
                for (int iter = 0; iter < 2; iter++)
                {
                    var buffers = new HashSet<byte[]>();
                    for (int i = 0; i < 100; i++)
                    {
                        buffers.Add(pool.Rent(length));
                    }

                    Assert.Equal(100, buffers.Count);

                    foreach (byte[] buffer in buffers)
                    {
                        pool.Return(buffer);
                    }
                }
            }
        }
            public void Dispose()
            {
                byte[]? data = Interlocked.Exchange(ref _data, null !);
                if (data == null)
                {
                    return;
                }

                // The data in this rented buffer only conveys the positions and
                // lengths of tags in a document, but no content; so it does not
                // need to be cleared.
                _pool?.Return(data);
                ByteLength = 0;
            }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public void Dispose()
        {
            if (_data is null)
            {
                return;
            }

            _arrayPool?.Return(_data);
            _data = null;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Releases all resources used by this stream.
        /// </summary>
        /// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langword="false"/> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                pool?.Return(GetBuffer());
                pool = null;
            }

            base.Dispose(disposing);
        }
        /// <summary>
        ///     Dispose the buffer. This is extremely important if buffer pooling is used
        /// </summary>
        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
            _arrayPool?.Return(Buffer);
            Buffer = null;
        }
Ejemplo n.º 6
0
        public void Dispose()
        {
            if (!disposedValue)
            {
                arrayPool?.Return(Array);
                RealLength = 0;
                Array      = System.Array.Empty <T> ();

                disposedValue = true;
            }
        }
Ejemplo n.º 7
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    var ctx = await channel.Reader.ReadAsync(stoppingToken);

                    vmewblock(ctx.Buffer, ctx.Address, ctx.Length);

                    pool?.Return(ctx.Buffer);

                    // use a object pool and return here?
                }
                catch (OperationCanceledException)
                {
                    break;
                }
            }
        }
Ejemplo n.º 8
0
 public static void CanRentManySizedBuffers(ArrayPool<byte> pool)
 {
     for (int i = 1; i < 10000; i++)
     {
         byte[] buffer = pool.Rent(i);
         Assert.Equal(i <= 16 ? 16 : RoundUpToPowerOf2(i), buffer.Length);
         pool.Return(buffer);
     }
 }
Ejemplo n.º 9
0
 public static void CallingReturnWithoutClearingDoesNotClearTheBuffer(ArrayPool<byte> pool)
 {
     byte[] buffer = pool.Rent(4);
     FillArray(buffer);
     pool.Return(buffer, clearArray: false);
     CheckFilledArray(buffer, (byte b1, byte b2) => Assert.Equal(b1, b2));
 }
Ejemplo n.º 10
0
 protected override void Dispose(bool disposing)
 {
     _pool?.Return(_buffer.Array);
 }
Ejemplo n.º 11
0
 public static void CallingReturnBufferWithNullBufferThrows(ArrayPool <byte> pool)
 {
     AssertExtensions.Throws <ArgumentNullException>("array", () => pool.Return(null));
 }
        public void Encrypt(
            Stream reader,
            Stream writer,
            ReadOnlySpan <byte> privateKey   = default,
            ReadOnlySpan <byte> symmetricKey = default,
            IEncryptionProvider symmetricKeyEncryptionProvider = null)
        {
            Check.ArgNotNull(reader, nameof(reader));
            Check.ArgNotNull(writer, nameof(writer));

            byte[]           symmetricKeyRental = null;
            byte[]           ivRental           = null;
            byte[]           headerRental       = null;
            byte[]           signingKeyRental   = null;
            byte[]           buffer             = null;
            ArrayPool <byte> pool = ArrayPool <byte> .Shared;

            try
            {
                buffer = pool.Rent(4096);
                using (var header = this.GenerateHeader(this.options, symmetricKey, privateKey, null, symmetricKeyEncryptionProvider))
                {
                    symmetricKeyRental = pool.Rent(header.SymmetricKey.Memory.Length);
                    ivRental           = pool.Rent(header.IvSize);
                    header.SymmetricKey.Memory.CopyTo(symmetricKeyRental);
                    header.IV.Memory.CopyTo(ivRental);
                    this.algorithm ??= CreateSymmetricAlgorithm(this.options);

                    using (var encryptor = this.algorithm.CreateEncryptor(symmetricKeyRental, ivRental))
                    {
                        var cs = new CryptoStream(writer, encryptor, CryptoStreamMode.Write);
                        using (var bw = new BinaryWriter(writer, Utf8Options.NoBom, true))
                        {
                            bw.Write(new byte[header.HeaderSize]);
                            bw.Flush();
                        }

                        long bytesLeft = reader.Length;

                        while (bytesLeft > 0)
                        {
                            int read = reader.Read(buffer, 0, buffer.Length);
                            bytesLeft -= read;
                            cs.Write(buffer, 0, read);
                        }

                        cs.Flush();
                        cs.FlushFinalBlock();
                        writer.Flush();
                    }

                    headerRental = pool.Rent(header.HeaderSize);
                    header.Bytes.Memory.CopyTo(headerRental);

                    if (!this.options.SkipSigning && header.SigningKey != null && !header.SigningKey.Memory.IsEmpty)
                    {
                        signingKeyRental = pool.Rent(header.SigningKey.Memory.Length);
                        header.SigningKey.CopyTo(signingKeyRental);
                        using (var signer = CreateSigningAlgorithm(this.options))
                        {
                            signer.Key = signingKeyRental;

                            writer.Seek(header.HeaderSize, SeekOrigin.Begin);
                            var hash = signer.ComputeHash(writer);

                            Array.Copy(hash, 0, headerRental, header.Position, hash.Length);
                            hash.Clear();
                        }
                    }

                    writer.Seek(0, SeekOrigin.Begin);
                    using (var bw = new BinaryWriter(writer, Utf8Options.NoBom, true))
                    {
                        bw.Write(headerRental, 0, header.HeaderSize);
                        writer.Flush();
                        writer.Seek(0, SeekOrigin.End);
                    }
                }
            }
            finally
            {
                if (buffer != null)
                {
                    pool.Return(buffer, true);
                }

                if (symmetricKeyRental != null)
                {
                    pool.Return(symmetricKeyRental, true);
                }

                if (ivRental != null)
                {
                    pool.Return(ivRental, true);
                }

                if (headerRental != null)
                {
                    pool.Return(headerRental, true);
                }

                if (signingKeyRental != null)
                {
                    pool.Return(signingKeyRental, true);
                }
            }
        }
Ejemplo n.º 13
0
    /// <inheritdoc/>
    public override int Read(Span <byte> buffer)
    {
        ThrowIfDisposed();

        if (_buffer.Position < _buffer.Length || _completelyBuffered)
        {
            // Just read from the buffer
            return(_buffer.Read(buffer));
        }

        var read = _inner.Read(buffer);

        if (_bufferLimit.HasValue && _bufferLimit - read < _buffer.Length)
        {
            throw new IOException("Buffer limit exceeded.");
        }

        // We're about to go over the threshold, switch to a file
        if (_inMemory && _memoryThreshold - read < _buffer.Length)
        {
            _inMemory = false;
            var oldBuffer = _buffer;
            _buffer = CreateTempFile();
            if (_rentedBuffer == null)
            {
                // Copy data from the in memory buffer to the file stream using a pooled buffer
                oldBuffer.Position = 0;
                var rentedBuffer = _bytePool.Rent(Math.Min((int)oldBuffer.Length, _maxRentedBufferSize));
                try
                {
                    var copyRead = oldBuffer.Read(rentedBuffer);
                    while (copyRead > 0)
                    {
                        _buffer.Write(rentedBuffer.AsSpan(0, copyRead));
                        copyRead = oldBuffer.Read(rentedBuffer);
                    }
                }
                finally
                {
                    _bytePool.Return(rentedBuffer);
                }
            }
            else
            {
                _buffer.Write(_rentedBuffer.AsSpan(0, (int)oldBuffer.Length));
                _bytePool.Return(_rentedBuffer);
                _rentedBuffer = null;
            }
        }

        if (read > 0)
        {
            _buffer.Write(buffer.Slice(0, read));
        }
        else
        {
            _completelyBuffered = true;
        }

        return(read);
    }
Ejemplo n.º 14
0
 public static void ReturningANonPooledBufferOfDifferentSizeToThePoolThrows(ArrayPool <byte> pool)
 {
     AssertExtensions.Throws <ArgumentException>("array", () => pool.Return(new byte[1]));
 }
        /// <summary>
        /// Encrypts the data and returns the encrypted bytes.
        /// </summary>
        /// <param name="blob">The data to encrypt.</param>
        /// <param name="privateKey">
        ///  A password or phrase used to generate the key for the symmetric algorithm.
        /// </param>
        /// <param name="symmetricKey">
        ///  The key for the symmetric algorithm. If used, the private key is ignored
        ///  and the symmetric key is stored with the message.
        /// </param>
        /// <param name="symmetricKeyEncryptionProvider">
        ///  The encryption provider used to encrypt/decrypt the symmetric key when it is
        ///  stored with the message.
        /// </param>
        /// <returns>Encrypted bytes.</returns>
        public ReadOnlySpan <byte> Encrypt(
            ReadOnlySpan <byte> blob,
            ReadOnlySpan <byte> privateKey   = default,
            ReadOnlySpan <byte> symmetricKey = default,
            IEncryptionProvider symmetricKeyEncryptionProvider = null)
        {
            if (blob == null)
            {
                throw new ArgumentNullException(nameof(blob));
            }

            byte[]           symmetricKeyRental = null;
            byte[]           ivRental           = null;
            byte[]           headerRental       = null;
            byte[]           signingKeyRental   = null;
            ArrayPool <byte> pool = ArrayPool <byte> .Shared;

            try
            {
                using (var header = this.GenerateHeader(this.options, symmetricKey, privateKey, null, symmetricKeyEncryptionProvider))
                {
                    byte[] encryptedBlob = null;
                    symmetricKeyRental = pool.Rent(header.SymmetricKey.Memory.Length);
                    ivRental           = pool.Rent(header.IvSize);
                    header.SymmetricKey.Memory.CopyTo(symmetricKeyRental);
                    header.IV.Memory.CopyTo(ivRental);

                    this.algorithm = this.algorithm ?? CreateSymmetricAlgorithm(this.options);
                    using (var encryptor = this.algorithm.CreateEncryptor(symmetricKeyRental, ivRental))
                        using (var ms = new MemoryStream())
                            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                            {
#if NET461 || NET451
                                var next = ArrayPool <byte> .Shared.Rent(blob.Length);

                                blob.CopyTo(next);
                                cs.Write(next, 0, next.Length);
                                next.Clear();
                                ArrayPool <byte> .Shared.Return(next);
#else
                                cs.Write(blob);
#endif
                                cs.Flush();
                                cs.FlushFinalBlock();
                                ms.Flush();
                                encryptedBlob = ms.ToArray();
                            }

                    headerRental = pool.Rent(header.HeaderSize);
                    header.Bytes.Memory.CopyTo(headerRental);

                    if (!this.options.SkipSigning && header.SigningKey != null && !header.SigningKey.Memory.IsEmpty)
                    {
                        signingKeyRental      = pool.Rent(header.SigningKey.Memory.Length);
                        this.signingAlgorithm = this.signingAlgorithm ?? CreateSigningAlgorithm(this.options);

                        header.SigningKey.Memory.CopyTo(signingKeyRental);
                        this.signingAlgorithm.Key = signingKeyRental;
                        var hash = this.signingAlgorithm.ComputeHash(encryptedBlob);

                        Array.Copy(hash, 0, headerRental, header.Position, hash.Length);

                        hash.Clear();
                        hash = null;
                    }

                    using (var ms = new MemoryStream())
                    {
                        using (var writer = new BinaryWriter(ms, Utf8Options.NoBom, true))
                        {
                            writer.Write(headerRental, 0, header.HeaderSize);
                        }

#if NET461 || NET451
                        ms.Write(encryptedBlob, 0, encryptedBlob.Length);
#else
                        ms.Write(encryptedBlob.AsMemory());
#endif
                        encryptedBlob.Clear();
                        ms.Flush();
                        return(ms.ToArray());
                    }
                }
            }
            finally
            {
                if (symmetricKeyRental != null)
                {
                    pool.Return(symmetricKeyRental, true);
                }

                if (ivRental != null)
                {
                    pool.Return(ivRental, true);
                }

                if (headerRental != null)
                {
                    pool.Return(headerRental, true);
                }

                if (signingKeyRental != null)
                {
                    pool.Return(signingKeyRental, true);
                }
            }
        }
Ejemplo n.º 16
0
 public void Dispose()
 {
     _pool.Return(_buffer.Items);
     _buffer.Count = 0;
 }
Ejemplo n.º 17
0
 public void Return(char[] array)
 {
     _arrayPool.Return(array);
 }
Ejemplo n.º 18
0
 public static void Return(T[] array, bool clearArray = false)
 {
     ArrayPoolImpl.Return(array, clearArray);
 }
        public HttpResponseStreamWriter(
            Stream stream,
            Encoding encoding,
            int bufferSize,
            ArrayPool <byte> bytePool,
            ArrayPool <char> charPool)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException(Resources.HttpResponseStreamWriter_StreamNotWritable, nameof(stream));
            }

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

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

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

            _stream         = stream;
            Encoding        = encoding;
            _charBufferSize = bufferSize;

            _encoder  = encoding.GetEncoder();
            _bytePool = bytePool;
            _charPool = charPool;

            _charBuffer = charPool.Rent(bufferSize);

            try
            {
                var requiredLength = encoding.GetMaxByteCount(bufferSize);
                _byteBuffer = bytePool.Rent(requiredLength);
            }
            catch
            {
                charPool.Return(_charBuffer);
                _charBuffer = null;

                if (_byteBuffer != null)
                {
                    bytePool.Return(_byteBuffer);
                    _byteBuffer = null;
                }

                throw;
            }
        }
Ejemplo n.º 20
0
 public void ReturnPools()
 {
     _dreamValuePool.Return(LocalVariables, true);
     _stackPool.Return(_stack);
 }
Ejemplo n.º 21
0
        public static void Renting0LengthArrayReturnsSingleton(ArrayPool<byte> pool)
        {
            byte[] zero0 = pool.Rent(0);
            byte[] zero1 = pool.Rent(0);
            byte[] zero2 = pool.Rent(0);
            byte[] one = pool.Rent(1);

            Assert.Same(zero0, zero1);
            Assert.Same(zero1, zero2);
            Assert.NotSame(zero2, one);

            pool.Return(zero0);
            pool.Return(zero1);
            pool.Return(zero2);
            pool.Return(one);

            Assert.Same(zero0, pool.Rent(0));
        }
Ejemplo n.º 22
0
 public void Return(char[] buffer)
 {
     bufferPool.Return(buffer);
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Buffers a portion of the given stream, returning the buffered stream partition.
        /// </summary>
        /// <param name="stream">
        /// Stream to buffer from.
        /// </param>
        /// <param name="minCount">
        /// Minimum number of bytes to buffer. This method will not return until at least this many bytes have been read from <paramref name="stream"/> or the stream completes.
        /// </param>
        /// <param name="maxCount">
        /// Maximum number of bytes to buffer.
        /// </param>
        /// <param name="absolutePosition">
        /// Current position of the stream, since <see cref="Stream.Position"/> throws if not seekable.
        /// </param>
        /// <param name="arrayPool">
        /// Pool to rent buffer space from.
        /// </param>
        /// <param name="maxArrayPoolRentalSize">
        /// Max size we can request from the array pool.
        /// </param>
        /// <param name="async">
        /// Whether to perform this operation asynchronously.
        /// </param>
        /// <param name="cancellationToken">
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The buffered stream partition with memory backed by an array pool.
        /// </returns>
        internal static async Task <PooledMemoryStream> BufferStreamPartitionInternal(
            Stream stream,
            long minCount,
            long maxCount,
            long absolutePosition,
            ArrayPool <byte> arrayPool,
            int?maxArrayPoolRentalSize,
            bool async,
            CancellationToken cancellationToken)
        {
            long totalRead       = 0;
            var  streamPartition = new PooledMemoryStream(arrayPool, absolutePosition, maxArrayPoolRentalSize ?? DefaultMaxArrayPoolRentalSize);

            // max count to write into a single array
            int maxCountIndividualBuffer;
            // min count to write into a single array
            int minCountIndividualBuffer;
            // the amount that was written into the current array
            int readIndividualBuffer;

            do
            {
                // buffer to write to
                byte[] buffer;
                // offset to start writing at
                int             offset;
                BufferPartition latestBuffer = streamPartition.GetLatestBufferWithAvailableSpaceOrDefault();
                // whether we got a brand new buffer to write into
                bool newbuffer;
                if (latestBuffer != default)
                {
                    buffer    = latestBuffer.Buffer;
                    offset    = latestBuffer.DataLength;
                    newbuffer = false;
                }
                else
                {
                    buffer    = arrayPool.Rent((int)Math.Min(maxCount - totalRead, streamPartition.MaxArraySize));
                    offset    = 0;
                    newbuffer = true;
                }

                // limit max and min count for this buffer by buffer length
                maxCountIndividualBuffer = (int)Math.Min(maxCount - totalRead, buffer.Length - offset);
                // definitionally limited by max; we won't ever have a swapped min/max range
                minCountIndividualBuffer = (int)Math.Min(minCount - totalRead, maxCountIndividualBuffer);

                readIndividualBuffer = await ReadLoopInternal(
                    stream,
                    buffer,
                    offset : offset,
                    minCountIndividualBuffer,
                    maxCountIndividualBuffer,
                    async,
                    cancellationToken).ConfigureAwait(false);

                // if nothing was placed in a brand new array
                if (readIndividualBuffer == 0 && newbuffer)
                {
                    arrayPool.Return(buffer);
                }
                // if brand new array and we did place data in it
                else if (newbuffer)
                {
                    streamPartition.BufferSet.Add(new BufferPartition
                    {
                        Buffer     = buffer,
                        DataLength = readIndividualBuffer
                    });
                }
                // added to an existing array that was not entirely filled
                else
                {
                    latestBuffer.DataLength += readIndividualBuffer;
                }

                totalRead += readIndividualBuffer;

                /* If we filled the buffer this loop, then quitting on min count is pointless. The point of quitting
                 * on min count is when the source stream doesn't have available bytes and we've reached an amount worth
                 * sending instead of blocking on. If we filled the available array, we don't actually know whether more
                 * data is available yet, as we limited our read for reasons outside the stream state. We should therefore
                 * try another read regardless of whether we hit min count.
                 */
            } while (
                // stream is done if this value is zero; no other check matters
                readIndividualBuffer != 0 &&
                // stop filling the partition if we've hit the max size of the partition
                totalRead < maxCount &&
                // stop filling the partition if we've reached min count and we know we've hit at least a pause in the stream
                (totalRead < minCount || readIndividualBuffer == maxCountIndividualBuffer));

            return(streamPartition);
        }
Ejemplo n.º 24
0
        internal const byte ReservedEscapeMessageBytes       = 5;                                                                                                      // 2 characters total, escape one '\' of 1 byte and real one of up to 4 bytes

        internal static async IAsyncEnumerable <string> GetMessageParts(string message, string?steamMessagePrefix = null, bool isAccountLimited = false)
        {
            if (string.IsNullOrEmpty(message))
            {
                throw new ArgumentNullException(nameof(message));
            }

            int prefixBytes  = 0;
            int prefixLength = 0;

            if (!string.IsNullOrEmpty(steamMessagePrefix))
            {
                // We must escape our message prefix if needed
                // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
                steamMessagePrefix = Escape(steamMessagePrefix !);

                prefixBytes = GetMessagePrefixBytes(steamMessagePrefix);

                if (prefixBytes > MaxMessagePrefixBytes)
                {
                    throw new ArgumentOutOfRangeException(nameof(steamMessagePrefix));
                }

                prefixLength = steamMessagePrefix.Length;
            }

            int maxMessageBytes = (isAccountLimited ? MaxMessageBytesForLimitedAccounts : MaxMessageBytesForUnlimitedAccounts) - ReservedContinuationMessageBytes;

            // We must escape our message prior to sending it
            message = Escape(message);

            int           messagePartBytes = prefixBytes;
            StringBuilder messagePart      = new(steamMessagePrefix);

            Decoder          decoder  = Encoding.UTF8.GetDecoder();
            ArrayPool <char> charPool = ArrayPool <char> .Shared;

            using StringReader stringReader = new(message);

            string?line;

            while ((line = await stringReader.ReadLineAsync().ConfigureAwait(false)) != null)
            {
                // Special case for empty newline
                if (line.Length == 0)
                {
                    if (messagePart.Length > prefixLength)
                    {
                        messagePartBytes += NewlineWeight;
                        messagePart.AppendLine();
                    }

                    // Check if we reached the limit for one message
                    if (messagePartBytes + NewlineWeight + ReservedEscapeMessageBytes > maxMessageBytes)
                    {
                        if (stringReader.Peek() >= 0)
                        {
                            messagePart.Append(ParagraphCharacter);
                        }

                        yield return(messagePart.ToString());

                        messagePartBytes = prefixBytes;
                        messagePart.Clear();
                        messagePart.Append(steamMessagePrefix);
                    }

                    // Move on to the next line
                    continue;
                }

                byte[] lineBytes = Encoding.UTF8.GetBytes(line);

                for (int lineBytesRead = 0; lineBytesRead < lineBytes.Length;)
                {
                    if (messagePart.Length > prefixLength)
                    {
                        if (messagePartBytes + NewlineWeight + lineBytes.Length > maxMessageBytes)
                        {
                            messagePart.Append(ParagraphCharacter);

                            yield return(messagePart.ToString());

                            messagePartBytes = prefixBytes;
                            messagePart.Clear();
                            messagePart.Append(steamMessagePrefix);
                        }
                        else
                        {
                            messagePartBytes += NewlineWeight;
                            messagePart.AppendLine();
                        }
                    }

                    int bytesToTake = Math.Min(maxMessageBytes - messagePartBytes, lineBytes.Length - lineBytesRead);

                    // We can never have more characters than bytes used, so this covers the worst case of 1-byte characters exclusively
                    char[] lineChunk = charPool.Rent(bytesToTake);

                    try {
                        // We have to reset the decoder prior to using it, as we must discard any amount of bytes read from previous incomplete character
                        decoder.Reset();

                        int charsUsed = decoder.GetChars(lineBytes, lineBytesRead, bytesToTake, lineChunk, 0, false);

                        switch (charsUsed)
                        {
                        case <= 0:
                            throw new InvalidOperationException(nameof(charsUsed));

                        case >= 2 when(lineChunk[charsUsed - 1] == '\\') && (lineChunk[charsUsed - 2] != '\\'):
                            // If our message is of max length and ends with a single '\' then we can't split it here, because it escapes the next character
                            // Instead, we'll cut this message one char short and include the rest in the next iteration
                            charsUsed--;

                            break;
                        }

                        int bytesUsed = Encoding.UTF8.GetByteCount(lineChunk, 0, charsUsed);

                        if (lineBytesRead > 0)
                        {
                            messagePartBytes += ContinuationCharacterBytes;
                            messagePart.Append(ContinuationCharacter);
                        }

                        lineBytesRead += bytesUsed;

                        messagePartBytes += bytesUsed;
                        messagePart.Append(lineChunk, 0, charsUsed);
                    } finally {
                        charPool.Return(lineChunk);
                    }

                    bool midLineSplitting = false;

                    if (lineBytesRead < lineBytes.Length)
                    {
                        midLineSplitting = true;

                        messagePartBytes += ContinuationCharacterBytes;
                        messagePart.Append(ContinuationCharacter);
                    }

                    // Check if we still have room for one more line
                    if (messagePartBytes + NewlineWeight + ReservedEscapeMessageBytes <= maxMessageBytes)
                    {
                        continue;
                    }

                    if (!midLineSplitting && (stringReader.Peek() >= 0))
                    {
                        messagePart.Append(ParagraphCharacter);
                    }

                    yield return(messagePart.ToString());

                    messagePartBytes = prefixBytes;
                    messagePart.Clear();
                    messagePart.Append(steamMessagePrefix);
                }
            }

            if (messagePart.Length <= prefixLength)
            {
                yield break;
            }

            yield return(messagePart.ToString());
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Returns a previously rented pooled buffer, optionally without clearing it.
 /// </summary>
 /// <param name="buffer">
 /// The rented buffer.
 /// </param>
 /// <param name="clearBuffer">
 /// Whether to clear the data held in the buffer.
 /// </param>
 protected void ReturnBuffer(byte[] buffer, bool clearBuffer = true)
 {
     bufferPool.Return(buffer, clearBuffer);
 }
Ejemplo n.º 26
0
        static void Main(string[] args)
        {
            AdjustPrivileges();

            Console.Clear();
            Console.WindowWidth  = 50;
            Console.WindowHeight = 5;
            Console.BufferWidth  = Console.WindowWidth;
            Console.BufferHeight = Console.WindowHeight;
            do
            {
                Console.Title      = "Demon's Souls Trainer";
                Console.CursorLeft = 0;
                Console.Write("Searching for the process...");
                var procList = Process.GetProcesses()
                               .Where(p => p.MainWindowTitle.Contains("Demon's Souls", StringComparison.InvariantCultureIgnoreCase) &&
                                      p.MainModule.ModuleName.Contains("rpcs3", StringComparison.InvariantCultureIgnoreCase)
                                      ).ToList();
                if (procList.Count == 1)
                {
                    var des = procList[0];
                    Console.Clear();
                    Console.WriteLine($"Opened process {des.Id}: {des.MainModule.ModuleName}");
                    Console.Title        += " (Active)";
                    Console.CursorVisible = false;
                    var ptrBuf  = ArrayPool.Rent(4);
                    var valBuf  = ArrayPool.Rent(valueLength);
                    var nameBuf = ArrayPool.Rent(2 * 16);
                    using (var pmr = ProcessMemoryReader.OpenProcess(des))
                    {
                        var rpcs3Base = pmr.GetMemoryRegions().First(r => r.offset >= 0x1_0000_0000 && (r.offset % 0x1000_0000 == 0)).offset; // should be either 0x1_0000_0000 or 0x3_0000_0000
                        Console.WriteLine($"Guest memory base: 0x{rpcs3Base:x8}");
                        const int statsPointer  = 0x01B4A5EC;                                                                                 // 4
                        const int characterName = 0x202E80B0;                                                                                 // 16*2
                        const int currentSouls  = 0x202E8098;                                                                                 // 4
                        const int offsetHp      = 0x3c4;
                        var       pBase         = (IntPtr)(rpcs3Base + statsPointer);
                        do
                        {
                            pmr.ReadProcessMemory(pBase, 4, ptrBuf, out var readBytes);
                            if (readBytes == 4)
                            {
                                var ptr = (IntPtr)(rpcs3Base + EndianBitConverter.BigEndian.ToUInt32(ptrBuf, 0) + offsetHp);
                                pmr.ReadProcessMemory(ptr, valueLength, valBuf, out readBytes);
                                if (readBytes == valueLength)
                                {
                                    var hp = EndianBitConverter.BigEndian.ToUInt32(valBuf, 4);
                                    var mp = EndianBitConverter.BigEndian.ToUInt32(valBuf, 12);
                                    var st = EndianBitConverter.BigEndian.ToUInt32(valBuf, 20);
                                    if (hp < 9999 && mp < 9999 & st < 9999)
                                    {
                                        Buffer.BlockCopy(valBuf, 4, valBuf, 0, 4);
                                        Buffer.BlockCopy(valBuf, 12, valBuf, 8, 4);
                                        Buffer.BlockCopy(valBuf, 20, valBuf, 16, 4);
                                        pmr.WriteProcessMemory(ptr, valBuf, out _);
                                        pmr.ReadProcessMemory((IntPtr)(rpcs3Base + characterName), 2 * 16, nameBuf, out readBytes);

                                        var name = readBytes > 0 ? Encoding.BigEndianUnicode.GetString(nameBuf, 0, readBytes / 2) : "";
                                        name = name.TrimEnd('\0', ' ');
                                        if (!string.IsNullOrEmpty(name))
                                        {
                                            name += " ";
                                        }

                                        pmr.ReadProcessMemory((IntPtr)(rpcs3Base + currentSouls), 4, ptrBuf, out readBytes);
                                        var souls = rpcs3Base == 0x1_0000_0000 && readBytes == 4 ? EndianBitConverter.BigEndian.ToInt32(ptrBuf, 0).ToString() : "";

                                        Console.CursorLeft = 0;
                                        Console.Write(name);
                                        Console.ForegroundColor = ConsoleColor.Red;
                                        Console.Write($"{hp} ");
                                        Console.ForegroundColor = ConsoleColor.Blue;
                                        Console.Write($"{mp} ");
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        Console.Write($"{st} ");
                                        Console.ResetColor();
                                        Console.Write($"{souls}       ");
                                    }
                                }
                            }
#if DEBUG
                            else
                            {
                                var error = Marshal.GetLastWin32Error();
                                var msg   = new Win32Exception(error).Message;
                                Console.CursorLeft = 0;
                                Console.Write(msg);
                            }
#endif
                            Thread.Sleep(100);
                        } while (!des.HasExited);
                    }
                    ArrayPool.Return(nameBuf);
                    ArrayPool.Return(valBuf);
                    ArrayPool.Return(ptrBuf);
                    Console.Clear();
                    Console.CursorVisible = false;
                }
                else
                {
                    Thread.Sleep(1000);
                }
            } while (true);
        }
Ejemplo n.º 27
0
 public void FreeBuffer()
 {
     _pool.Return(_buffer);
 }
Ejemplo n.º 28
0
 public void Dispose() => Pool.Return(Value);
        public HttpRequestStreamReader(
            Stream stream,
            Encoding encoding,
            int bufferSize,
            ArrayPool<byte> bytePool,
            ArrayPool<char> charPool)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException(Resources.HttpRequestStreamReader_StreamNotReadable, nameof(stream));
            }

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

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

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

            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bufferSize));
            }

            _stream = stream;
            _encoding = encoding;
            _byteBufferSize = bufferSize;
            _bytePool = bytePool;
            _charPool = charPool;

            _decoder = encoding.GetDecoder();

            _byteBuffer = _bytePool.Rent(bufferSize);

            try
            {
                var requiredLength = encoding.GetMaxCharCount(bufferSize);
                _charBuffer = _charPool.Rent(requiredLength);
            }
            catch
            {
                _bytePool.Return(_byteBuffer);
                _byteBuffer = null;

                if (_charBuffer != null)
                {
                    _charPool.Return(_charBuffer);
                    _charBuffer = null;
                }
            }
        }
Ejemplo n.º 30
0
        public static CompressionResult Compress(AssemblyData data, string outputDirectory)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (String.IsNullOrEmpty(outputDirectory))
            {
                throw new ArgumentException("must not be null or empty", nameof(outputDirectory));
            }

            Directory.CreateDirectory(outputDirectory);

            var fi = new FileInfo(data.SourcePath);

            if (!fi.Exists)
            {
                throw new InvalidOperationException($"File '{data.SourcePath}' does not exist");
            }
            // if ((ulong)fi.Length > InputAssemblySizeLimit) {
            //  return CompressionResult.InputTooBig;
            // }

            data.DestinationPath = Path.Combine(outputDirectory, $"{Path.GetFileName (data.SourcePath)}.lz4");
            data.SourceSize      = (uint)fi.Length;

            byte[] sourceBytes = null;
            byte[] destBytes   = null;
            try {
                sourceBytes = bytePool.Rent(checked ((int)fi.Length));
                using (var fs = File.Open(data.SourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    fs.Read(sourceBytes, 0, (int)fi.Length);
                }

                destBytes = bytePool.Rent(LZ4Codec.MaximumOutputSize(sourceBytes.Length));
                int encodedLength = LZ4Codec.Encode(sourceBytes, 0, checked ((int)fi.Length), destBytes, 0, destBytes.Length, LZ4Level.L09_HC);
                if (encodedLength < 0)
                {
                    return(CompressionResult.EncodingFailed);
                }

                data.DestinationSize = (uint)encodedLength;
                using (var fs = File.Open(data.DestinationPath, FileMode.Create, FileAccess.Write, FileShare.Read)) {
                    using (var bw = new BinaryWriter(fs)) {
                        bw.Write(CompressedDataMagic);                           // magic
                        bw.Write(data.DescriptorIndex);                          // index into runtime array of descriptors
                        bw.Write(checked ((uint)fi.Length));                     // file size before compression

                        bw.Write(destBytes, 0, encodedLength);
                        bw.Flush();
                    }
                }
            } finally {
                if (sourceBytes != null)
                {
                    bytePool.Return(sourceBytes);
                }
                if (destBytes != null)
                {
                    bytePool.Return(destBytes);
                }
            }

            return(CompressionResult.Success);
        }
Ejemplo n.º 31
0
 public static void CallingReturnBufferWithNullBufferThrows(ArrayPool<byte> pool)
 {
     Assert.Throws<ArgumentNullException>("array", () => pool.Return(null));
 }
Ejemplo n.º 32
0
 public void Return(T[] array)
 {
     _inner.Return(array);
 }
Ejemplo n.º 33
0
        public static void CallingReturnWithClearingDoesClearTheBuffer(ArrayPool<byte> pool)
        {
            byte[] buffer = pool.Rent(4);
            FillArray(buffer);

            // Note - yes this is bad to hold on to the old instance but we need to validate the contract
            pool.Return(buffer, clearArray: true);
            CheckFilledArray(buffer, (byte b1, byte b2) => Assert.Equal(b1, default(byte)));
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Internal part of the DHT processor, whatever does it mean
        /// </summary>
        /// <param name="inputProcessor">The decoder instance</param>
        /// <param name="defineHuffmanTablesData">The temporal buffer that holds the data that has been read from the Jpeg stream</param>
        /// <param name="remaining">Remaining bits</param>
        public void ProcessDefineHuffmanTablesMarkerLoop(
            ref InputProcessor inputProcessor,
            byte[] defineHuffmanTablesData,
            ref int remaining)
        {
            // Read nCodes and huffman.Valuess (and derive h.Length).
            // nCodes[i] is the number of codes with code length i.
            // h.Length is the total number of codes.
            this.Length = 0;

            int[] ncodes = new int[MaxCodeLength];
            for (int i = 0; i < ncodes.Length; i++)
            {
                ncodes[i]    = defineHuffmanTablesData[i + 1];
                this.Length += ncodes[i];
            }

            if (this.Length == 0)
            {
                throw new ImageFormatException("Huffman table has zero length");
            }

            if (this.Length > MaxNCodes)
            {
                throw new ImageFormatException("Huffman table has excessive length");
            }

            remaining -= this.Length + 17;
            if (remaining < 0)
            {
                throw new ImageFormatException("DHT has wrong length");
            }

            byte[] values = null;
            try
            {
                values = BytePool256.Rent(MaxNCodes);
                inputProcessor.ReadFull(values, 0, this.Length);

                for (int i = 0; i < values.Length; i++)
                {
                    this.Values[i] = values[i];
                }
            }
            finally
            {
                BytePool256.Return(values, true);
            }

            // Derive the look-up table.
            for (int i = 0; i < this.Lut.Length; i++)
            {
                this.Lut[i] = 0;
            }

            int x = 0, code = 0;

            for (int i = 0; i < LutSizeLog2; i++)
            {
                code <<= 1;

                for (int j = 0; j < ncodes[i]; j++)
                {
                    // The codeLength is 1+i, so shift code by 8-(1+i) to
                    // calculate the high bits for every 8-bit sequence
                    // whose codeLength's high bits matches code.
                    // The high 8 bits of lutValue are the encoded value.
                    // The low 8 bits are 1 plus the codeLength.
                    int base2    = code << (7 - i);
                    int lutValue = (this.Values[x] << 8) | (2 + i);

                    for (int k = 0; k < 1 << (7 - i); k++)
                    {
                        this.Lut[base2 | k] = lutValue;
                    }

                    code++;
                    x++;
                }
            }

            // Derive minCodes, maxCodes, and indices.
            int c = 0, index = 0;

            for (int i = 0; i < ncodes.Length; i++)
            {
                int nc = ncodes[i];
                if (nc == 0)
                {
                    this.MinCodes[i] = -1;
                    this.MaxCodes[i] = -1;
                    this.Indices[i]  = -1;
                }
                else
                {
                    this.MinCodes[i] = c;
                    this.MaxCodes[i] = c + nc - 1;
                    this.Indices[i]  = index;
                    c     += nc;
                    index += nc;
                }

                c <<= 1;
            }
        }
Ejemplo n.º 35
0
 public static void ReturningANonPooledBufferOfDifferentSizeToThePoolThrows(ArrayPool<byte> pool)
 {
     Assert.Throws<ArgumentException>("array", () => pool.Return(new byte[1]));
 }
Ejemplo n.º 36
0
 public void Clear()
 {
     Default.Numbers.Return(buckets);
     Slots.Return(slots);
 }
Ejemplo n.º 37
0
 public static void UsePoolInParallel(ArrayPool<byte> pool)
 {
     int[] sizes = new int[] { 16, 32, 64, 128 };
     Parallel.For(0, 250000, i =>
     {
         foreach (int size in sizes)
         {
             byte[] array = pool.Rent(size);
             Assert.NotNull(array);
             Assert.InRange(array.Length, size, int.MaxValue);
             pool.Return(array);
         }
     });
 }
        public HttpResponseStreamWriter(
            Stream stream,
            Encoding encoding,
            int bufferSize,
            ArrayPool<byte> bytePool,
            ArrayPool<char> charPool)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException(Resources.HttpResponseStreamWriter_StreamNotWritable, nameof(stream));
            }

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

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

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

            _stream = stream;
            Encoding = encoding;
            _charBufferSize = bufferSize;

            _encoder = encoding.GetEncoder();
            _bytePool = bytePool;
            _charPool = charPool;

            _charBuffer = charPool.Rent(bufferSize);

            try
            {
                var requiredLength = encoding.GetMaxByteCount(bufferSize);
                _byteBuffer = bytePool.Rent(requiredLength);
            }
            catch
            {
                charPool.Return(_charBuffer);
                _charBuffer = null;

                if (_byteBuffer != null)
                {
                    bytePool.Return(_byteBuffer);
                    _byteBuffer = null;
                }

                throw;
            }
        }
Ejemplo n.º 39
0
 internal void ReturnRentedArrays(ArrayPool <byte> pool, bool clearArray)
 {
     pool.Return(RentedArray, clearArray);
     LinkedSerializedRequest?.ReturnRentedArrays(pool, clearArray);
 }
Ejemplo n.º 40
0
        /// <summary>
        /// 保持应答
        /// </summary>
        /// <param name="listenSocket">监听Socket</param>
        /// <returns></returns>
        private async Task KeepAccept(Socket listenSocket)
        {
            while (!_cancellationTokenSource.IsCancellationRequested)
            {
                var buffer = default(byte[]);

                try
                {
                    var bufferSize = ChannelOptions.MaxPackageLength;
                    buffer = _bufferPool.Rent(bufferSize);

                    var result = await listenSocket
                                 .ReceiveFromAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), SocketFlags.None, _acceptRemoteEndPoint)
                                 .ConfigureAwait(false);

                    var packageData    = new ArraySegment <byte>(buffer, 0, result.ReceivedBytes);
                    var remoteEndPoint = result.RemoteEndPoint as IPEndPoint;

                    var sessionID = _udpSessionIdentifierProvider.GetSessionIdentifier(remoteEndPoint, packageData);

                    var session = await _sessionContainer.GetSessionByIDAsync(sessionID);

                    IVirtualChannel channel = null;

                    if (session != null)
                    {
                        channel = session.Channel as IVirtualChannel;
                    }
                    else
                    {
                        channel = await CreateChannel(_listenSocket, remoteEndPoint, sessionID);

                        if (channel == null)
                        {
                            return;
                        }

                        OnNewClientAccept(channel);
                    }

                    await channel.WritePipeDataAsync(packageData.AsMemory(), _cancellationTokenSource.Token);
                }
                catch (Exception e)
                {
                    if (e is ObjectDisposedException || e is NullReferenceException)
                    {
                        break;
                    }

                    if (e is SocketException se)
                    {
                        var errorCode = se.ErrorCode;

                        //The listen socket was closed
                        if (errorCode == 125 || errorCode == 89 || errorCode == 995 || errorCode == 10004 || errorCode == 10038)
                        {
                            break;
                        }
                    }

                    _logger.LogError(e, $"Listener[{this.ToString()}] failed to receive udp data");
                }
                finally
                {
                    _bufferPool.Return(buffer);
                }
            }

            _stopTaskCompletionSource.TrySetResult(true);
        }