func (v *Value) Get() interface{} { t := Type(v.g().g_type) switch t { case TYPE_INVALID: return nil case TYPE_STRING: return C.GoString((*C.char)(C.g_value_get_string(v.g()))) case TYPE_GO_INT: return int(C.g_value_get_long(v.g())) case TYPE_GO_UINT: return uint(C.g_value_get_ulong(v.g())) case TYPE_CHAR: return int8(C.g_value_get_schar(v.g())) case TYPE_UCHAR: return uint8(C.g_value_get_uchar(v.g())) case TYPE_GO_INT32: return int32(C.g_value_get_int(v.g())) case TYPE_GO_UINT32: return uint32(C.g_value_get_uint(v.g())) case TYPE_INT64: return int64(C.g_value_get_int64(v.g())) case TYPE_UINT64: return uint64(C.g_value_get_uint64(v.g())) case TYPE_BOOLEAN: return (C.g_value_get_boolean(v.g()) != C.gboolean(0)) case TYPE_FLOAT: return float32(C.g_value_get_float(v.g())) case TYPE_DOUBLE: return float64(C.g_value_get_double(v.g())) case TYPE_POINTER: return Pointer(C.g_value_get_pointer(v.g())) case TYPE_GTYPE: return Type(C.g_value_get_gtype(v.g())) } if t.IsA(TYPE_OBJECT) { o := new(Object) o.SetPtr(Pointer(C.g_value_get_object(v.g()))) return o } if C.g_value_fits_pointer(v.g()) != 0 { return Pointer(C.g_value_peek_pointer(v.g())) } // Value of unknown type is returned as is return v }
func fromGValue(v *C.GValue) (ret interface{}) { valueType := C.gvalue_get_type(v) fundamentalType := C.gtype_get_fundamental(valueType) switch fundamentalType { case C.G_TYPE_OBJECT: ret = unsafe.Pointer(C.g_value_get_object(v)) case C.G_TYPE_STRING: ret = fromGStr(C.g_value_get_string(v)) case C.G_TYPE_UINT: ret = int(C.g_value_get_uint(v)) case C.G_TYPE_BOXED: ret = unsafe.Pointer(C.g_value_get_boxed(v)) case C.G_TYPE_BOOLEAN: ret = C.g_value_get_boolean(v) == C.gboolean(1) default: fmt.Printf("from type %s %T\n", fromGStr(C.g_type_name(fundamentalType)), v) panic("FIXME") //TODO } return }
// GoValue() converts a Value to comparable Go type. GoValue() // returns a non-nil error if the conversion was unsuccessful. The // returned interface{} must be type asserted as the actual Go // representation of the Value. // // This function is a wrapper around the many g_value_get_*() // functions, depending on the type of the Value. func (v *Value) GoValue() (interface{}, error) { switch v.GetType() { case TYPE_INVALID: return nil, errors.New("Invalid type") case TYPE_NONE: return nil, nil case TYPE_BOOLEAN: c := C.g_value_get_boolean(v.Native()) return gobool(c), nil case TYPE_CHAR: c := C.g_value_get_schar(v.Native()) return int8(c), nil case TYPE_UCHAR: c := C.g_value_get_uchar(v.Native()) return uint8(c), nil case TYPE_INT64: c := C.g_value_get_int64(v.Native()) return int64(c), nil case TYPE_INT: c := C.g_value_get_int(v.Native()) return int(c), nil case TYPE_UINT64: c := C.g_value_get_uint64(v.Native()) return uint64(c), nil case TYPE_UINT: c := C.g_value_get_uint(v.Native()) return uint(c), nil case TYPE_FLOAT: c := C.g_value_get_float(v.Native()) return float32(c), nil case TYPE_DOUBLE: c := C.g_value_get_double(v.Native()) return float64(c), nil case TYPE_STRING: c := C.g_value_get_string(v.Native()) return C.GoString((*C.char)(c)), nil default: return nil, errors.New("Type conversion not supported") } }
func marshalUint(p uintptr) (interface{}, error) { c := C.g_value_get_uint((*C.GValue)(unsafe.Pointer(p))) return uint(c), nil }
// GoValue() converts a Value to comparable Go type. GoValue() // returns a non-nil error if the conversion was unsuccessful. The // returned interface{} must be type asserted as the actual Go // representation of the Value. // // This function is a wrapper around the many g_value_get_*() // functions, depending on the type of the Value. func (v *Value) GoValue() (interface{}, error) { _, fundamental, err := v.Type() if err != nil { return nil, err } // TODO: verify that all of these cases are indeed fundamental types switch fundamental { case TYPE_INVALID: return nil, errors.New("invalid type") case TYPE_NONE: return nil, nil case TYPE_INTERFACE: return nil, errors.New("interface conversion not yet implemented") case TYPE_CHAR: c := C.g_value_get_schar(v.Native()) return int8(c), nil case TYPE_UCHAR: c := C.g_value_get_uchar(v.Native()) return uint8(c), nil case TYPE_BOOLEAN: c := C.g_value_get_boolean(v.Native()) return gobool(c), nil // TODO: TYPE_INT should probably be a Go int32. case TYPE_INT, TYPE_LONG, TYPE_ENUM: c := C.g_value_get_int(v.Native()) return int(c), nil case TYPE_INT64: c := C.g_value_get_int64(v.Native()) return int64(c), nil // TODO: TYPE_UINT should probably be a Go uint32. case TYPE_UINT, TYPE_ULONG, TYPE_FLAGS: c := C.g_value_get_uint(v.Native()) return uint(c), nil case TYPE_UINT64: c := C.g_value_get_uint64(v.Native()) return uint64(c), nil case TYPE_FLOAT: c := C.g_value_get_float(v.Native()) return float32(c), nil case TYPE_DOUBLE: c := C.g_value_get_double(v.Native()) return float64(c), nil case TYPE_STRING: c := C.g_value_get_string(v.Native()) return C.GoString((*C.char)(c)), nil case TYPE_POINTER: c := C.g_value_get_pointer(v.Native()) return unsafe.Pointer(c), nil case TYPE_OBJECT: c := C.g_value_get_object(v.Native()) // TODO: need to try and return an actual pointer to the correct object type // this may require an additional cast()-like method for each module return ObjectNew(unsafe.Pointer(c)), nil case TYPE_VARIANT: return nil, errors.New("variant conversion not yet implemented") default: return nil, errors.New("type conversion not supported") } }
func (self GValue) GetPtr() unsafe.Pointer { switch self.gtype { case G_TYPE_STRING: return unsafe.Pointer(C.g_value_get_string(self.value)) case G_TYPE_BOOLEAN: b := C.g_value_get_boolean(self.value) return unsafe.Pointer(&b) case G_TYPE_CHAR: c := C.g_value_get_char(self.value) return unsafe.Pointer(&c) case G_TYPE_INT: i := C.g_value_get_int(self.value) return unsafe.Pointer(&i) case G_TYPE_LONG: l := C.g_value_get_long(self.value) return unsafe.Pointer(&l) case G_TYPE_INT64: i := C.g_value_get_int64(self.value) return unsafe.Pointer(&i) case G_TYPE_UCHAR: c := C.g_value_get_uchar(self.value) return unsafe.Pointer(&c) case G_TYPE_UINT: i := C.g_value_get_uint(self.value) return unsafe.Pointer(&i) case G_TYPE_ULONG: l := C.g_value_get_ulong(self.value) return unsafe.Pointer(&l) case G_TYPE_UINT64: i := C.g_value_get_uint64(self.value) return unsafe.Pointer(&i) case G_TYPE_FLOAT: f := C.g_value_get_float(self.value) return unsafe.Pointer(&f) case G_TYPE_DOUBLE: d := C.g_value_get_double(self.value) return unsafe.Pointer(&d) } // Now things get tricky // We know the type, but how is it stored? // Is it pointer? isIt := C.pointer_in_gvalue(self.value) if GoBool(unsafe.Pointer(&isIt)) { val := C.g_value_get_pointer(self.value) return unsafe.Pointer(val) } // Is it object? isIt = C.object_in_gvalue(self.value) if GoBool(unsafe.Pointer(&isIt)) { o := C.g_value_get_object(self.value) return unsafe.Pointer(o) } //Hmmm.... ptr := C.g_value_peek_pointer(self.value) if ptr != nil { return unsafe.Pointer(ptr) } return nil }