diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2016-08-11 18:07:29 +0200 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-08-11 18:07:29 +0200 |
commit | 1f64d789038594098ea2c9cf796391f101d0bea5 (patch) | |
tree | 50fb530fc2e48560e70489dc81758f54822dcf50 /core | |
parent | c1e277a7ca75ff84741d75ad45e29a2ff3e633e3 (diff) | |
download | go-git-1f64d789038594098ea2c9cf796391f101d0bea5.tar.gz |
core: new MemoryObject, move from memory.Object, packfile.Parser, base on new ObjectStorage interface
Diffstat (limited to 'core')
-rw-r--r-- | core/memory.go | 65 | ||||
-rw-r--r-- | core/memory_test.go | 71 | ||||
-rw-r--r-- | core/object.go | 1 |
3 files changed, 137 insertions, 0 deletions
diff --git a/core/memory.go b/core/memory.go new file mode 100644 index 0000000..6477f74 --- /dev/null +++ b/core/memory.go @@ -0,0 +1,65 @@ +package core + +import ( + "bytes" + "io/ioutil" +) + +// MemoryObject on memory Object implementation +type MemoryObject struct { + t ObjectType + h Hash + cont []byte + sz int64 +} + +// NewMemoryObject creates a new MemoryObject +func NewMemoryObject(t ObjectType, len int64, cont []byte) *MemoryObject { + return &MemoryObject{t: t, sz: len, cont: cont} +} + +// Hash return the object Hash, the hash is calculated on-the-fly the first +// time is called, the subsequent calls the same Hash is returned even if the +// type or the content has changed. The Hash is only generated if the size of +// the content is exactly the Object.Size +func (o *MemoryObject) Hash() Hash { + if o.h == ZeroHash && int64(len(o.cont)) == o.sz { + o.h = ComputeHash(o.t, o.cont) + } + + return o.h +} + +// Type return the ObjectType +func (o *MemoryObject) Type() ObjectType { return o.t } + +// SetType sets the ObjectType +func (o *MemoryObject) SetType(t ObjectType) { o.t = t } + +// Size return the size of the object +func (o *MemoryObject) Size() int64 { return o.sz } + +// SetSize set the object size, the given size should be written afterwards +func (o *MemoryObject) SetSize(s int64) { o.sz = s } + +// Content returns the contents of the object +func (o *MemoryObject) Content() []byte { return o.cont } + +// Reader returns a ObjectReader used to read the object's content. +func (o *MemoryObject) Reader() (ObjectReader, error) { + return ioutil.NopCloser(bytes.NewBuffer(o.cont)), nil +} + +// Writer returns a ObjectWriter used to write the object's content. +func (o *MemoryObject) Writer() (ObjectWriter, error) { + return o, nil +} + +func (o *MemoryObject) Write(p []byte) (n int, err error) { + o.cont = append(o.cont, p...) + return len(p), nil +} + +// Close releases any resources consumed by the object when it is acting as a +// ObjectWriter. +func (o *MemoryObject) Close() error { return nil } diff --git a/core/memory_test.go b/core/memory_test.go new file mode 100644 index 0000000..f1c3f64 --- /dev/null +++ b/core/memory_test.go @@ -0,0 +1,71 @@ +package core + +import ( + "io/ioutil" + + . "gopkg.in/check.v1" +) + +type MemoryObjectSuite struct{} + +var _ = Suite(&MemoryObjectSuite{}) + +func (s *MemoryObjectSuite) TestHash(c *C) { + o := &MemoryObject{} + o.SetType(BlobObject) + o.SetSize(14) + + _, err := o.Write([]byte("Hello, World!\n")) + c.Assert(err, IsNil) + + c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") + + o.SetType(CommitObject) + c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") +} + +func (s *MemoryObjectSuite) TestHashNotFilled(c *C) { + o := &MemoryObject{} + o.SetType(BlobObject) + o.SetSize(14) + + c.Assert(o.Hash(), Equals, ZeroHash) +} + +func (s *MemoryObjectSuite) TestType(c *C) { + o := &MemoryObject{} + o.SetType(BlobObject) + c.Assert(o.Type(), Equals, BlobObject) +} + +func (s *MemoryObjectSuite) TestSize(c *C) { + o := &MemoryObject{} + o.SetSize(42) + c.Assert(o.Size(), Equals, int64(42)) +} + +func (s *MemoryObjectSuite) TestReader(c *C) { + o := &MemoryObject{cont: []byte("foo")} + + reader, err := o.Reader() + c.Assert(err, IsNil) + defer func() { c.Assert(reader.Close(), IsNil) }() + + b, err := ioutil.ReadAll(reader) + c.Assert(err, IsNil) + c.Assert(b, DeepEquals, []byte("foo")) +} + +func (s *MemoryObjectSuite) TestWriter(c *C) { + o := &MemoryObject{} + + writer, err := o.Writer() + c.Assert(err, IsNil) + defer func() { c.Assert(writer.Close(), IsNil) }() + + n, err := writer.Write([]byte("foo")) + c.Assert(err, IsNil) + c.Assert(n, Equals, 3) + + c.Assert(o.cont, DeepEquals, []byte("foo")) +} diff --git a/core/object.go b/core/object.go index 4610c45..01dd660 100644 --- a/core/object.go +++ b/core/object.go @@ -41,6 +41,7 @@ type Object interface { // ObjectStorage generic storage of objects type ObjectStorage interface { + NewObject() Object Set(Object) (Hash, error) Get(Hash) (Object, error) Iter(ObjectType) (ObjectIter, error) |