commit
da5033fb98
92
odb.go
92
odb.go
|
@ -72,6 +72,33 @@ func (v *Odb) ForEach() chan *Oid {
|
|||
return ch
|
||||
}
|
||||
|
||||
// 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)
|
||||
ret := C.git_odb_open_rstream(&stream.ptr, v.ptr, id.toC())
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
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
|
||||
func (v *Odb) NewWriteStream(size int, otype ObjectType) (*OdbWriteStream, error) {
|
||||
stream := new(OdbWriteStream)
|
||||
ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.size_t(size), C.git_otype(otype))
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(stream, (*OdbWriteStream).Free)
|
||||
return stream, nil
|
||||
}
|
||||
|
||||
type OdbObject struct {
|
||||
ptr *C.git_odb_object
|
||||
}
|
||||
|
@ -102,3 +129,68 @@ func (object *OdbObject) Data() (data []byte) {
|
|||
|
||||
return blob
|
||||
}
|
||||
|
||||
type OdbReadStream struct {
|
||||
ptr *C.git_odb_stream
|
||||
}
|
||||
|
||||
// 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)
|
||||
ret := C.git_odb_stream_read(stream.ptr, ptr, size)
|
||||
if ret < 0 {
|
||||
return 0, LastError()
|
||||
}
|
||||
|
||||
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
|
||||
Id Oid
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
ret := C.git_odb_stream_write(stream.ptr, ptr, size)
|
||||
if ret < 0 {
|
||||
return 0, LastError()
|
||||
}
|
||||
|
||||
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 {
|
||||
ret := C.git_odb_stream_finalize_write(stream.Id.toC(), stream.ptr)
|
||||
if ret < 0 {
|
||||
return LastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (stream *OdbWriteStream) Free() {
|
||||
runtime.SetFinalizer(stream, nil)
|
||||
C.git_odb_stream_free(stream.ptr)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOdbStream(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer os.RemoveAll(repo.Workdir())
|
||||
_, _ = seedTestRepo(t, repo)
|
||||
|
||||
odb, error := repo.Odb()
|
||||
checkFatal(t, error)
|
||||
|
||||
str := "hello, world!"
|
||||
|
||||
stream, error := odb.NewWriteStream(len(str), OBJ_BLOB)
|
||||
checkFatal(t, error)
|
||||
n, error := io.WriteString(stream, str)
|
||||
checkFatal(t, error)
|
||||
if n != len(str) {
|
||||
t.Fatalf("Bad write length %v != %v", n, len(str))
|
||||
}
|
||||
|
||||
error = stream.Close()
|
||||
checkFatal(t, error)
|
||||
|
||||
expectedId, error := NewOidFromString("30f51a3fba5274d53522d0f19748456974647b4f")
|
||||
checkFatal(t, error)
|
||||
if stream.Id.Cmp(expectedId) != 0 {
|
||||
t.Fatal("Wrong data written")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue