func ToGo(ptr unsafe.Pointer) interface{} { if ptr == nil { return nil } class := C.cfish_Obj_get_class((*C.cfish_Obj)(ptr)) if class == C.CFISH_STRING { return CFStringToGo(ptr) } else if class == C.CFISH_BLOB { return BlobToGo(ptr) } else if class == C.CFISH_VECTOR { return VectorToGo(ptr) } else if class == C.CFISH_HASH { return HashToGo(ptr) } else if class == C.CFISH_BOOLEAN { if ptr == unsafe.Pointer(C.CFISH_TRUE) { return true } else { return false } } else if class == C.CFISH_INTEGER { val := C.CFISH_Int_Get_Value((*C.cfish_Integer)(ptr)) return int64(val) } else if class == C.CFISH_FLOAT { val := C.CFISH_Float_Get_Value((*C.cfish_Float)(ptr)) return float64(val) } else { // Don't convert to a native Go type, but wrap in a Go struct. return WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(ptr)))) } }
func WRAPAny(ptr unsafe.Pointer) Obj { if ptr == nil { return nil } class := C.cfish_Obj_get_class((*C.cfish_Obj)(ptr)) wrapFunc := (*wrapReg)[unsafe.Pointer(class)] if wrapFunc == nil { className := CFStringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name((*C.cfish_Class)(class)))) panic(fmt.Sprintf("Failed to find WRAP function for %s", className)) } return wrapFunc(ptr) }
func BlobToGo(ptr unsafe.Pointer) []byte { blob := (*C.cfish_Blob)(ptr) if blob == nil { return nil } class := C.cfish_Obj_get_class((*C.cfish_Obj)(ptr)) if class != C.CFISH_BLOB { mess := "Not a Blob: " + StringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name(class))) panic(NewErr(mess)) } data := C.CFISH_Blob_Get_Buf(blob) size := C.CFISH_Blob_Get_Size(blob) if size > C.size_t(C.INT_MAX) { panic(fmt.Sprintf("Overflow: %d > %d", size, C.INT_MAX)) } return C.GoBytes(unsafe.Pointer(data), C.int(size)) }
// Read data into the supplied doc. func (s *SearcherIMP) ReadDoc(docID int32, doc interface{}) error { self := (*C.lucy_Searcher)(clownfish.Unwrap(s, "s")) class := C.cfish_Obj_get_class((*C.cfish_Obj)(unsafe.Pointer(self))) if class == C.LUCY_INDEXSEARCHER { ixReader := C.LUCY_IxSearcher_Get_Reader((*C.lucy_IndexSearcher)(unsafe.Pointer(self))) cfStr := (*C.cfish_String)(clownfish.GoToClownfish("Lucy::Index::DocReader", unsafe.Pointer(C.CFISH_STRING), false)) defer C.cfish_decref(unsafe.Pointer(cfStr)) docReader := C.LUCY_IxReader_Fetch(ixReader, cfStr) if docReader == nil { return clownfish.NewErr("No DocReader available") } docReaderGo := clownfish.WRAPAny(unsafe.Pointer(C.cfish_incref(unsafe.Pointer(docReader)))).(DocReader) return docReaderGo.ReadDoc(docID, doc) } else { return clownfish.NewErr("Support for ReadDoc not implemented") } }
func VectorToGo(ptr unsafe.Pointer) []interface{} { vec := (*C.cfish_Vector)(ptr) if vec == nil { return nil } class := C.cfish_Obj_get_class((*C.cfish_Obj)(ptr)) if class != C.CFISH_VECTOR { mess := "Not a Vector: " + StringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name(class))) panic(NewErr(mess)) } size := C.CFISH_Vec_Get_Size(vec) if size > C.size_t(maxInt) { panic(fmt.Sprintf("Overflow: %d > %d", size, maxInt)) } slice := make([]interface{}, int(size)) for i := 0; i < int(size); i++ { slice[i] = ToGo(unsafe.Pointer(C.CFISH_Vec_Fetch(vec, C.size_t(i)))) } return slice }
func HashToGo(ptr unsafe.Pointer) map[string]interface{} { hash := (*C.cfish_Hash)(ptr) if hash == nil { return nil } class := C.cfish_Obj_get_class((*C.cfish_Obj)(ptr)) if class != C.CFISH_HASH { mess := "Not a Hash: " + StringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name(class))) panic(NewErr(mess)) } size := C.CFISH_Hash_Get_Size(hash) m := make(map[string]interface{}, int(size)) iter := C.cfish_HashIter_new(hash) defer C.cfish_dec_refcount(unsafe.Pointer(iter)) for C.CFISH_HashIter_Next(iter) { key := C.CFISH_HashIter_Get_Key(iter) val := C.CFISH_HashIter_Get_Value(iter) m[StringToGo(unsafe.Pointer(key))] = ToGo(unsafe.Pointer(val)) } return m }
func GetClass(o Obj) Class { objCF := (*C.cfish_Obj)(Unwrap(o, "o")) classCF := C.cfish_Obj_get_class(objCF) return WRAPClass(unsafe.Pointer(classCF)) }