Exemplo n.º 1
0
func newAttributeListFromC(C_attrs *C.struct_hyperclient_attribute, C_attrs_sz C.size_t) (attrs Attributes, err error) {
	attrs = Attributes{}
	for i := 0; i < int(C_attrs_sz); i++ {
		C_attr := C.GetAttribute(C_attrs, C.int(i))
		attr := C.GoString(C_attr.attr)
		switch C_attr.datatype {
		case datatype_STRING:
			attrs[attr] = C.GoStringN(C_attr.value, C.int(C_attr.value_sz))
		case datatype_INT64:
			var value int64
			buf := bytes.NewBuffer(C.GoBytes(unsafe.Pointer(C_attr.value), C.int(C_attr.value_sz)))
			err := binary.Read(buf, binary.LittleEndian, &value)
			if err != nil {
				return nil, fmt.Errorf("Could not decode INT64 attribute `%s` (#%d)", attr, i)
			}
			attrs[attr] = value
		case datatype_GARBAGE:
			continue
		default:
			return nil, fmt.Errorf("Unknown datatype %d found for attribute `%s` (#%d)", C_attr.datatype, attr, i)
		}
	}
	return attrs, nil
}
Exemplo n.º 2
0
func (client *Client) newAttributeListFromC(C_attrs *C.struct_hyperdex_client_attribute, C_attrs_sz C.size_t) (attrs Attributes, err error) {
	attrs = Attributes{}
	for i := 0; i < int(C_attrs_sz); i++ {
		C_attr := C.GetAttribute(C_attrs, C.int(i))
		if C_attr.value_sz == 0 {
			// If value_sz is 0, the attribute has not been set.
			// So we skip it.
			continue
		}

		attr := C.GoString(C_attr.attr)
		var C_iter C.struct_hyperdex_ds_iterator

		switch C_attr.datatype {
		case C.HYPERDATATYPE_STRING:
			attrs[attr] = C.GoStringN(C_attr.value, C.int(C_attr.value_sz))

		case C.HYPERDATATYPE_INT64:
			var C_int C.int64_t
			status := C.hyperdex_ds_unpack_int(C_attr.value, C_attr.value_sz, &C_int)
			if status == -1 {
				return nil, fmt.Errorf("The size of int is not exactly 8B")
			}
			attrs[attr] = int64(C_int)

		case C.HYPERDATATYPE_FLOAT:
			var C_double C.double
			status := C.hyperdex_ds_unpack_float(C_attr.value, C_attr.value_sz, &C_double)
			if status == -1 {
				return nil, fmt.Errorf("The size of float is not exactly 8B")
			}
			attrs[attr] = float64(C_double)

		case C.HYPERDATATYPE_LIST_STRING:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_LIST_STRING,
				C_attr.value, C_attr.value_sz)
			lst := make(ListStr, 0)

			for {
				var C_string *C.char
				var C_size_t C.size_t
				status := C.hyperdex_ds_iterate_list_string_next(&C_iter,
					&C_string, &C_size_t)
				if status > 0 {
					lst = append(lst, C.GoStringN(C_string, C.int(C_size_t)))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted list of strings")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_LIST_INT64:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_LIST_INT64,
				C_attr.value, C_attr.value_sz)
			lst := make(ListI64, 0)

			for {
				var num C.int64_t
				status := C.hyperdex_ds_iterate_list_int_next(&C_iter, &num)
				if status > 0 {
					lst = append(lst, int64(num))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted list of integers")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_LIST_FLOAT:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_LIST_FLOAT,
				C_attr.value, C_attr.value_sz)
			lst := make(ListF64, 0)

			for {
				var num C.double
				status := C.hyperdex_ds_iterate_list_float_next(&C_iter, &num)
				if status > 0 {
					lst = append(lst, float64(num))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted list of floats")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_SET_STRING:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_SET_STRING,
				C_attr.value, C_attr.value_sz)
			lst := make(SetStr, 0)

			for {
				var C_string *C.char
				var C_size_t C.size_t
				status := C.hyperdex_ds_iterate_set_string_next(&C_iter,
					&C_string, &C_size_t)
				if status > 0 {
					lst = append(lst, C.GoStringN(C_string, C.int(C_size_t)))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted set of strings")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_SET_INT64:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_SET_INT64,
				C_attr.value, C_attr.value_sz)
			lst := make(SetI64, 0)

			for {
				var num C.int64_t
				status := C.hyperdex_ds_iterate_set_int_next(&C_iter, &num)
				if status > 0 {
					lst = append(lst, int64(num))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted set of integers")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_SET_FLOAT:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_SET_FLOAT,
				C_attr.value, C_attr.value_sz)
			lst := make(SetF64, 0)

			for {
				var num C.double
				status := C.hyperdex_ds_iterate_set_float_next(&C_iter, &num)
				if status > 0 {
					lst = append(lst, float64(num))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted set of floats")
				} else {
					break
				}
			}

			attrs[attr] = lst

		case C.HYPERDATATYPE_MAP_STRING_STRING:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_STRING_STRING,
				C_attr.value, C_attr.value_sz)
			m := make(MapStrStr)

			for {
				var C_key_string *C.char
				var C_key_size_t C.size_t
				var C_value_string *C.char
				var C_value_size_t C.size_t

				status := C.hyperdex_ds_iterate_map_string_string_next(&C_iter,
					&C_key_string, &C_key_size_t, &C_value_string, &C_value_size_t)
				if status > 0 {
					m[C.GoStringN(C_key_string, C.int(C_key_size_t))] = C.GoStringN(C_value_string, C.int(C_value_size_t))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of strings to strings")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_STRING_INT64:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_STRING_INT64,
				C_attr.value, C_attr.value_sz)
			m := make(MapStrI64)

			for {
				var C_key_string *C.char
				var C_key_size_t C.size_t
				var C_value C.int64_t

				status := C.hyperdex_ds_iterate_map_string_int_next(&C_iter,
					&C_key_string, &C_key_size_t, &C_value)
				if status > 0 {
					m[C.GoStringN(C_key_string, C.int(C_key_size_t))] = int64(C_value)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of strings to integers")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_STRING_FLOAT:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_STRING_FLOAT,
				C_attr.value, C_attr.value_sz)
			m := make(MapStrF64)

			for {
				var C_key_string *C.char
				var C_key_size_t C.size_t
				var C_value C.double

				status := C.hyperdex_ds_iterate_map_string_float_next(&C_iter,
					&C_key_string, &C_key_size_t, &C_value)
				if status > 0 {
					m[C.GoStringN(C_key_string, C.int(C_key_size_t))] = float64(C_value)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of strings to floats")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_INT64_STRING:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_INT64_STRING,
				C_attr.value, C_attr.value_sz)
			m := make(MapI64Str)

			for {
				var C_key C.int64_t
				var C_val_string *C.char
				var C_val_size_t C.size_t

				status := C.hyperdex_ds_iterate_map_int_string_next(&C_iter,
					&C_key, &C_val_string, &C_val_size_t)
				if status > 0 {
					m[int64(C_key)] = C.GoStringN(C_val_string, C.int(C_val_size_t))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of integers to strings")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_INT64_INT64:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_INT64_INT64,
				C_attr.value, C_attr.value_sz)
			m := make(MapI64I64)

			for {
				var C_key C.int64_t
				var C_val C.int64_t

				status := C.hyperdex_ds_iterate_map_int_int_next(&C_iter,
					&C_key, &C_val)
				if status > 0 {
					m[int64(C_key)] = int64(C_val)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of integers to integers")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_INT64_FLOAT:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_INT64_FLOAT,
				C_attr.value, C_attr.value_sz)
			m := make(MapI64F64)

			for {
				var C_key C.int64_t
				var C_val C.double

				status := C.hyperdex_ds_iterate_map_int_float_next(&C_iter,
					&C_key, &C_val)
				if status > 0 {
					m[int64(C_key)] = float64(C_val)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of integers to floats")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_FLOAT_STRING:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_FLOAT_STRING,
				C_attr.value, C_attr.value_sz)
			m := make(MapF64Str)

			for {
				var C_key C.double
				var C_val_string *C.char
				var C_val_size_t C.size_t

				status := C.hyperdex_ds_iterate_map_float_string_next(&C_iter,
					&C_key, &C_val_string, &C_val_size_t)
				if status > 0 {
					m[float64(C_key)] = C.GoStringN(C_val_string, C.int(C_val_size_t))
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of floats to strings")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_FLOAT_INT64:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_FLOAT_INT64,
				C_attr.value, C_attr.value_sz)
			m := make(MapF64I64)

			for {
				var C_key C.double
				var C_val C.int64_t

				status := C.hyperdex_ds_iterate_map_float_int_next(&C_iter,
					&C_key, &C_val)
				if status > 0 {
					m[float64(C_key)] = int64(C_val)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of floats to integers")
				} else {
					break
				}
			}

			attrs[attr] = m

		case C.HYPERDATATYPE_MAP_FLOAT_FLOAT:
			C.hyperdex_ds_iterator_init(&C_iter, C.HYPERDATATYPE_MAP_FLOAT_FLOAT,
				C_attr.value, C_attr.value_sz)
			m := make(MapF64F64)

			for {
				var C_key C.double
				var C_val C.double

				status := C.hyperdex_ds_iterate_map_float_float_next(&C_iter,
					&C_key, &C_val)
				if status > 0 {
					m[float64(C_key)] = float64(C_val)
				} else if status < 0 {
					return nil, fmt.Errorf("Corrupted map of floats to floats")
				} else {
					break
				}
			}

			attrs[attr] = m

		default:
			return nil, fmt.Errorf("Unknown datatype %d found for attribute `%s` (#%d)", C_attr.datatype, attr, i)
		}
	}
	return attrs, nil
}