You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/10/31 22:02:46 UTC
[09/20] lucy git commit: Customize and test Go bindings for
FileHandle.
Customize and test Go bindings for FileHandle.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/5bd926fc
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/5bd926fc
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/5bd926fc
Branch: refs/heads/LUCY-282-test-index-go-pt1
Commit: 5bd926fce657c2c9eb03677001859936db992d22
Parents: 5492483
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Oct 26 19:02:51 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Mon Oct 26 21:18:38 2015 -0700
----------------------------------------------------------------------
go/build.go | 9 +++++
go/lucy/store.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++
go/lucy/store_test.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 197 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/5bd926fc/go/build.go
----------------------------------------------------------------------
diff --git a/go/build.go b/go/build.go
index d15f5c8..3921e18 100644
--- a/go/build.go
+++ b/go/build.go
@@ -271,6 +271,15 @@ func specClasses(parcel *cfc.Parcel) {
folderBinding.SpecMethod("Local_Open_Dir", "LocalOpenDir() (DirHandle, error)")
folderBinding.SpecMethod("Local_MkDir", "LocalMkDir(string) error")
folderBinding.Register()
+
+ fhBinding := cfc.NewGoClass(parcel, "Lucy::Store::FileHandle")
+ fhBinding.SpecMethod("", "Write([]byte, int) error")
+ fhBinding.SpecMethod("", "Read([]byte, int64, int) error")
+ fhBinding.SpecMethod("Window", "Window(FileWindow, int64, int64) error")
+ fhBinding.SpecMethod("Release_Window", "ReleaseWindow(FileWindow) error")
+ fhBinding.SpecMethod("Grow", "Grow(int64) error")
+ fhBinding.SpecMethod("Close", "Close() error")
+ fhBinding.Register()
}
func build() {
http://git-wip-us.apache.org/repos/asf/lucy/blob/5bd926fc/go/lucy/store.go
----------------------------------------------------------------------
diff --git a/go/lucy/store.go b/go/lucy/store.go
index da6e1c7..e89fbbe 100644
--- a/go/lucy/store.go
+++ b/go/lucy/store.go
@@ -23,6 +23,9 @@ package lucy
#include "Lucy/Store/Folder.h"
#include "Lucy/Store/InStream.h"
#include "Lucy/Store/OutStream.h"
+#include "Lucy/Store/FileHandle.h"
+#include "Lucy/Store/FSFileHandle.h"
+#include "Lucy/Store/RAMFileHandle.h"
#include "Clownfish/Err.h"
*/
@@ -545,3 +548,94 @@ func (f *FolderIMP) LocalMkDir(name string) error {
}
return nil
}
+
+func (fh *FileHandleIMP) Write(data []byte, size int) error {
+ return clownfish.TrapErr(func() {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ if size > len(data) {
+ panic(clownfish.NewErr(fmt.Sprintf("Buf only %d long, can't write %d bytes",
+ len(data), size)))
+ }
+ octets := C.CString(string(data))
+ defer C.free(unsafe.Pointer(octets))
+ C.LUCY_FH_Write(self, unsafe.Pointer(octets), C.size_t(size))
+ })
+}
+
+func (fh *FileHandleIMP) Read(b []byte, offset int64, length int) error {
+ return clownfish.TrapErr(func() {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ buf := (*C.char)(C.malloc(C.size_t(length)))
+ defer C.free(unsafe.Pointer(buf))
+ C.LUCY_FH_Read(self, buf, C.int64_t(offset), C.size_t(length))
+ dupe := []byte(C.GoStringN(buf, C.int(length)))
+ for i := 0; i < length; i++ {
+ b[i] = dupe[i]
+ }
+ })
+}
+
+func (fh *FileHandleIMP) Grow(length int64) error {
+ return clownfish.TrapErr(func() {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ C.LUCY_FH_Grow(self, C.int64_t(length))
+ })
+}
+
+func (fh *FileHandleIMP) Window(window FileWindow, offset, length int64) error {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ windowC := (*C.lucy_FileWindow)(clownfish.Unwrap(window, "window"))
+ success := C.LUCY_FH_Window(self, windowC, C.int64_t(offset), C.int64_t(length))
+ if !success {
+ cfErr := C.cfish_Err_get_error();
+ return clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(cfErr)))).(error)
+ }
+ return nil
+}
+
+func (fh *FileHandleIMP) ReleaseWindow(window FileWindow) error {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ windowC := (*C.lucy_FileWindow)(clownfish.Unwrap(window, "window"))
+ success := C.LUCY_FH_Release_Window(self, windowC)
+ if !success {
+ cfErr := C.cfish_Err_get_error();
+ return clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(cfErr)))).(error)
+ }
+ return nil
+}
+
+func (fh *FileHandleIMP) Close() error {
+ return clownfish.TrapErr(func() {
+ self := (*C.lucy_FileHandle)(clownfish.Unwrap(fh, "fh"))
+ C.LUCY_FH_Close(self)
+ })
+}
+
+func OpenFSFileHandle(path string, flags uint32) (fh FSFileHandle, err error) {
+ err = clownfish.TrapErr(func() {
+ pathC := (*C.cfish_String)(clownfish.GoToClownfish(path, unsafe.Pointer(C.CFISH_STRING), false))
+ defer C.cfish_decref(unsafe.Pointer(pathC))
+ cfObj := C.lucy_FSFH_open(pathC, C.uint32_t(flags))
+ if cfObj == nil {
+ cfErr := C.cfish_Err_get_error();
+ panic(clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(cfErr)))).(error))
+ }
+ fh = WRAPFSFileHandle(unsafe.Pointer(cfObj))
+ })
+ return fh, err
+}
+
+func OpenRAMFileHandle(path string, flags uint32, ramFile RAMFile) (fh RAMFileHandle, err error) {
+ err = clownfish.TrapErr(func() {
+ pathC := (*C.cfish_String)(clownfish.GoToClownfish(path, unsafe.Pointer(C.CFISH_STRING), false))
+ ramFileC := (*C.lucy_RAMFile)(clownfish.GoToClownfish(ramFile, unsafe.Pointer(C.LUCY_RAMFILE), true))
+ defer C.cfish_decref(unsafe.Pointer(pathC))
+ cfObj := C.lucy_RAMFH_open(pathC, C.uint32_t(flags), ramFileC)
+ if cfObj == nil {
+ cfErr := C.cfish_Err_get_error();
+ panic(clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(cfErr)))).(error))
+ }
+ fh = WRAPRAMFileHandle(unsafe.Pointer(cfObj))
+ })
+ return fh, err
+}
http://git-wip-us.apache.org/repos/asf/lucy/blob/5bd926fc/go/lucy/store_test.go
----------------------------------------------------------------------
diff --git a/go/lucy/store_test.go b/go/lucy/store_test.go
index c5aa6dd..762141b 100644
--- a/go/lucy/store_test.go
+++ b/go/lucy/store_test.go
@@ -443,3 +443,97 @@ func TestFSFolderBasics(t *testing.T) {
defer os.RemoveAll("_fsfolder_go_test")
runFolderTests(t, folder)
}
+
+func TestFileWindowBasics(t *testing.T) {
+ window := NewFileWindow()
+ window.SetOffset(30)
+ if got := window.GetOffset(); got != 30 {
+ t.Errorf("SetOffset/GetOffset: %d", got)
+ }
+ if got := window.GetLen(); got != 0 {
+ t.Errorf("GetLen: %d", got)
+ }
+}
+
+func runFileHandleCommonTests(t *testing.T, makeFH func(uint32) FileHandle) {
+ var err error
+ fh := makeFH(0x2 | 0x4) // FH_WRITE_ONLY | FH_CREATE
+ if fh == nil {
+ t.Errorf("Failed to open FileHandle for write: %v", err)
+ return
+ }
+ fh.SetPath("fake")
+ if got := fh.GetPath(); got != "fake" {
+ t.Errorf("SetPath/GetPath: %v", got)
+ }
+ err = fh.Grow(20)
+ if err != nil {
+ t.Errorf("Grow: %v", err)
+ }
+ fh.Write([]byte("hello"), 5)
+ err = fh.Close()
+ if err != nil {
+ t.Errorf("Close: %v", err)
+ }
+
+ fh = makeFH(0x1) // FH_READ_ONLY
+ if fh == nil {
+ t.Errorf("Failed to open FileHandle for read: %v", err)
+ }
+ fh.SetPath("fake")
+ if got := fh.GetPath(); got != "fake" {
+ t.Errorf("SetPath/GetPath: %v", got)
+ }
+ if got := fh.Length(); got != 5 {
+ t.Errorf("Unexpected Length: %d", got)
+ }
+ buf := make([]byte, 3)
+ fh.Read(buf, 1, 3)
+ if !reflect.DeepEqual(buf, []byte("ell")) {
+ t.Errorf("FH read/write: %v", buf)
+ }
+
+ window := NewFileWindow()
+ err = fh.Window(window, 1, 2)
+ if err != nil {
+ t.Errorf("Window: %v", err)
+ }
+ err = fh.Window(window, 1, 2)
+ if err != nil {
+ t.Errorf("ReleaseWindow: %v", err)
+ }
+
+ err = fh.Close()
+ if err != nil {
+ t.Errorf("Close: %v", err)
+ }
+}
+
+func TestRAMFileHandleAll(t *testing.T) {
+ ramFile := NewRAMFile(nil, false)
+ makeFH := func(flags uint32) FileHandle {
+ fh, err := OpenRAMFileHandle("content", flags, ramFile)
+ if fh == nil || err != nil {
+ t.Errorf("OpenRAMFileHandle: %v", err)
+ }
+ return fh
+ }
+ runFileHandleCommonTests(t, makeFH)
+ fh := makeFH(0x1).(RAMFileHandle) // FH_READ_ONLY
+ if _, ok := fh.GetFile().(RAMFile); !ok {
+ t.Errorf("GetFile")
+ }
+}
+
+func TestFSFileHandleAll(t *testing.T) {
+ path := "_fsfilehandle_test"
+ defer os.Remove(path)
+ makeFH := func(flags uint32) FileHandle {
+ fh, err := OpenFSFileHandle(path, flags)
+ if fh == nil || err != nil {
+ t.Errorf("OpenFSFileHandle: %v", err)
+ }
+ return fh
+ }
+ runFileHandleCommonTests(t, makeFH)
+}