From e3cb5921c8f3b730a8bbd21877176197c20b8fc7 Mon Sep 17 00:00:00 2001 From: Joshua Sjoding Date: Sat, 27 Feb 2016 00:30:35 -0800 Subject: Added objfile format used for loose git objects --- formats/objfile/common.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 formats/objfile/common.go (limited to 'formats/objfile/common.go') 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]) + } +} -- cgit