diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2015-10-25 20:30:36 +0100 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2015-10-25 20:30:36 +0100 |
commit | 9a44cd8ccff143a112436c38bfe5581e74b68f07 (patch) | |
tree | f4d2f38cc61647bf159a7c870913e6f6b60828b2 /common | |
parent | be69a505926451bf10450ac68d40265a6f43e150 (diff) | |
download | go-git-9a44cd8ccff143a112436c38bfe5581e74b68f07.tar.gz |
formats/packfile: new reader API
Diffstat (limited to 'common')
-rw-r--r-- | common/hash.go | 35 | ||||
-rw-r--r-- | common/hash_test.go | 27 | ||||
-rw-r--r-- | common/object.go | 95 |
3 files changed, 157 insertions, 0 deletions
diff --git a/common/hash.go b/common/hash.go new file mode 100644 index 0000000..83844c7 --- /dev/null +++ b/common/hash.go @@ -0,0 +1,35 @@ +package common + +import ( + "crypto/sha1" + "encoding/hex" + "strconv" +) + +// Hash SHA1 hased content +type Hash [20]byte + +// ComputeHash compute the hash for a given ObjectType and content +func ComputeHash(t ObjectType, content []byte) Hash { + h := t.Bytes() + h = append(h, ' ') + h = strconv.AppendInt(h, int64(len(content)), 10) + h = append(h, 0) + h = append(h, content...) + + return Hash(sha1.Sum(h)) +} + +// NewHash return a new Hash from a hexadecimal hash representation +func NewHash(s string) Hash { + b, _ := hex.DecodeString(s) + + var h Hash + copy(h[:], b) + + return h +} + +func (h Hash) String() string { + return hex.EncodeToString(h[:]) +} diff --git a/common/hash_test.go b/common/hash_test.go new file mode 100644 index 0000000..cee0c0f --- /dev/null +++ b/common/hash_test.go @@ -0,0 +1,27 @@ +package common + +import ( + "testing" + + . "gopkg.in/check.v1" +) + +func Test(t *testing.T) { TestingT(t) } + +type HashSuite struct{} + +var _ = Suite(&HashSuite{}) + +func (s *HashSuite) TestComputeHash(c *C) { + hash := ComputeHash(BlobObject, []byte("")) + c.Assert(hash.String(), Equals, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391") + + hash = ComputeHash(BlobObject, []byte("Hello, World!\n")) + c.Assert(hash.String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") +} + +func (s *HashSuite) TestNewHash(c *C) { + hash := ComputeHash(BlobObject, []byte("Hello, World!\n")) + + c.Assert(hash, Equals, NewHash(hash.String())) +} diff --git a/common/object.go b/common/object.go new file mode 100644 index 0000000..60c44da --- /dev/null +++ b/common/object.go @@ -0,0 +1,95 @@ +package common + +import ( + "bytes" + "io" +) + +// Object is a generic representation of any git object +type Object interface { + Type() ObjectType + SetType(ObjectType) + Size() int64 + SetSize(int64) + Hash() Hash + Reader() io.Reader + Writer() io.Writer +} + +// ObjectStorage generic storage of objects +type ObjectStorage interface { + New() Object + Set(Object) Hash + Get(Hash) (Object, bool) +} + +// ObjectType internal object type's +type ObjectType int8 + +const ( + CommitObject ObjectType = 1 + TreeObject ObjectType = 2 + BlobObject ObjectType = 3 + TagObject ObjectType = 4 + OFSDeltaObject ObjectType = 6 + REFDeltaObject ObjectType = 7 +) + +func (t ObjectType) String() string { + switch t { + case CommitObject: + return "commit" + case TreeObject: + return "tree" + case BlobObject: + return "blob" + default: + return "-" + } +} + +func (t ObjectType) Bytes() []byte { + return []byte(t.String()) +} + +type RAWObject struct { + b []byte + t ObjectType + s int64 +} + +func (o *RAWObject) Type() ObjectType { return o.t } +func (o *RAWObject) SetType(t ObjectType) { o.t = t } +func (o *RAWObject) Size() int64 { return o.s } +func (o *RAWObject) SetSize(s int64) { o.s = s } +func (o *RAWObject) Reader() io.Reader { return bytes.NewBuffer(o.b) } +func (o *RAWObject) Hash() Hash { return ComputeHash(o.t, o.b) } +func (o *RAWObject) Writer() io.Writer { return o } +func (o *RAWObject) Write(p []byte) (n int, err error) { + o.b = append(o.b, p...) + return len(p), nil +} + +type RAWObjectStorage struct { + Objects map[Hash]*RAWObject +} + +func NewRAWObjectStorage() *RAWObjectStorage { + return &RAWObjectStorage{make(map[Hash]*RAWObject, 0)} +} + +func (o *RAWObjectStorage) New() Object { + return &RAWObject{} +} + +func (o *RAWObjectStorage) Set(obj Object) Hash { + h := obj.Hash() + o.Objects[h] = obj.(*RAWObject) + + return h +} + +func (o *RAWObjectStorage) Get(h Hash) (Object, bool) { + obj, ok := o.Objects[h] + return obj, ok +} |