2013-03-05 13:53:04 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <git2.h>
|
2013-05-21 14:37:08 -05:00
|
|
|
|
2016-12-22 08:46:13 -06:00
|
|
|
extern int git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
|
2013-05-21 14:37:08 -05:00
|
|
|
extern int _go_git_odb_foreach(git_odb *db, void *payload);
|
2014-01-29 17:55:17 -06:00
|
|
|
extern void _go_git_odb_backend_free(git_odb_backend *backend);
|
2016-12-22 08:46:13 -06:00
|
|
|
extern int _go_git_odb_write_pack(git_odb_writepack **out, git_odb *db, void *progress_payload);
|
|
|
|
extern int _go_git_odb_writepack_append(git_odb_writepack *writepack, const void *, size_t, git_transfer_progress *);
|
|
|
|
extern int _go_git_odb_writepack_commit(git_odb_writepack *writepack, git_transfer_progress *);
|
|
|
|
extern void _go_git_odb_writepack_free(git_odb_writepack *writepack);
|
2013-03-05 13:53:04 -06:00
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
import (
|
2018-12-27 22:29:20 -06:00
|
|
|
"io"
|
2013-03-05 13:53:04 -06:00
|
|
|
"reflect"
|
|
|
|
"runtime"
|
2014-01-29 17:55:17 -06:00
|
|
|
"unsafe"
|
2013-03-05 13:53:04 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
type Odb struct {
|
|
|
|
ptr *C.git_odb
|
|
|
|
}
|
|
|
|
|
2013-12-18 16:25:54 -06:00
|
|
|
type OdbBackend struct {
|
2014-01-29 17:55:17 -06:00
|
|
|
ptr *C.git_odb_backend
|
2013-12-18 23:33:23 -06:00
|
|
|
}
|
|
|
|
|
2013-12-19 16:24:44 -06:00
|
|
|
func NewOdb() (odb *Odb, err error) {
|
2014-01-29 17:55:17 -06:00
|
|
|
odb = new(Odb)
|
2013-12-18 23:33:23 -06:00
|
|
|
|
2014-12-05 19:44:57 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-01-29 17:55:17 -06:00
|
|
|
ret := C.git_odb_new(&odb.ptr)
|
|
|
|
if ret < 0 {
|
2014-04-03 15:49:22 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2014-01-29 17:55:17 -06:00
|
|
|
}
|
2013-12-18 23:33:23 -06:00
|
|
|
|
2014-01-29 17:55:17 -06:00
|
|
|
runtime.SetFinalizer(odb, (*Odb).Free)
|
2014-04-03 15:39:21 -05:00
|
|
|
return odb, nil
|
2013-12-18 23:33:23 -06:00
|
|
|
}
|
|
|
|
|
2016-09-30 09:00:20 -05:00
|
|
|
func NewOdbBackendFromC(ptr unsafe.Pointer) (backend *OdbBackend) {
|
|
|
|
backend = &OdbBackend{(*C.git_odb_backend)(ptr)}
|
2014-04-03 15:39:21 -05:00
|
|
|
return backend
|
2013-12-20 13:11:24 -06:00
|
|
|
}
|
|
|
|
|
2016-12-22 08:46:13 -06:00
|
|
|
func (v *Odb) AddAlternate(backend *OdbBackend, priority int) (err error) {
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
2014-12-05 19:44:57 -06:00
|
|
|
|
2016-12-22 08:46:13 -06:00
|
|
|
ret := C.git_odb_add_alternate(v.ptr, backend.ptr, C.int(priority))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
if ret < 0 {
|
|
|
|
backend.Free()
|
|
|
|
return MakeGitError(ret)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Odb) AddBackend(backend *OdbBackend, priority int) (err error) {
|
2014-12-05 19:44:57 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-01-29 17:55:17 -06:00
|
|
|
ret := C.git_odb_add_backend(v.ptr, backend.ptr, C.int(priority))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2014-01-29 17:55:17 -06:00
|
|
|
if ret < 0 {
|
|
|
|
backend.Free()
|
2014-04-03 15:49:22 -05:00
|
|
|
return MakeGitError(ret)
|
2014-01-29 17:55:17 -06:00
|
|
|
}
|
|
|
|
return nil
|
2013-12-18 16:25:54 -06:00
|
|
|
}
|
|
|
|
|
2016-12-22 08:46:13 -06:00
|
|
|
func NewOdbBackendOnePack(packfileIndexPath string) (backend *OdbBackend, err error) {
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
cstr := C.CString(packfileIndexPath)
|
|
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
|
|
|
|
var odbOnePack *C.git_odb_backend = nil
|
|
|
|
ret := C.git_odb_backend_one_pack(&odbOnePack, cstr)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
return NewOdbBackendFromC(unsafe.Pointer(odbOnePack)), nil
|
|
|
|
}
|
|
|
|
|
2016-02-02 12:02:15 -06:00
|
|
|
func (v *Odb) ReadHeader(oid *Oid) (uint64, ObjectType, error) {
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
2017-07-08 09:07:51 -05:00
|
|
|
|
2016-02-02 12:02:15 -06:00
|
|
|
var sz C.size_t
|
2019-01-05 04:45:30 -06:00
|
|
|
var cotype C.git_object_t
|
2016-02-02 12:02:15 -06:00
|
|
|
|
|
|
|
ret := C.git_odb_read_header(&sz, &cotype, v.ptr, oid.toC())
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2016-02-02 12:02:15 -06:00
|
|
|
if ret < 0 {
|
2019-01-12 15:21:20 -06:00
|
|
|
return 0, ObjectInvalid, MakeGitError(ret)
|
2016-02-02 12:02:15 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return uint64(sz), ObjectType(cotype), nil
|
|
|
|
}
|
2017-07-08 09:07:51 -05:00
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
func (v *Odb) Exists(oid *Oid) bool {
|
|
|
|
ret := C.git_odb_exists(v.ptr, oid.toC())
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
runtime.KeepAlive(oid)
|
2013-03-05 13:53:04 -06:00
|
|
|
return ret != 0
|
|
|
|
}
|
|
|
|
|
2013-09-11 16:01:27 -05:00
|
|
|
func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) {
|
2013-03-05 13:53:04 -06:00
|
|
|
oid = new(Oid)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2018-07-03 18:43:07 -05:00
|
|
|
var size C.size_t
|
|
|
|
if len(data) > 0 {
|
|
|
|
size = C.size_t(len(data))
|
|
|
|
} else {
|
|
|
|
data = []byte{0}
|
|
|
|
size = C.size_t(0)
|
|
|
|
}
|
|
|
|
|
2019-01-05 04:45:30 -06:00
|
|
|
ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(&data[0]), size, C.git_object_t(otype))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-05 13:53:04 -06:00
|
|
|
if ret < 0 {
|
2014-04-03 15:41:43 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2014-04-03 15:39:21 -05:00
|
|
|
return oid, nil
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
|
|
|
|
obj = new(OdbObject)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC())
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
runtime.KeepAlive(oid)
|
2013-03-05 13:53:04 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
runtime.SetFinalizer(obj, (*OdbObject).Free)
|
2014-04-03 15:39:21 -05:00
|
|
|
return obj, nil
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2014-05-06 07:19:34 -05:00
|
|
|
type OdbForEachCallback func(id *Oid) error
|
|
|
|
|
|
|
|
type foreachData struct {
|
|
|
|
callback OdbForEachCallback
|
2015-03-04 13:40:26 -06:00
|
|
|
err error
|
2014-05-06 07:19:34 -05:00
|
|
|
}
|
|
|
|
|
2013-05-21 14:37:08 -05:00
|
|
|
//export odbForEachCb
|
2015-04-24 02:55:06 -05:00
|
|
|
func odbForEachCb(id *C.git_oid, handle unsafe.Pointer) int {
|
|
|
|
data, ok := pointerHandles.Get(handle).(*foreachData)
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
panic("could not retrieve handle")
|
|
|
|
}
|
2014-05-06 07:19:34 -05:00
|
|
|
|
|
|
|
err := data.callback(newOidFromC(id))
|
|
|
|
if err != nil {
|
|
|
|
data.err = err
|
|
|
|
return C.GIT_EUSER
|
2013-05-21 14:37:08 -05:00
|
|
|
}
|
2014-05-06 07:19:34 -05:00
|
|
|
|
2014-01-29 17:55:17 -06:00
|
|
|
return 0
|
2013-05-21 14:37:08 -05:00
|
|
|
}
|
|
|
|
|
2014-05-06 07:19:34 -05:00
|
|
|
func (v *Odb) ForEach(callback OdbForEachCallback) error {
|
2015-03-04 13:40:26 -06:00
|
|
|
data := foreachData{
|
2014-05-06 07:19:34 -05:00
|
|
|
callback: callback,
|
2015-03-04 13:40:26 -06:00
|
|
|
err: nil,
|
2014-05-06 07:19:34 -05:00
|
|
|
}
|
2013-05-21 14:37:08 -05:00
|
|
|
|
2014-12-05 19:44:57 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2015-04-24 02:55:06 -05:00
|
|
|
handle := pointerHandles.Track(&data)
|
|
|
|
defer pointerHandles.Untrack(handle)
|
|
|
|
|
|
|
|
ret := C._go_git_odb_foreach(v.ptr, handle)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2014-05-06 07:19:34 -05:00
|
|
|
if ret == C.GIT_EUSER {
|
|
|
|
return data.err
|
|
|
|
} else if ret < 0 {
|
|
|
|
return MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2013-05-21 14:37:08 -05:00
|
|
|
}
|
|
|
|
|
2014-01-25 15:18:32 -06:00
|
|
|
// Hash determines the object-ID (sha1) of a data buffer.
|
|
|
|
func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) {
|
|
|
|
oid = new(Oid)
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2018-07-03 18:43:07 -05:00
|
|
|
var size C.size_t
|
|
|
|
if len(data) > 0 {
|
|
|
|
size = C.size_t(len(data))
|
|
|
|
} else {
|
|
|
|
data = []byte{0}
|
|
|
|
size = C.size_t(0)
|
|
|
|
}
|
|
|
|
|
2019-01-05 04:45:30 -06:00
|
|
|
ret := C.git_odb_hash(oid.toC(), unsafe.Pointer(&data[0]), size, C.git_object_t(otype))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(data)
|
2014-01-25 15:18:32 -06:00
|
|
|
if ret < 0 {
|
2014-04-03 15:41:43 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2014-01-25 15:18:32 -06:00
|
|
|
}
|
2014-04-03 15:39:21 -05:00
|
|
|
return oid, nil
|
2014-01-25 15:18:32 -06:00
|
|
|
}
|
|
|
|
|
2013-09-11 12:17:45 -05:00
|
|
|
// NewReadStream opens a read stream from the ODB. Reading from it will give you the
|
|
|
|
// contents of the object.
|
|
|
|
func (v *Odb) NewReadStream(id *Oid) (*OdbReadStream, error) {
|
|
|
|
stream := new(OdbReadStream)
|
2019-01-05 04:45:30 -06:00
|
|
|
var ctype C.git_object_t
|
2018-02-22 02:28:58 -06:00
|
|
|
var csize C.size_t
|
2014-12-05 19:44:57 -06:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2018-02-22 02:28:58 -06:00
|
|
|
ret := C.git_odb_open_rstream(&stream.ptr, &csize, &ctype, v.ptr, id.toC())
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
runtime.KeepAlive(id)
|
2013-09-11 12:17:45 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return nil, MakeGitError(ret)
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
2018-02-22 02:28:58 -06:00
|
|
|
stream.Size = uint64(csize)
|
|
|
|
stream.Type = ObjectType(ctype)
|
2013-09-11 12:17:45 -05:00
|
|
|
runtime.SetFinalizer(stream, (*OdbReadStream).Free)
|
|
|
|
return stream, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewWriteStream opens a write stream to the ODB, which allows you to
|
|
|
|
// create a new object in the database. The size and type must be
|
|
|
|
// known in advance
|
2015-06-07 21:11:21 -05:00
|
|
|
func (v *Odb) NewWriteStream(size int64, otype ObjectType) (*OdbWriteStream, error) {
|
2013-09-11 12:17:45 -05:00
|
|
|
stream := new(OdbWriteStream)
|
2014-12-05 19:58:28 -06:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2019-12-10 16:15:32 -06:00
|
|
|
ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.git_object_size_t(size), C.git_object_t(otype))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-09-11 12:17:45 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return nil, MakeGitError(ret)
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
runtime.SetFinalizer(stream, (*OdbWriteStream).Free)
|
|
|
|
return stream, nil
|
|
|
|
}
|
|
|
|
|
2016-12-22 08:46:13 -06:00
|
|
|
// NewWritePack opens a stream for writing a pack file to the ODB. If the ODB
|
|
|
|
// layer understands pack files, then the given packfile will likely be
|
|
|
|
// streamed directly to disk (and a corresponding index created). If the ODB
|
|
|
|
// layer does not understand pack files, the objects will be stored in whatever
|
|
|
|
// format the ODB layer uses.
|
|
|
|
func (v *Odb) NewWritePack(callback TransferProgressCallback) (*OdbWritepack, error) {
|
|
|
|
writepack := new(OdbWritepack)
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
writepack.callbacks.TransferProgressCallback = callback
|
|
|
|
writepack.callbacksHandle = pointerHandles.Track(&writepack.callbacks)
|
|
|
|
|
|
|
|
ret := C._go_git_odb_write_pack(&writepack.ptr, v.ptr, writepack.callbacksHandle)
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
if ret < 0 {
|
|
|
|
pointerHandles.Untrack(writepack.callbacksHandle)
|
|
|
|
return nil, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
runtime.SetFinalizer(writepack, (*OdbWritepack).Free)
|
|
|
|
return writepack, nil
|
|
|
|
}
|
|
|
|
|
2014-01-29 17:55:17 -06:00
|
|
|
func (v *OdbBackend) Free() {
|
|
|
|
C._go_git_odb_backend_free(v.ptr)
|
|
|
|
}
|
|
|
|
|
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) {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := newOidFromC(C.git_odb_object_id(object.ptr))
|
|
|
|
runtime.KeepAlive(object)
|
|
|
|
return ret
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-03-06 10:15:28 -06:00
|
|
|
func (object *OdbObject) Len() (len uint64) {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := uint64(C.git_odb_object_size(object.ptr))
|
|
|
|
runtime.KeepAlive(object)
|
|
|
|
return ret
|
2013-03-06 10:15:28 -06:00
|
|
|
}
|
|
|
|
|
2016-07-19 14:48:52 -05:00
|
|
|
func (object *OdbObject) Type() ObjectType {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := ObjectType(C.git_odb_object_type(object.ptr))
|
|
|
|
runtime.KeepAlive(object)
|
|
|
|
return ret
|
2016-07-19 14:48:52 -05:00
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
// Data returns a slice pointing to the unmanaged object memory. You must make
|
|
|
|
// sure the object is referenced for at least as long as the slice is used.
|
2013-03-06 10:15:28 -06:00
|
|
|
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
|
|
|
}
|
2013-09-11 12:17:45 -05:00
|
|
|
|
|
|
|
type OdbReadStream struct {
|
2018-02-22 02:28:58 -06:00
|
|
|
ptr *C.git_odb_stream
|
|
|
|
Size uint64
|
|
|
|
Type ObjectType
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read reads from the stream
|
|
|
|
func (stream *OdbReadStream) Read(data []byte) (int, error) {
|
|
|
|
header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
|
|
|
ptr := (*C.char)(unsafe.Pointer(header.Data))
|
|
|
|
size := C.size_t(header.Cap)
|
2014-12-05 19:58:28 -06:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-09-11 12:17:45 -05:00
|
|
|
ret := C.git_odb_stream_read(stream.ptr, ptr, size)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(stream)
|
2013-09-11 12:17:45 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return 0, MakeGitError(ret)
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
2018-12-27 22:29:20 -06:00
|
|
|
if ret == 0 {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
2013-09-11 12:17:45 -05:00
|
|
|
|
|
|
|
header.Len = int(ret)
|
|
|
|
|
|
|
|
return len(data), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close is a dummy function in order to implement the Closer and
|
|
|
|
// ReadCloser interfaces
|
|
|
|
func (stream *OdbReadStream) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (stream *OdbReadStream) Free() {
|
|
|
|
runtime.SetFinalizer(stream, nil)
|
|
|
|
C.git_odb_stream_free(stream.ptr)
|
|
|
|
}
|
|
|
|
|
|
|
|
type OdbWriteStream struct {
|
|
|
|
ptr *C.git_odb_stream
|
2014-01-29 17:55:17 -06:00
|
|
|
Id Oid
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Write writes to the stream
|
|
|
|
func (stream *OdbWriteStream) Write(data []byte) (int, error) {
|
|
|
|
header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
|
|
|
ptr := (*C.char)(unsafe.Pointer(header.Data))
|
|
|
|
size := C.size_t(header.Len)
|
|
|
|
|
2014-12-05 19:58:28 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-09-11 12:17:45 -05:00
|
|
|
ret := C.git_odb_stream_write(stream.ptr, ptr, size)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(stream)
|
2013-09-11 12:17:45 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return 0, MakeGitError(ret)
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return len(data), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close signals that all the data has been written and stores the
|
|
|
|
// resulting object id in the stream's Id field.
|
|
|
|
func (stream *OdbWriteStream) Close() error {
|
2014-12-05 19:58:28 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-09-11 12:17:45 -05:00
|
|
|
ret := C.git_odb_stream_finalize_write(stream.Id.toC(), stream.ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(stream)
|
2013-09-11 12:17:45 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return MakeGitError(ret)
|
2013-09-11 12:17:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (stream *OdbWriteStream) Free() {
|
|
|
|
runtime.SetFinalizer(stream, nil)
|
|
|
|
C.git_odb_stream_free(stream.ptr)
|
|
|
|
}
|
2016-12-22 08:46:13 -06:00
|
|
|
|
|
|
|
// OdbWritepack is a stream to write a packfile to the ODB.
|
|
|
|
type OdbWritepack struct {
|
|
|
|
ptr *C.git_odb_writepack
|
|
|
|
stats C.git_transfer_progress
|
|
|
|
callbacks RemoteCallbacks
|
|
|
|
callbacksHandle unsafe.Pointer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (writepack *OdbWritepack) Write(data []byte) (int, error) {
|
|
|
|
header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
|
|
|
ptr := unsafe.Pointer(header.Data)
|
|
|
|
size := C.size_t(header.Len)
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ret := C._go_git_odb_writepack_append(writepack.ptr, ptr, size, &writepack.stats)
|
|
|
|
runtime.KeepAlive(writepack)
|
|
|
|
if ret < 0 {
|
|
|
|
return 0, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return len(data), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (writepack *OdbWritepack) Commit() error {
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ret := C._go_git_odb_writepack_commit(writepack.ptr, &writepack.stats)
|
|
|
|
runtime.KeepAlive(writepack)
|
|
|
|
if ret < 0 {
|
|
|
|
return MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (writepack *OdbWritepack) Free() {
|
|
|
|
pointerHandles.Untrack(writepack.callbacksHandle)
|
|
|
|
runtime.SetFinalizer(writepack, nil)
|
|
|
|
C._go_git_odb_writepack_free(writepack.ptr)
|
|
|
|
}
|