public void Reserve(long capacity) { if (capacity <= Capacity) { return; } var newBuffer = ReusableByteBufferManager.GetBuffer(capacity); if (this.length > 0) { if (this.bufferValidFrom < this.bufferValidTo) { Array.Copy(this.reusableBuffer.Buffer, this.bufferValidFrom, newBuffer.Buffer, 0, this.length); } else { Array.Copy(this.reusableBuffer.Buffer, this.bufferValidFrom, newBuffer.Buffer, 0, Capacity - this.bufferValidFrom); Array.Copy(this.reusableBuffer.Buffer, 0, newBuffer.Buffer, Capacity - this.bufferValidFrom, this.bufferValidTo); } } this.reusableBuffer.Dispose(); this.reusableBuffer = newBuffer; this.bufferValidFrom = 0; this.bufferValidTo = this.length; }
internal Allocation(ReusableByteBufferManager b, long size) { BufferManager = b; Buffer = new byte[size]; Stream = new MemoryStream(Buffer); Writer = new BinaryWriter(Stream); }
public CircularMemoryStream(int baseCapacity = 0, FeedOverflowMode feedOverflowMode = FeedOverflowMode.ExtendCapacity) { this.overflowMode = feedOverflowMode; if (feedOverflowMode == FeedOverflowMode.ExtendCapacity && baseCapacity == 0) { this.reusableBuffer = ReusableByteBufferManager.GetBuffer(); } else { this.reusableBuffer = ReusableByteBufferManager.GetBuffer(baseCapacity); } }
public async Task <MultipartPartStream> NextPart(CancellationToken?cancellationToken = null) { if (this.noMoreParts) { return(null); } if (this.baseStream == null) { this.baseStream = new BufferedStream(await this.response.Content.ReadAsStreamAsync(), 16384); } if (MultipartBoundary == null) { switch (this.response.StatusCode) { case System.Net.HttpStatusCode.OK: { this.noMoreParts = true; var stream = new MultipartPartStream(this.response.Content.Headers.ContentLength.Value, 0, this.response.Content.Headers.ContentLength.Value); stream.AppendBaseStream(new ReadLengthLimitingStream(this.baseStream, this.response.Content.Headers.ContentLength.Value)); return(stream); } case System.Net.HttpStatusCode.PartialContent: if (this.response.Content.Headers.ContentType.MediaType.ToLowerInvariant() != "multipart/byteranges") { this.noMoreParts = true; var rangeHeader = this.response.Content.Headers.ContentRange; var rangeLength = rangeHeader.To.Value + 1 - rangeHeader.From.Value; var stream = new MultipartPartStream(rangeHeader.Length.Value, rangeHeader.From.Value, rangeLength); stream.AppendBaseStream(new ReadLengthLimitingStream(this.baseStream, rangeLength)); return(stream); } else { MultipartBoundary = "--" + this.response.Content.Headers.ContentType.Parameters.Where(p => p.Name.ToLowerInvariant() == "boundary").First().Value; this.multipartEndBoundary = MultipartBoundary + "--"; this.multipartBufferStream = new(); this.multipartHeaderLines = new(); } break; default: this.response.EnsureSuccessStatusCode(); throw new EndOfStreamException($"Unhandled success status code {this.response.StatusCode}"); } } while (true) { if (cancellationToken.HasValue) { cancellationToken.Value.ThrowIfCancellationRequested(); } var eof = false; using (var buffer = ReusableByteBufferManager.GetBuffer()) { int readSize; if (cancellationToken == null) { readSize = await this.baseStream.ReadAsync(buffer.Buffer, 0, buffer.Buffer.Length); } else { readSize = await this.baseStream.ReadAsync(buffer.Buffer, 0, buffer.Buffer.Length, (CancellationToken)cancellationToken); } if (readSize == 0) { eof = true; } else { this.multipartBufferStream.Feed(buffer.Buffer, 0, readSize); } } for (int i = 0; i < this.multipartBufferStream.Length - 1; ++i) { if (this.multipartBufferStream[i + 0] != '\r' || this.multipartBufferStream[i + 1] != '\n') { continue; } var isEmptyLine = i == 0; if (isEmptyLine) { this.multipartBufferStream.Consume(null, 0, 2); } else { using var buffer = ReusableByteBufferManager.GetBuffer(); if (i > buffer.Buffer.Length) { throw new IOException($"Multipart header line is too long ({i} bytes)"); } this.multipartBufferStream.Consume(buffer.Buffer, 0, i + 2); this.multipartHeaderLines.Add(Encoding.UTF8.GetString(buffer.Buffer, 0, i)); } i = -1; if (this.multipartHeaderLines.Count == 0) { continue; } if (this.multipartHeaderLines.Last() == this.multipartEndBoundary) { this.noMoreParts = true; return(null); } if (!isEmptyLine) { continue; } ContentRangeHeaderValue rangeHeader = null; foreach (var headerLine in this.multipartHeaderLines) { var kvs = headerLine.Split(new char[] { ':' }, 2); if (kvs.Length != 2) { continue; } if (kvs[0].ToLowerInvariant() != "content-range") { continue; } if (ContentRangeHeaderValue.TryParse(kvs[1], out rangeHeader)) { break; } } if (rangeHeader == null) { throw new IOException("Content-Range not found in multipart part"); } this.multipartHeaderLines.Clear(); var rangeFrom = rangeHeader.From.Value; var rangeLength = rangeHeader.To.Value - rangeFrom + 1; var stream = new MultipartPartStream(rangeHeader.Length.Value, rangeFrom, rangeLength); stream.AppendBaseStream(new ConsumeLengthLimitingStream(this.multipartBufferStream, Math.Min(rangeLength, this.multipartBufferStream.Length))); stream.AppendBaseStream(new ReadLengthLimitingStream(this.baseStream, stream.UnfulfilledBaseStreamLength)); return(stream); } if (eof && !this.noMoreParts) { throw new EndOfStreamException("Reached premature EOF"); } } }