1//GVariant : GVariant — strongly typed value datatype 2// https://developer.gnome.org/glib/2.26/glib-GVariant.html 3 4package glib 5 6// #include "gvariant.go.h" 7// #include "glib.go.h" 8import "C" 9 10import ( 11 "fmt" 12 "unsafe" 13) 14 15/* 16 * GVariant 17 */ 18 19// IVariant is an interface type implemented by Variant and all types which embed 20// an Variant. It is meant to be used as a type for function arguments which 21// require GVariants or any subclasses thereof. 22type IVariant interface { 23 ToGVariant() *C.GVariant 24 ToVariant() *Variant 25} 26 27// A Variant is a representation of GLib's GVariant. 28type Variant struct { 29 GVariant *C.GVariant 30} 31 32// ToGVariant exposes the underlying *C.GVariant type for this Variant, 33// necessary to implement IVariant. 34func (v *Variant) ToGVariant() *C.GVariant { 35 if v == nil { 36 return nil 37 } 38 return v.native() 39} 40 41// ToVariant returns this Variant, necessary to implement IVariant. 42func (v *Variant) ToVariant() *Variant { 43 return v 44} 45 46// newVariant creates a new Variant from a GVariant pointer. 47func newVariant(p *C.GVariant) *Variant { 48 return &Variant{GVariant: p} 49} 50 51// VariantFromUnsafePointer returns a Variant from an unsafe pointer. 52// XXX: unnecessary footgun? 53//func VariantFromUnsafePointer(p unsafe.Pointer) *Variant { 54// return &Variant{C.toGVariant(p)} 55//} 56 57// native returns a pointer to the underlying GVariant. 58func (v *Variant) native() *C.GVariant { 59 if v == nil || v.GVariant == nil { 60 return nil 61 } 62 return v.GVariant 63} 64 65// Native returns a pointer to the underlying GVariant. 66func (v *Variant) Native() uintptr { 67 return uintptr(unsafe.Pointer(v.native())) 68} 69 70// TypeString returns the g variant type string for this variant. 71func (v *Variant) TypeString() string { 72 // the string returned from this belongs to GVariant and must not be freed. 73 return C.GoString((*C.char)(C.g_variant_get_type_string(v.native()))) 74} 75 76// IsContainer returns true if the variant is a container and false otherwise. 77func (v *Variant) IsContainer() bool { 78 return gobool(C.g_variant_is_container(v.native())) 79} 80 81// IsFloating returns true if the variant has a floating reference count. 82// XXX: this isn't useful without ref_sink/take_ref, which are themselves 83// perhaps not useful for most Go code that may use variants. 84//func (v *Variant) IsFloating() bool { 85// return gobool(C.g_variant_is_floating(v.native())) 86//} 87 88// GetBoolean returns the bool value of this variant. 89func (v *Variant) GetBoolean() bool { 90 return gobool(C.g_variant_get_boolean(v.native())) 91} 92 93// GetString returns the string value of the variant. 94func (v *Variant) GetString() string { 95 var len C.gsize 96 gc := C.g_variant_get_string(v.native(), &len) 97 defer C.g_free(C.gpointer(gc)) 98 return C.GoStringN((*C.char)(gc), (C.int)(len)) 99} 100 101// GetStrv returns a slice of strings from this variant. It wraps 102// g_variant_get_strv, but returns copies of the strings instead. 103func (v *Variant) GetStrv() []string { 104 gstrv := C.g_variant_get_strv(v.native(), nil) 105 // we do not own the memory for these strings, so we must not use strfreev 106 // but we must free the actual pointer we receive. 107 c := gstrv 108 defer C.g_free(C.gpointer(gstrv)) 109 var strs []string 110 111 for *c != nil { 112 strs = append(strs, C.GoString((*C.char)(*c))) 113 c = C.next_gcharptr(c) 114 } 115 return strs 116} 117 118// GetInt returns the int64 value of the variant if it is an integer type, and 119// an error otherwise. It wraps variouns `g_variant_get_*` functions dealing 120// with integers of different sizes. 121func (v *Variant) GetInt() (int64, error) { 122 t := v.Type().String() 123 var i int64 124 switch t { 125 case "y": 126 i = int64(C.g_variant_get_byte(v.native())) 127 case "n": 128 i = int64(C.g_variant_get_int16(v.native())) 129 case "q": 130 i = int64(C.g_variant_get_uint16(v.native())) 131 case "i": 132 i = int64(C.g_variant_get_int32(v.native())) 133 case "u": 134 i = int64(C.g_variant_get_uint32(v.native())) 135 case "x": 136 i = int64(C.g_variant_get_int64(v.native())) 137 case "t": 138 i = int64(C.g_variant_get_uint64(v.native())) 139 default: 140 return 0, fmt.Errorf("variant type %s not an integer type", t) 141 } 142 return i, nil 143} 144 145// Type returns the VariantType for this variant. 146func (v *Variant) Type() *VariantType { 147 return newVariantType(C.g_variant_get_type(v.native())) 148} 149 150// IsType returns true if the variant's type matches t. 151func (v *Variant) IsType(t *VariantType) bool { 152 return gobool(C.g_variant_is_of_type(v.native(), t.native())) 153} 154 155// String wraps g_variant_print(). It returns a string understood 156// by g_variant_parse(). 157func (v *Variant) String() string { 158 gc := C.g_variant_print(v.native(), gbool(false)) 159 defer C.g_free(C.gpointer(gc)) 160 return C.GoString((*C.char)(gc)) 161} 162 163// AnnotatedString wraps g_variant_print(), but returns a type-annotated 164// string. 165func (v *Variant) AnnotatedString() string { 166 gc := C.g_variant_print(v.native(), gbool(true)) 167 defer C.g_free(C.gpointer(gc)) 168 return C.GoString((*C.char)(gc)) 169} 170 171//void g_variant_unref () 172//GVariant * g_variant_ref () 173//GVariant * g_variant_ref_sink () 174//GVariant * g_variant_take_ref () 175//gint g_variant_compare () 176//GVariantClass g_variant_classify () 177//gboolean g_variant_check_format_string () 178//void g_variant_get () 179//void g_variant_get_va () 180//GVariant * g_variant_new () 181//GVariant * g_variant_new_va () 182//GVariant * g_variant_new_boolean () 183//GVariant * g_variant_new_byte () 184//GVariant * g_variant_new_int16 () 185//GVariant * g_variant_new_uint16 () 186//GVariant * g_variant_new_int32 () 187//GVariant * g_variant_new_uint32 () 188//GVariant * g_variant_new_int64 () 189//GVariant * g_variant_new_uint64 () 190//GVariant * g_variant_new_handle () 191//GVariant * g_variant_new_double () 192//GVariant * g_variant_new_string () 193//GVariant * g_variant_new_take_string () 194//GVariant * g_variant_new_printf () 195//GVariant * g_variant_new_object_path () 196//gboolean g_variant_is_object_path () 197//GVariant * g_variant_new_signature () 198//gboolean g_variant_is_signature () 199//GVariant * g_variant_new_variant () 200//GVariant * g_variant_new_strv () 201//GVariant * g_variant_new_objv () 202//GVariant * g_variant_new_bytestring () 203//GVariant * g_variant_new_bytestring_array () 204//guchar g_variant_get_byte () 205//gint16 g_variant_get_int16 () 206//guint16 g_variant_get_uint16 () 207//gint32 g_variant_get_int32 () 208//guint32 g_variant_get_uint32 () 209//gint64 g_variant_get_int64 () 210//guint64 g_variant_get_uint64 () 211//gint32 g_variant_get_handle () 212//gdouble g_variant_get_double () 213//const gchar * g_variant_get_string () 214//gchar * g_variant_dup_string () 215//GVariant * g_variant_get_variant () 216//const gchar ** g_variant_get_strv () 217//gchar ** g_variant_dup_strv () 218//const gchar ** g_variant_get_objv () 219//gchar ** g_variant_dup_objv () 220//const gchar * g_variant_get_bytestring () 221//gchar * g_variant_dup_bytestring () 222//const gchar ** g_variant_get_bytestring_array () 223//gchar ** g_variant_dup_bytestring_array () 224//GVariant * g_variant_new_maybe () 225//GVariant * g_variant_new_array () 226//GVariant * g_variant_new_tuple () 227//GVariant * g_variant_new_dict_entry () 228//GVariant * g_variant_new_fixed_array () 229//GVariant * g_variant_get_maybe () 230//gsize g_variant_n_children () 231//GVariant * g_variant_get_child_value () 232//void g_variant_get_child () 233//GVariant * g_variant_lookup_value () 234//gboolean g_variant_lookup () 235//gconstpointer g_variant_get_fixed_array () 236//gsize g_variant_get_size () 237//gconstpointer g_variant_get_data () 238//GBytes * g_variant_get_data_as_bytes () 239//void g_variant_store () 240//GVariant * g_variant_new_from_data () 241//GVariant * g_variant_new_from_bytes () 242//GVariant * g_variant_byteswap () 243//GVariant * g_variant_get_normal_form () 244//gboolean g_variant_is_normal_form () 245//guint g_variant_hash () 246//gboolean g_variant_equal () 247//gchar * g_variant_print () 248//GString * g_variant_print_string () 249//GVariantIter * g_variant_iter_copy () 250//void g_variant_iter_free () 251//gsize g_variant_iter_init () 252//gsize g_variant_iter_n_children () 253//GVariantIter * g_variant_iter_new () 254//GVariant * g_variant_iter_next_value () 255//gboolean g_variant_iter_next () 256//gboolean g_variant_iter_loop () 257//void g_variant_builder_unref () 258//GVariantBuilder * g_variant_builder_ref () 259//GVariantBuilder * g_variant_builder_new () 260//void g_variant_builder_init () 261//void g_variant_builder_clear () 262//void g_variant_builder_add_value () 263//void g_variant_builder_add () 264//void g_variant_builder_add_parsed () 265//GVariant * g_variant_builder_end () 266//void g_variant_builder_open () 267//void g_variant_builder_close () 268//void g_variant_dict_unref () 269//GVariantDict * g_variant_dict_ref () 270//GVariantDict * g_variant_dict_new () 271//void g_variant_dict_init () 272//void g_variant_dict_clear () 273//gboolean g_variant_dict_contains () 274//gboolean g_variant_dict_lookup () 275//GVariant * g_variant_dict_lookup_value () 276//void g_variant_dict_insert () 277//void g_variant_dict_insert_value () 278//gboolean g_variant_dict_remove () 279//GVariant * g_variant_dict_end () 280//#define G_VARIANT_PARSE_ERROR 281//GVariant * g_variant_parse () 282//GVariant * g_variant_new_parsed_va () 283//GVariant * g_variant_new_parsed () 284//gchar * g_variant_parse_error_print_context () 285