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/master
Commit: 5bd926fce657c2c9eb03677001859936db992d22
Parents: 5492483
Author: Marvin Humphrey <[email protected]>
Authored: Mon Oct 26 19:02:51 2015 -0700
Committer: Marvin Humphrey <[email protected]>
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)
+}

Reply via email to