2013-03-05 13:53:04 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#cgo pkg-config: libgit2
|
|
|
|
#include <git2.h>
|
|
|
|
#include <git2/errors.h>
|
2013-05-21 14:37:08 -05:00
|
|
|
|
|
|
|
extern int _go_git_odb_foreach(git_odb *db, void *payload);
|
2013-03-05 13:53:04 -06:00
|
|
|
*/
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
runtime.SetFinalizer(obj, (*OdbObject).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-05-21 14:37:08 -05:00
|
|
|
//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
|
|
|
|
}
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
type OdbObject struct {
|
|
|
|
ptr *C.git_odb_object
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
func (v *OdbObject) Free() {
|
|
|
|
runtime.SetFinalizer(v, nil)
|
|
|
|
C.git_odb_object_free(v.ptr)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-03-06 10:15:28 -06:00
|
|
|
func (object *OdbObject) Id() (oid *Oid) {
|
|
|
|
return newOidFromC(C.git_odb_object_id(object.ptr))
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-03-06 10:15:28 -06:00
|
|
|
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
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|