aboutsummaryrefslogtreecommitdiffstats
path: root/formats/objfile/common.go
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2016-02-27 23:50:04 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2016-02-27 23:50:04 +0100
commit9c9cdff966cc181296f400769d3c8596f17e743a (patch)
treeddd60f794c193e1a407e78b5ca94d0a83466fd78 /formats/objfile/common.go
parent1e74b17f05ad27818df39818a0d22107a0b4b424 (diff)
parent31f920a06aa5d7e7cf363645dac02f6e798fffb1 (diff)
downloadgo-git-9c9cdff966cc181296f400769d3c8596f17e743a.tar.gz
Merge pull request #37 from scjalliance/objfile-format
Added support for objfile format
Diffstat (limited to 'formats/objfile/common.go')
-rw-r--r--formats/objfile/common.go79
1 files changed, 79 insertions, 0 deletions
diff --git a/formats/objfile/common.go b/formats/objfile/common.go
new file mode 100644
index 0000000..2f0585f
--- /dev/null
+++ b/formats/objfile/common.go
@@ -0,0 +1,79 @@
+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")
+ // ErrNegativeSize is returned when a negative object size is declared.
+ ErrNegativeSize = errors.New("objfile: negative object size")
+)
+
+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 ErrHeader
+ }
+
+ if h.size < 0 {
+ return ErrNegativeSize
+ }
+
+ 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])
+ }
+}