aboutsummaryrefslogtreecommitdiffstats
path: root/formats/objfile/common.go
diff options
context:
space:
mode:
Diffstat (limited to 'formats/objfile/common.go')
-rw-r--r--formats/objfile/common.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/formats/objfile/common.go b/formats/objfile/common.go
new file mode 100644
index 0000000..7389086
--- /dev/null
+++ b/formats/objfile/common.go
@@ -0,0 +1,73 @@
+package objfile
+
+import (
+ "errors"
+ "io"
+ "strconv"
+
+ "gopkg.in/src-d/go-git.v3/core"
+)
+
+var (
+ // ErrClosed is returned when the objfile Reader or Writer is already closed.
+ ErrClosed = errors.New("objfile: already closed")
+ // ErrHeader is returned when the objfile has an invalid header.
+ ErrHeader = errors.New("objfile: invalid header")
+)
+
+type header struct {
+ t core.ObjectType
+ size int64
+}
+
+func (h *header) Read(r io.Reader) error {
+ t, err := h.readSlice(r, ' ')
+ if err != nil {
+ return err
+ }
+
+ h.t, err = core.ParseObjectType(string(t))
+ if err != nil {
+ return err
+ }
+
+ size, err := h.readSlice(r, 0)
+ if err != nil {
+ return err
+ }
+
+ h.size, err = strconv.ParseInt(string(size), 10, 64)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (h *header) Write(w io.Writer) error {
+ b := h.t.Bytes()
+ b = append(b, ' ')
+ b = append(b, []byte(strconv.FormatInt(h.size, 10))...)
+ b = append(b, 0)
+ _, err := w.Write(b)
+ return err
+}
+
+// readSlice reads one byte at a time from r until it encounters delim or an
+// error.
+func (h *header) readSlice(r io.Reader, delim byte) ([]byte, error) {
+ var buf [1]byte
+ value := make([]byte, 0, 16)
+ for {
+ if n, err := r.Read(buf[:]); err != nil && (err != io.EOF || n == 0) {
+ if err == io.EOF {
+ return nil, ErrHeader
+ }
+ return nil, err
+ }
+ if buf[0] == delim {
+ return value, nil
+ }
+ value = append(value, buf[0])
+ }
+}