예제 #1
0
 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);
 }
예제 #2
0
 public void Pop(BytesSegment bs, int count)
 {
     Peek(bs, count);
     Sub(count);
 }
예제 #3
0
 public void Peek(BytesSegment bs, int count)
 {
     CopyTo(bs.Bytes, 0, bs.Offset, count);
 }
예제 #4
0
        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);
        }