Пример #1
0
func goToHash(value interface{}, nullable bool) unsafe.Pointer {
	switch v := value.(type) {
	case map[string]interface{}:
		if v == nil {
			if nullable {
				return nil
			}
		} else {
			size := len(v)
			hash := C.cfish_Hash_new(C.size_t(size))
			for key, val := range v {
				newVal := GoToClownfish(val, nil, true)
				keySize := len(key)
				keyStr := C.CString(key)
				cfKey := C.cfish_Str_new_steal_utf8(keyStr, C.size_t(keySize))
				defer C.cfish_dec_refcount(unsafe.Pointer(cfKey))
				C.CFISH_Hash_Store(hash, cfKey, (*C.cfish_Obj)(newVal))
			}
			return unsafe.Pointer(hash)
		}
	case Obj:
		certifyCF(v, C.CFISH_HASH, nullable)
		return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
	}
	mess := fmt.Sprintf("Can't convert %T to clownfish.Hash", value)
	panic(NewErr(mess))
}
Пример #2
0
func goToString(value interface{}, nullable bool) unsafe.Pointer {
	switch v := value.(type) {
	case string:
		size := len(v)
		str := C.CString(v)
		return unsafe.Pointer(C.cfish_Str_new_steal_utf8(str, C.size_t(size)))
	case Obj:
		certifyCF(v, C.CFISH_STRING, nullable)
		return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
	}
	mess := fmt.Sprintf("Can't convert %T to clownfish.String", value)
	panic(NewErr(mess))
}
Пример #3
0
// Turn a slice of Go strings into a Vector of Clownfish Strings.
func stringSliceToVec(strings []string) *C.cfish_Vector {
	if strings == nil {
		return nil
	}
	size := len(strings)
	vec := C.cfish_Vec_new(C.size_t(size))
	for i := 0; i < size; i++ {
		str := C.CString(strings[i])
		length := C.size_t(len(strings[i]))
		cfStr := C.cfish_Str_new_steal_utf8(str, length)
		C.CFISH_Vec_Push(vec, (*C.cfish_Obj)(unsafe.Pointer(cfStr)))
	}
	return vec
}
Пример #4
0
func NewString(goString string) String {
	str := C.CString(goString)
	len := C.size_t(len(goString))
	cfObj := C.cfish_Str_new_steal_utf8(str, len)
	return WRAPString(unsafe.Pointer(cfObj))
}
Пример #5
0
Файл: lucy.go Проект: kidaa/lucy
//export GOLUCY_DefDocReader_Fetch_Doc
func GOLUCY_DefDocReader_Fetch_Doc(ddr *C.lucy_DefaultDocReader,
	docID C.int32_t) *C.lucy_HitDoc {
	ivars := C.lucy_DefDocReader_IVARS(ddr)
	schema := ivars.schema
	datInstream := ivars.dat_in
	ixInstream := ivars.ix_in
	fields := C.cfish_Hash_new(1)
	fieldNameCap := C.size_t(31)
	var fieldName *C.char = ((*C.char)(C.malloc(fieldNameCap + 1)))

	// Get data file pointer from index, read number of fields.
	C.LUCY_InStream_Seek(ixInstream, C.int64_t(docID*8))
	start := C.LUCY_InStream_Read_U64(ixInstream)
	C.LUCY_InStream_Seek(datInstream, C.int64_t(start))
	numFields := uint32(C.LUCY_InStream_Read_C32(datInstream))

	// Decode stored data and build up the doc field by field.
	for i := uint32(0); i < numFields; i++ {
		// Read field name.
		fieldNameLen := C.size_t(C.LUCY_InStream_Read_C32(datInstream))
		if fieldNameLen > fieldNameCap {
			fieldNameCap = fieldNameLen
			fieldName = ((*C.char)(C.realloc(unsafe.Pointer(fieldName), fieldNameCap+1)))
		}
		C.LUCY_InStream_Read_Bytes(datInstream, fieldName, fieldNameLen)

		// Find the Field's FieldType.
		// TODO: Creating and destroying a new string each time is
		// inefficient.  The solution should be to add a privte
		// Schema_Fetch_Type_Utf8 method which takes char* and size_t.
		fieldNameStr := C.cfish_Str_new_from_utf8(fieldName, fieldNameLen)
		fieldType := C.LUCY_Schema_Fetch_Type(schema, fieldNameStr)
		C.cfish_dec_refcount(unsafe.Pointer(fieldNameStr))

		// Read the field value.
		var value *C.cfish_Obj
		switch C.LUCY_FType_Primitive_ID(fieldType) & C.lucy_FType_PRIMITIVE_ID_MASK {
		case C.lucy_FType_TEXT:
			valueLen := C.size_t(C.LUCY_InStream_Read_C32(datInstream))
			buf := ((*C.char)(C.malloc(valueLen + 1)))
			C.LUCY_InStream_Read_Bytes(datInstream, buf, valueLen)
			C.null_terminate_string(buf, valueLen)
			value = ((*C.cfish_Obj)(C.cfish_Str_new_steal_utf8(buf, valueLen)))
		case C.lucy_FType_BLOB:
			valueLen := C.size_t(C.LUCY_InStream_Read_C32(datInstream))
			buf := ((*C.char)(C.malloc(valueLen)))
			C.LUCY_InStream_Read_Bytes(datInstream, buf, valueLen)
			value = ((*C.cfish_Obj)(C.cfish_Blob_new_steal(buf, valueLen)))
		case C.lucy_FType_FLOAT32:
			value = ((*C.cfish_Obj)(C.cfish_Float_new(C.double(C.LUCY_InStream_Read_F32(datInstream)))))
		case C.lucy_FType_FLOAT64:
			value = ((*C.cfish_Obj)(C.cfish_Float_new(C.LUCY_InStream_Read_F64(datInstream))))
		case C.lucy_FType_INT32:
			value = ((*C.cfish_Obj)(C.cfish_Int_new(C.int64_t(C.LUCY_InStream_Read_C32(datInstream)))))
		case C.lucy_FType_INT64:
			value = ((*C.cfish_Obj)(C.cfish_Int_new(C.int64_t(C.LUCY_InStream_Read_C64(datInstream)))))
		default:
			value = nil
			panic(clownfish.NewErr("Internal Lucy error: bad type id for field " +
				C.GoStringN(fieldName, C.int(fieldNameLen))))
		}

		// Store the value.
		C.CFISH_Hash_Store_Utf8(fields, fieldName, fieldNameLen, value)
	}
	C.free(unsafe.Pointer(fieldName))

	retval := C.lucy_HitDoc_new(unsafe.Pointer(fields), docID, 0.0)
	C.cfish_dec_refcount(unsafe.Pointer(fields))
	return retval
}