Beispiel #1
0
func goToInteger(value interface{}, nullable bool) unsafe.Pointer {
	switch v := value.(type) {
	case int:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uint:
		if uint64(v) > math.MaxInt64 {
			mess := fmt.Sprintf("uint value too large: %v", v)
			panic(NewErr(mess))
		}
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uintptr:
		if uint64(v) > math.MaxInt64 {
			mess := fmt.Sprintf("uintptr value too large: %v", v)
			panic(NewErr(mess))
		}
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uint64:
		if v > math.MaxInt64 {
			mess := fmt.Sprintf("uint64 value too large: %v", v)
			panic(NewErr(mess))
		}
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uint32:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uint16:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case uint8:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case int64:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case int32:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case int16:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case int8:
		return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
	case Obj:
		certifyCF(v, C.CFISH_INTEGER, nullable)
		return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
	}
	mess := fmt.Sprintf("Can't convert %T to clownfish.Integer", value)
	panic(NewErr(mess))
}
Beispiel #2
0
//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
}