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)
+}