gofakes3/chunk.go
oniumy 2077be77fb Fix chunkedReader.Read not handling early inner.Read return correctly
The previous implementation expected inner.Read to always read until the end of the provided slice.
2023-03-12 14:16:04 +01:00

65 lines
1.3 KiB
Go

package gofakes3
import (
"fmt"
"io"
"io/ioutil"
)
type chunkedReader struct {
inner io.Reader
chunkRemain int
notFirstChunk bool
}
func newChunkedReader(inner io.Reader) *chunkedReader {
return &chunkedReader{
inner: inner,
chunkRemain: 0,
notFirstChunk: false,
}
}
func (r *chunkedReader) Read(p []byte) (n int, err error) {
sizeToRead := len(p)
for sizeToRead > 0 {
if r.chunkRemain > 0 {
// read until this chunk or sizeToRead ends
bytesToRead := sizeToRead
if sizeToRead > r.chunkRemain {
bytesToRead = r.chunkRemain
}
innerN, err := r.inner.Read(p[n : n+bytesToRead])
r.chunkRemain -= innerN
sizeToRead -= innerN
n += innerN
if err != nil {
return n, err
}
} else {
if !r.notFirstChunk {
// Is first chunk.
r.notFirstChunk = true
} else {
// skip last chunk's b"\r\n"
_, err = io.CopyN(ioutil.Discard, r.inner, 2)
if err != nil {
return n, err
}
}
// read next chunk header
chunkSize := 0
_, err = fmt.Fscanf(r.inner, "%x;", &chunkSize)
if err != nil {
return n, err
}
r.chunkRemain = chunkSize
_, err = io.CopyN(ioutil.Discard, r.inner, 16+64+2) // "chunk-signature=" + sizeOfHash + "\r\n"
if err != nil {
return n, err
}
}
}
return n, nil
}