diff options
Diffstat (limited to 'odb.go')
| -rw-r--r-- | odb.go | 95 |
1 files changed, 70 insertions, 25 deletions
@@ -5,18 +5,49 @@ package git #include <git2/errors.h> extern int _go_git_odb_foreach(git_odb *db, void *payload); +extern void _go_git_odb_backend_free(git_odb_backend *backend); */ import "C" import ( - "unsafe" "reflect" "runtime" + "unsafe" ) type Odb struct { ptr *C.git_odb } +type OdbBackend struct { + ptr *C.git_odb_backend +} + +func NewOdb() (odb *Odb, err error) { + odb = new(Odb) + + ret := C.git_odb_new(&odb.ptr) + if ret < 0 { + return nil, MakeGitError(ret) + } + + runtime.SetFinalizer(odb, (*Odb).Free) + return odb, nil +} + +func NewOdbBackendFromC(ptr *C.git_odb_backend) (backend *OdbBackend) { + backend = &OdbBackend{ptr} + return backend +} + +func (v *Odb) AddBackend(backend *OdbBackend, priority int) (err error) { + ret := C.git_odb_add_backend(v.ptr, backend.ptr, C.int(priority)) + if ret < 0 { + backend.Free() + return MakeGitError(ret) + } + return nil +} + func (v *Odb) Exists(oid *Oid) bool { ret := C.git_odb_exists(v.ptr, oid.toC()) return ret != 0 @@ -32,10 +63,10 @@ func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) { ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(hdr.Data), C.size_t(hdr.Len), C.git_otype(otype)) if ret < 0 { - err = MakeGitError(ret) + return nil, MakeGitError(ret) } - return + return oid, nil } func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) { @@ -50,33 +81,43 @@ func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) { } runtime.SetFinalizer(obj, (*OdbObject).Free) - return + return obj, nil +} + +type OdbForEachCallback func(id *Oid) error + +type foreachData struct { + callback OdbForEachCallback + err error } //export odbForEachCb func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int { - ch := *(*chan *Oid)(payload) - oid := newOidFromC(id) - // Because the channel is unbuffered, we never read our own data. If ch is - // readable, the user has sent something on it, which means we should - // abort. - select { - case ch <- oid: - case <-ch: - return -1 + data := (*foreachData)(payload) + + err := data.callback(newOidFromC(id)) + if err != nil { + data.err = err + return C.GIT_EUSER } - return 0; -} -func (v *Odb) forEachWrap(ch chan *Oid) { - C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&ch)) - close(ch) + return 0 } -func (v *Odb) ForEach() chan *Oid { - ch := make(chan *Oid, 0) - go v.forEachWrap(ch) - return ch +func (v *Odb) ForEach(callback OdbForEachCallback) error { + data := foreachData { + callback: callback, + err: nil, + } + + ret := C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&data)) + if ret == C.GIT_EUSER { + return data.err + } else if ret < 0 { + return MakeGitError(ret) + } + + return nil } // Hash determines the object-ID (sha1) of a data buffer. @@ -90,9 +131,9 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) { ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype)); if ret < 0 { - err = MakeGitError(ret) + return nil, MakeGitError(ret) } - return + return oid, nil } // NewReadStream opens a read stream from the ODB. Reading from it will give you the @@ -122,6 +163,10 @@ func (v *Odb) NewWriteStream(size int, otype ObjectType) (*OdbWriteStream, error return stream, nil } +func (v *OdbBackend) Free() { + C._go_git_odb_backend_free(v.ptr) +} + type OdbObject struct { ptr *C.git_odb_object } @@ -185,7 +230,7 @@ func (stream *OdbReadStream) Free() { type OdbWriteStream struct { ptr *C.git_odb_stream - Id Oid + Id Oid } // Write writes to the stream |
