package git /* #cgo pkg-config: libgit2 #include #include extern int _go_git_odb_foreach(git_odb *db, void *payload); */ import "C" import ( "unsafe" "reflect" "runtime" ) type Odb struct { ptr *C.git_odb } func (v *Odb) Exists(oid *Oid) bool { ret := C.git_odb_exists(v.ptr, oid.toC()) return ret != 0 } func (v *Odb) Write(data []byte, otype int) (oid *Oid, err error) { oid = new(Oid) hdr := (*reflect.SliceHeader)(unsafe.Pointer(&data)) 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 = LastError() } return } func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) { obj = new(OdbObject) ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC()) if ret < 0 { return nil, LastError() } runtime.SetFinalizer(obj, (*OdbObject).Free) return } //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 } return 0; } func (v *Odb) forEachWrap(ch chan *Oid) { C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&ch)) close(ch) } func (v *Odb) ForEach() chan *Oid { ch := make(chan *Oid, 0) go v.forEachWrap(ch) return ch } type OdbObject struct { ptr *C.git_odb_object } func (v *OdbObject) Free() { runtime.SetFinalizer(v, nil) C.git_odb_object_free(v.ptr) } func (object *OdbObject) Id() (oid *Oid) { return newOidFromC(C.git_odb_object_id(object.ptr)) } func (object *OdbObject) Len() (len uint64) { return uint64(C.git_odb_object_size(object.ptr)) } func (object *OdbObject) Data() (data []byte) { var c_blob unsafe.Pointer = C.git_odb_object_data(object.ptr) var blob []byte len := int(C.git_odb_object_size(object.ptr)) sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&blob))) sliceHeader.Cap = len sliceHeader.Len = len sliceHeader.Data = uintptr(c_blob) return blob }