Take 2 on polymorphism

This commit is contained in:
Vicent Marti 2013-04-16 23:04:35 +02:00
parent c7286515b8
commit d190d8a6b3
6 changed files with 112 additions and 53 deletions

18
blob.go
View File

@ -7,17 +7,25 @@ package git
*/ */
import "C" import "C"
import ( import (
"runtime"
"unsafe" "unsafe"
"runtime"
) )
type Blob struct { type Blob struct {
ptr *C.git_object ptr *C.git_blob
} }
func (v *Blob) Free() { func (o *Blob) Id() *Oid {
runtime.SetFinalizer(v, nil) return newOidFromC(C.git_blob_id(o.ptr))
C.git_object_free(v.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 {

View File

@ -19,8 +19,17 @@ type Commit struct {
ptr *C.git_commit ptr *C.git_commit
} }
func (c *Commit) Id() *Oid { func (o *Commit) Id() *Oid {
return newOidFromC(C.git_commit_id(c.ptr)) 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 {
@ -28,15 +37,14 @@ func (c *Commit) Message() string {
} }
func (c *Commit) Tree() (*Tree, error) { func (c *Commit) Tree() (*Tree, error) {
tree := new(Tree) var ptr *C.git_object
err := C.git_commit_tree(&tree.ptr, c.ptr) err := C.git_commit_tree(&ptr, c.ptr)
if err < 0 { if err < 0 {
return nil, LastError() return nil, LastError()
} }
runtime.SetFinalizer(tree, (*Tree).Free) return allocObject(ptr).(*Tree), nil
return tree, nil
} }
func (c *Commit) TreeId() *Oid { func (c *Commit) TreeId() *Oid {

49
object.go Normal file
View File

@ -0,0 +1,49 @@
package git
/*
#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
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
}

9
odb.go
View File

@ -12,15 +12,6 @@ import (
"runtime" "runtime"
) )
var (
OBJ_ANY = C.GIT_OBJ_ANY
OBJ_BAD = C.GIT_OBJ_BAD
OBJ_COMMIT = C.GIT_OBJ_COMMIT
OBJ_TREE = C.GIT_OBJ_TREE
OBJ_BLOB = C.GIT_OBJ_BLOB
OBJ_TAG = C.GIT_OBJ_TAG
)
type Odb struct { type Odb struct {
ptr *C.git_odb ptr *C.git_odb
} }

View File

@ -72,35 +72,41 @@ func (v *Repository) Index() (*Index, error) {
return newIndexFromC(ptr), nil return newIndexFromC(ptr), nil
} }
func (v *Repository) LookupTree(oid *Oid) (*Tree, error) { func (v *Repository) Lookup(oid *Oid, t ObjectType) (Object, error) {
tree := new(Tree) var ptr *C.git_object
ret := C.git_tree_lookup(&tree.ptr, v.ptr, oid.toC()) ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t))
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
} }
return tree, nil return allocObject(ptr), nil
} }
func (v *Repository) LookupCommit(o *Oid) (*Commit, error) { func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
commit := new(Commit) obj, err := v.Lookup(oid, OBJ_TREE)
ecode := C.git_commit_lookup(&commit.ptr, v.ptr, o.toC()) if err != nil {
if ecode < 0 { return nil, err
return nil, LastError()
} }
return commit, nil return obj.(*Tree), nil
} }
func (v *Repository) LookupBlob(o *Oid) (*Blob, error) { func (v *Repository) LookupCommit(oid *Oid) (*Commit, error) {
blob := new(Blob) obj, err := v.Lookup(oid, OBJ_COMMIT)
ecode := C.git_blob_lookup(&blob.ptr, v.ptr, o.toC()) if err != nil {
if ecode < 0 { return nil, err
return nil, LastError()
} }
runtime.SetFinalizer(blob, (*Blob).Free) return obj.(*Commit), nil
return blob, nil }
func (v *Repository) LookupBlob(oid *Oid) (*Blob, error) {
obj, err := v.Lookup(oid, OBJ_BLOB)
if err != nil {
return nil, err
}
return obj.(*Blob), nil
} }
func (v *Repository) LookupReference(name string) (*Reference, error) { func (v *Repository) LookupReference(name string) (*Reference, error) {

29
tree.go
View File

@ -17,6 +17,19 @@ type Tree struct {
ptr *C.git_tree 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)
}
type TreeEntry struct { type TreeEntry struct {
Name string Name string
Id *Oid Id *Oid
@ -31,22 +44,6 @@ func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
} }
} }
func (t *Tree) Free() {
runtime.SetFinalizer(t, nil)
C.git_tree_free(t.ptr)
}
func TreeLookup(repo *Repository, oid *Oid) (*Tree, error) {
tree := new(Tree)
err := C.git_tree_lookup(&tree.ptr, repo.ptr, oid.toC())
if err < 0 {
return nil, LastError()
}
runtime.SetFinalizer(tree, (*Tree).Free)
return tree, nil
}
func (t *Tree) EntryByName(filename string) *TreeEntry { func (t *Tree) EntryByName(filename string) *TreeEntry {
cname := C.CString(filename) cname := C.CString(filename)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))