internal HeaderTable SetMaxLength(int maxLength, IBufferPool pool) { if (checked ((int)maxLength) == MaxLength) { return(this); } if (maxLength == 0 || Count == 0) { _buffer?.Dispose(); return(new HeaderTable(maxLength ^ DefaultMaxLength, 0, null)); } int bytesToKeep = 0, headersToKeep = 0, totalBytes = 0; var span = _buffer.Data.Span; for (int i = 0; i < Count; i++) { long lengths = span.Slice(bytesToKeep).Read <long>(); int itemLen = ItemLength(lengths); totalBytes += itemLen; if (totalBytes > MaxLength) { break; } bytesToKeep += itemLen; headersToKeep++; } var newBuffer = pool.Lease(maxLength); _buffer.Data.Span.Slice(0, bytesToKeep).CopyTo(newBuffer.Data.Span.Slice(bytesToKeep)); _buffer.Dispose(); return(new HeaderTable(maxLength ^ DefaultMaxLength, headersToKeep, newBuffer)); }
internal void Ensure(int count = 1) { EnsureAlloc(); var segment = _writingHead; if (segment == null) { segment = AllocateWriteHead(count); } var bytesLeftInBuffer = segment.WritableBytes; // If inadequate bytes left or if the segment is readonly if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < count || segment.ReadOnly) { var nextBuffer = _pool.Lease(count); var nextSegment = new BufferSegment(nextBuffer); segment.Next = nextSegment; _writingHead = nextSegment; } }
internal HeaderTable Add(Header header, IBufferPool pool) { int newHeaderLength = header.Length; if (newHeaderLength > MaxLength) { throw new InvalidOperationException("Indexed header exceeds max length"); } if (_buffer == null) { var buffer = pool.Lease(MaxLength); header.WriteTo(buffer.Data.Span.Slice(0, newHeaderLength)); return(new HeaderTable(_maxLength, 1, buffer)); } else { // shuffle up int headersToKeep = 0, bytesToKeep = 0, totalBytes = newHeaderLength; var span = _buffer.Data.Span; for (int i = 0; i < Count; i++) { long lengths = span.Slice(bytesToKeep).Read <long>(); int itemLen = ItemLength(lengths); totalBytes += itemLen; if (totalBytes > MaxLength) { break; } bytesToKeep += itemLen; headersToKeep++; } span.Slice(0, bytesToKeep).CopyTo(span.Slice(newHeaderLength, bytesToKeep)); header.WriteTo(span.Slice(0, newHeaderLength)); return(new HeaderTable(_maxLength, headersToKeep + 1, _buffer)); } }