aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2016-08-11 18:07:29 +0200
committerMáximo Cuadros <mcuadros@gmail.com>2016-08-11 18:07:29 +0200
commit1f64d789038594098ea2c9cf796391f101d0bea5 (patch)
tree50fb530fc2e48560e70489dc81758f54822dcf50 /core
parentc1e277a7ca75ff84741d75ad45e29a2ff3e633e3 (diff)
downloadgo-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.go65
-rw-r--r--core/memory_test.go71
-rw-r--r--core/object.go1
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)