aboutsummaryrefslogtreecommitdiff
path: root/objectstore/loose
diff options
context:
space:
mode:
Diffstat (limited to 'objectstore/loose')
-rw-r--r--objectstore/loose/parse.go12
-rw-r--r--objectstore/loose/read_header.go2
-rw-r--r--objectstore/loose/read_reader.go27
3 files changed, 27 insertions, 14 deletions
diff --git a/objectstore/loose/parse.go b/objectstore/loose/parse.go
index fc678262..4021e333 100644
--- a/objectstore/loose/parse.go
+++ b/objectstore/loose/parse.go
@@ -34,16 +34,16 @@ func parseRaw(raw []byte) (objecttype.Type, []byte, error) {
return ty, content, nil
}
-// readHeader reads and parses a loose object header from br.
-// br must be positioned at the start of decoded loose object bytes.
-func readHeader(br *bufio.Reader) (objecttype.Type, int64, error) {
+// readHeader reads and parses a loose object header from br, and returns
+// the raw header bytes including the trailing NUL.
+func readHeader(br *bufio.Reader) ([]byte, objecttype.Type, int64, error) {
header, err := br.ReadSlice(0)
if err != nil {
- return objecttype.TypeInvalid, 0, err
+ return nil, objecttype.TypeInvalid, 0, err
}
ty, size, _, ok := objectheader.Parse(header)
if !ok {
- return objecttype.TypeInvalid, 0, errors.New("objectstore/loose: malformed object header")
+ return nil, objecttype.TypeInvalid, 0, errors.New("objectstore/loose: malformed object header")
}
- return ty, size, nil
+ return header, ty, size, nil
}
diff --git a/objectstore/loose/read_header.go b/objectstore/loose/read_header.go
index 0fa587fc..e6db30cd 100644
--- a/objectstore/loose/read_header.go
+++ b/objectstore/loose/read_header.go
@@ -22,7 +22,7 @@ func (store *Store) ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, er
}
defer func() { _ = zr.Close() }()
- ty, size, err := readHeader(bufio.NewReader(zr))
+ _, ty, size, err := readHeader(bufio.NewReader(zr))
if err != nil {
return objecttype.TypeInvalid, 0, err
}
diff --git a/objectstore/loose/read_reader.go b/objectstore/loose/read_reader.go
index dde0de07..68df820d 100644
--- a/objectstore/loose/read_reader.go
+++ b/objectstore/loose/read_reader.go
@@ -2,18 +2,19 @@ package loose
import (
"bufio"
+ "bytes"
"compress/zlib"
"errors"
"io"
"os"
+ "codeberg.org/lindenii/furgit/internal/iolimit"
"codeberg.org/lindenii/furgit/objectid"
"codeberg.org/lindenii/furgit/objecttype"
)
type objectReader struct {
- // reader is the stream exposed by Read. It may be the raw zlib reader
- // (full object) or a buffered reader positioned at content bytes only.
+ // reader is the stream exposed by Read.
reader io.Reader
// file is the underlying loose object file and is closed by Close.
file *os.File
@@ -53,10 +54,22 @@ func (store *Store) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error)
if err != nil {
return nil, err
}
+
+ br := bufio.NewReader(zr)
+ header, _, size, err := readHeader(br)
+ if err != nil {
+ _ = zr.Close()
+ _ = file.Close()
+ return nil, err
+ }
+
return &objectReader{
- reader: zr,
- file: file,
- zr: zr,
+ reader: io.MultiReader(
+ bytes.NewReader(header),
+ iolimit.ExpectLengthReader(br, size),
+ ),
+ file: file,
+ zr: zr,
}, nil
}
@@ -69,7 +82,7 @@ func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, in
}
br := bufio.NewReader(zr)
- ty, size, err := readHeader(br)
+ _, ty, size, err := readHeader(br)
if err != nil {
_ = zr.Close()
_ = file.Close()
@@ -77,7 +90,7 @@ func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, in
}
return ty, size, &objectReader{
- reader: br,
+ reader: iolimit.ExpectLengthReader(br, size),
file: file,
zr: zr,
}, nil