Next returns buf filled with the next n bytes. buf is only valid until next call of Next. If an error occurs, buf will be nil.
(n int)
| 43 | // Next returns buf filled with the next n bytes. buf is only valid until next call of Next. If an error occurs, buf |
| 44 | // will be nil. |
| 45 | func (r *chunkReader) Next(n int) (buf []byte, err error) { |
| 46 | // Reset the buffer if it is empty |
| 47 | if r.rp == r.wp { |
| 48 | if len(*r.buf) != r.minBufSize { |
| 49 | iobufpool.Put(r.buf) |
| 50 | r.buf = iobufpool.Get(r.minBufSize) |
| 51 | } |
| 52 | r.rp = 0 |
| 53 | r.wp = 0 |
| 54 | } |
| 55 | |
| 56 | // n bytes already in buf |
| 57 | if (r.wp - r.rp) >= n { |
| 58 | buf = (*r.buf)[r.rp : r.rp+n : r.rp+n] |
| 59 | r.rp += n |
| 60 | return buf, err |
| 61 | } |
| 62 | |
| 63 | // buf is smaller than requested number of bytes |
| 64 | if len(*r.buf) < n { |
| 65 | bigBuf := iobufpool.Get(n) |
| 66 | r.wp = copy((*bigBuf), (*r.buf)[r.rp:r.wp]) |
| 67 | r.rp = 0 |
| 68 | iobufpool.Put(r.buf) |
| 69 | r.buf = bigBuf |
| 70 | } |
| 71 | |
| 72 | // buf is large enough, but need to shift filled area to start to make enough contiguous space |
| 73 | minReadCount := n - (r.wp - r.rp) |
| 74 | if (len(*r.buf) - r.wp) < minReadCount { |
| 75 | r.wp = copy((*r.buf), (*r.buf)[r.rp:r.wp]) |
| 76 | r.rp = 0 |
| 77 | } |
| 78 | |
| 79 | // Read at least the required number of bytes from the underlying io.Reader |
| 80 | readBytesCount, err := io.ReadAtLeast(r.r, (*r.buf)[r.wp:], minReadCount) |
| 81 | r.wp += readBytesCount |
| 82 | // fmt.Println("read", n) |
| 83 | if err != nil { |
| 84 | return nil, err |
| 85 | } |
| 86 | |
| 87 | buf = (*r.buf)[r.rp : r.rp+n : r.rp+n] |
| 88 | r.rp += n |
| 89 | return buf, nil |
| 90 | } |