From a34f9e082ef6430ade6f6ef7c61997169749759b Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 11 Mar 2016 22:49:43 -0500 Subject: [PATCH] lazy part_set reader --- types/part_set.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/types/part_set.go b/types/part_set.go index 06314fe1d..146e23c43 100644 --- a/types/part_set.go +++ b/types/part_set.go @@ -230,6 +230,8 @@ func (ps *PartSet) GetReader() io.Reader { if !ps.IsComplete() { PanicSanity("Cannot GetReader() on incomplete PartSet") } + return NewPartSetReader(ps.parts) + buf := []byte{} for _, part := range ps.parts { buf = append(buf, part.Bytes...) @@ -237,6 +239,41 @@ func (ps *PartSet) GetReader() io.Reader { return bytes.NewReader(buf) } +type PartSetReader struct { + i int + parts []*Part + reader *bytes.Reader +} + +func NewPartSetReader(parts []*Part) *PartSetReader { + return &PartSetReader{ + i: 0, + parts: parts, + reader: bytes.NewReader(parts[0].Bytes), + } +} + +func (psr *PartSetReader) Read(p []byte) (n int, err error) { + readerLen := psr.reader.Len() + if readerLen >= len(p) { + return psr.reader.Read(p) + } else if readerLen > 0 { + n1, err := psr.Read(p[:readerLen]) + if err != nil { + return n1, err + } + n2, err := psr.Read(p[readerLen:]) + return n1 + n2, err + } + + psr.i += 1 + if psr.i >= len(psr.parts) { + return 0, fmt.Errorf("Attempt to read from PartSet but no parts left") + } + psr.reader = bytes.NewReader(psr.parts[psr.i].Bytes) + return psr.Read(p) +} + func (ps *PartSet) StringShort() string { if ps == nil { return "nil-PartSet"