From d190d8a6b3717402744902d060be57195f27d604 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 16 Apr 2013 23:04:35 +0200 Subject: Take 2 on polymorphism --- object.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 object.go (limited to 'object.go') diff --git a/object.go b/object.go new file mode 100644 index 0000000..0d55409 --- /dev/null +++ b/object.go @@ -0,0 +1,49 @@ +package git + +/* +#cgo pkg-config: libgit2 +#include +#include +*/ +import "C" +import "runtime" + +type ObjectType int + +var ( + OBJ_ANY ObjectType = C.GIT_OBJ_ANY + OBJ_BAD ObjectType = C.GIT_OBJ_BAD + OBJ_COMMIT ObjectType = C.GIT_OBJ_COMMIT + OBJ_TREE ObjectType = C.GIT_OBJ_TREE + OBJ_BLOB ObjectType = C.GIT_OBJ_BLOB + OBJ_TAG ObjectType = C.GIT_OBJ_TAG +) + +type Object interface { + Free() + Id() *Oid + Type() ObjectType +} + +func allocObject(cobj *C.git_object) Object { + var object Object + + switch ObjectType(C.git_object_type(cobj)) { + case OBJ_COMMIT: + object = &Commit{cobj} + runtime.SetFinalizer(object, (*Commit).Free) + + case OBJ_TREE: + object = &Tree{cobj} + runtime.SetFinalizer(object, (*Tree).Free) + + case OBJ_BLOB: + object = &Blob{cobj} + runtime.SetFinalizer(object, (*Blob).Free) + + default: + return nil + } + + return object +} -- cgit v1.2.3 From 2bf17ba2f18ad3ae3068568e5754046544b159b7 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Thu, 18 Apr 2013 00:54:46 +0200 Subject: Ok, now with shared base object --- blob.go | 20 +++----------------- commit.go | 26 ++++++-------------------- object.go | 38 +++++++++++++++++++++++++++----------- tree.go | 23 +++++------------------ 4 files changed, 41 insertions(+), 66 deletions(-) (limited to 'object.go') diff --git a/blob.go b/blob.go index ee50a15..cc26c92 100644 --- a/blob.go +++ b/blob.go @@ -8,31 +8,17 @@ package git import "C" import ( "unsafe" - "runtime" ) type Blob struct { - ptr *C.git_blob + gitObject } -func (o *Blob) Id() *Oid { - return newOidFromC(C.git_blob_id(o.ptr)) -} - -func (o *Blob) Type() ObjectType { - return OBJ_BLOB -} - -func (o *Blob) Free() { - runtime.SetFinalizer(o, nil) - C.git_blob_free(o.ptr) -} - -func (v *Blob) Size() int64 { +func (v Blob) Size() int64 { return int64(C.git_blob_rawsize(v.ptr)) } -func (v *Blob) Contents() []byte { +func (v Blob) Contents() []byte { size := C.int(C.git_blob_rawsize(v.ptr)) buffer := unsafe.Pointer(C.git_blob_rawcontent(v.ptr)) return C.GoBytes(buffer, size) diff --git a/commit.go b/commit.go index b1ca6c4..9730a70 100644 --- a/commit.go +++ b/commit.go @@ -9,34 +9,20 @@ extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr); import "C" import ( - "runtime" "unsafe" "time" ) // Commit type Commit struct { - ptr *C.git_commit + gitObject } -func (o *Commit) Id() *Oid { - return newOidFromC(C.git_commit_id(o.ptr)) -} - -func (o *Commit) Type() ObjectType { - return OBJ_COMMIT -} - -func (o *Commit) Free() { - runtime.SetFinalizer(o, nil) - C.git_commit_free(o.ptr) -} - -func (c *Commit) Message() string { +func (c Commit) Message() string { return C.GoString(C.git_commit_message(c.ptr)) } -func (c *Commit) Tree() (*Tree, error) { +func (c Commit) Tree() (*Tree, error) { var ptr *C.git_object err := C.git_commit_tree(&ptr, c.ptr) @@ -47,16 +33,16 @@ func (c *Commit) Tree() (*Tree, error) { return allocObject(ptr).(*Tree), nil } -func (c *Commit) TreeId() *Oid { +func (c Commit) TreeId() *Oid { return newOidFromC(C.git_commit_tree_id(c.ptr)) } -func (c *Commit) Author() *Signature { +func (c Commit) Author() *Signature { ptr := C.git_commit_author(c.ptr) return newSignatureFromC(ptr) } -func (c *Commit) Committer() *Signature { +func (c Commit) Committer() *Signature { ptr := C.git_commit_committer(c.ptr) return newSignatureFromC(ptr) } diff --git a/object.go b/object.go index 0d55409..a346234 100644 --- a/object.go +++ b/object.go @@ -25,25 +25,41 @@ type Object interface { Type() ObjectType } +type gitObject struct { + ptr *C.git_object +} + +func (o gitObject) Id() *Oid { + return newOidFromC(C.git_commit_id(o.ptr)) +} + +func (o gitObject) Type() ObjectType { + return ObjectType(C.git_object_type(o.ptr)) +} + +func (o gitObject) Free() { + runtime.SetFinalizer(o, nil) + C.git_commit_free(o.ptr) +} + func allocObject(cobj *C.git_object) Object { - var object Object switch ObjectType(C.git_object_type(cobj)) { case OBJ_COMMIT: - object = &Commit{cobj} - runtime.SetFinalizer(object, (*Commit).Free) + commit := &Commit{gitObject{cobj}} + runtime.SetFinalizer(commit, (*Commit).Free) + return commit case OBJ_TREE: - object = &Tree{cobj} - runtime.SetFinalizer(object, (*Tree).Free) + tree := &Tree{gitObject{cobj}} + runtime.SetFinalizer(tree, (*Tree).Free) + return tree case OBJ_BLOB: - object = &Blob{cobj} - runtime.SetFinalizer(object, (*Blob).Free) - - default: - return nil + blob := &Blob{gitObject{cobj}} + runtime.SetFinalizer(blob, (*Blob).Free) + return blob } - return object + return nil } diff --git a/tree.go b/tree.go index d8a639c..3bc8999 100644 --- a/tree.go +++ b/tree.go @@ -14,20 +14,7 @@ import ( ) type Tree struct { - ptr *C.git_tree -} - -func (o *Tree) Id() *Oid { - return newOidFromC(C.git_tree_id(o.ptr)) -} - -func (o *Tree) Type() ObjectType { - return OBJ_TREE -} - -func (o *Tree) Free() { - runtime.SetFinalizer(o, nil) - C.git_tree_free(o.ptr) + gitObject } type TreeEntry struct { @@ -44,7 +31,7 @@ func newTreeEntry(entry *C.git_tree_entry) *TreeEntry { } } -func (t *Tree) EntryByName(filename string) *TreeEntry { +func (t Tree) EntryByName(filename string) *TreeEntry { cname := C.CString(filename) defer C.free(unsafe.Pointer(cname)) @@ -56,7 +43,7 @@ func (t *Tree) EntryByName(filename string) *TreeEntry { return newTreeEntry(entry) } -func (t *Tree) EntryByIndex(index uint64) *TreeEntry { +func (t Tree) EntryByIndex(index uint64) *TreeEntry { entry := C.git_tree_entry_byindex(t.ptr, C.size_t(index)) if entry == nil { return nil @@ -65,7 +52,7 @@ func (t *Tree) EntryByIndex(index uint64) *TreeEntry { return newTreeEntry(entry) } -func (t *Tree) EntryCount() uint64 { +func (t Tree) EntryCount() uint64 { num := C.git_tree_entrycount(t.ptr) return uint64(num) } @@ -81,7 +68,7 @@ func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe return C.int(callback(root, newTreeEntry(entry))) } -func (t *Tree) Walk(callback TreeWalkCallback) error { +func (t Tree) Walk(callback TreeWalkCallback) error { err := C._go_git_treewalk( t.ptr, C.GIT_TREEWALK_PRE, -- cgit v1.2.3 From ac6ea9aa754dde141c778f862263de26add8afe1 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Fri, 26 Apr 2013 02:06:47 +0200 Subject: Add String() Method to ObjectType --- object.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'object.go') diff --git a/object.go b/object.go index a346234..a98c681 100644 --- a/object.go +++ b/object.go @@ -29,6 +29,25 @@ type gitObject struct { ptr *C.git_object } +func (t ObjectType) String() (string) { + switch (t) { + case OBJ_ANY: + return "Any" + case OBJ_BAD: + return "Bad" + case OBJ_COMMIT: + return "Commit" + case OBJ_TREE: + return "Tree" + case OBJ_BLOB: + return "Blob" + case OBJ_TAG: + return "tag" + } + // Never reached + return "" +} + func (o gitObject) Id() *Oid { return newOidFromC(C.git_commit_id(o.ptr)) } -- cgit v1.2.3 From 289d84e1f7e7618dce387c53034deee55fab0a44 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Fri, 26 Apr 2013 02:32:41 +0200 Subject: Give gitObject.Free a pointer-receiver This is needed to get runtime.SetFinalizer to work, which expects a pointer-receiver. Without it the runtime will crash, when it tries to garbage-collect an object. --- object.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'object.go') diff --git a/object.go b/object.go index a346234..ec1e468 100644 --- a/object.go +++ b/object.go @@ -37,7 +37,7 @@ func (o gitObject) Type() ObjectType { return ObjectType(C.git_object_type(o.ptr)) } -func (o gitObject) Free() { +func (o *gitObject) Free() { runtime.SetFinalizer(o, nil) C.git_commit_free(o.ptr) } -- cgit v1.2.3