diff options
author | Joshua Sjoding <joshua.sjoding@scjalliance.com> | 2016-02-27 00:30:35 -0800 |
---|---|---|
committer | Joshua Sjoding <joshua.sjoding@scjalliance.com> | 2016-02-27 00:30:35 -0800 |
commit | e3cb5921c8f3b730a8bbd21877176197c20b8fc7 (patch) | |
tree | b56c8d3d3ec2aa5a90d175da7010fe11ee2cdc3e /formats/objfile/common.go | |
parent | ff809118743100300c38d0c626ffe8c840fb1275 (diff) | |
download | go-git-e3cb5921c8f3b730a8bbd21877176197c20b8fc7.tar.gz |
Added objfile format used for loose git objects
Diffstat (limited to 'formats/objfile/common.go')
-rw-r--r-- | formats/objfile/common.go | 73 |
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]) + } +} |