public void Push(BytesSegment bs) { if (bytes == null) { bytes = bs.GetBytes(true); Length = bytes.Length; return; } if (bytes.Length < bs.Len) { var newBytes = new byte[Length + bs.Len]; CopyTo(newBytes, 0, bs.Len, Length); bytes = newBytes; curPos = bs.Len; } curPos -= bs.Len; Length += bs.Len; Buffer.BlockCopy(bs.Bytes, bs.Offset, bytes, curPos, bs.Len); }
public void Pop(BytesSegment bs, int count) { Peek(bs, count); Sub(count); }
public void Peek(BytesSegment bs, int count) { CopyTo(bs.Bytes, 0, bs.Offset, count); }
public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (state == 2) { throw new EndOfStreamException(); } int matchingPos = 0; int boundaryLength = Boundary.Length; if (state == 1) { state = 2; return(0); } var buf = new BytesSegment(buffer, offset, count); var bufRead = await BaseStream.ReadAsync(buffer, offset, count, cancellationToken); var i = offset; SEARCH: for (; i < offset + bufRead; i++) // TODO: use KMP search algorithm { if (buffer[i] == Boundary[matchingPos]) { if (++matchingPos == boundaryLength) { IsReadingPart = false; state = 1; bstream.Push(new BytesSegment(buffer, i + 1, bufRead - (i + 1))); bufRead = i + 1 - boundaryLength; goto ANOTHERBREAK; } } else { if (matchingPos > 0) { i += -matchingPos + 1; matchingPos = 0; } } } if (matchingPos > 0) { if (bufRead > matchingPos) // if got data before matching beginning { bstream.Push(new BytesSegment(buffer, offset + bufRead - matchingPos, matchingPos)); bufRead -= matchingPos; } else { if (buf.Len > boundaryLength) { var readuntil = boundaryLength; do { bufRead += await BaseStream.ReadAsync(buffer, offset + bufRead, readuntil - bufRead, cancellationToken); } while (bufRead < readuntil); goto SEARCH; } else { // TODO throw new NotImplementedException(); } } } ANOTHERBREAK: var ret = bufRead; _position += ret; return(ret); }