1package glib 2 3// #include <glib.h> 4// #include <glib-object.h> 5// #include "glib.go.h" 6import "C" 7import "unsafe" 8 9// SList is a representation of Glib's GSList. A SList must be manually freed 10// by either calling Free() or FreeFull() 11type SList struct { 12 list *C.struct__GSList 13 // If set, dataWrap is called every time Data() 14 // is called to wrap raw underlying 15 // value into appropriate type. 16 dataWrap func(unsafe.Pointer) interface{} 17} 18 19func WrapSList(obj uintptr) *SList { 20 return wrapSList((*C.struct__GSList)(unsafe.Pointer(obj))) 21} 22 23func wrapSList(obj *C.struct__GSList) *SList { 24 if obj == nil { 25 return nil 26 } 27 28 //NOTE a list should be freed by calling either 29 //g_slist_free() or g_slist_free_full(). However, it's not possible to use a 30 //finalizer for this. 31 return &SList{list: obj} 32} 33 34func (v *SList) wrapNewHead(obj *C.struct__GSList) *SList { 35 if obj == nil { 36 return nil 37 } 38 return &SList{ 39 list: obj, 40 dataWrap: v.dataWrap, 41 } 42} 43 44func (v *SList) Native() uintptr { 45 return uintptr(unsafe.Pointer(v.list)) 46} 47 48func (v *SList) native() *C.struct__GSList { 49 if v == nil || v.list == nil { 50 return nil 51 } 52 return v.list 53} 54 55// DataWapper sets wrap functions, which is called during NthData() 56// and Data(). It's used to cast raw C data into appropriate 57// Go structures and types every time that data is retreived. 58func (v *SList) DataWrapper(fn func(unsafe.Pointer) interface{}) { 59 if v == nil { 60 return 61 } 62 v.dataWrap = fn 63} 64 65func (v *SList) Append(data uintptr) *SList { 66 ret := C.g_slist_append(v.native(), C.gpointer(data)) 67 if ret == v.native() { 68 return v 69 } 70 71 return wrapSList(ret) 72} 73 74// Length is a wrapper around g_slist_length(). 75func (v *SList) Length() uint { 76 return uint(C.g_slist_length(v.native())) 77} 78 79// Next is a wrapper around the next struct field 80func (v *SList) Next() *SList { 81 n := v.native() 82 if n == nil { 83 return nil 84 } 85 86 return wrapSList(n.next) 87} 88 89// dataRaw is a wrapper around the data struct field 90func (v *SList) dataRaw() unsafe.Pointer { 91 n := v.native() 92 if n == nil { 93 return nil 94 } 95 return unsafe.Pointer(n.data) 96} 97 98// DataRaw is a wrapper around the data struct field 99func (v *SList) DataRaw() unsafe.Pointer { 100 n := v.native() 101 if n == nil { 102 return nil 103 } 104 return unsafe.Pointer(n.data) 105} 106 107// Data acts the same as data struct field, but it returns raw unsafe.Pointer as interface. 108// TODO: Align with List struct and add member + logic for `dataWrap func(unsafe.Pointer) interface{}`? 109func (v *SList) Data() interface{} { 110 ptr := v.dataRaw() 111 if v.dataWrap != nil { 112 return v.dataWrap(ptr) 113 } 114 return ptr 115} 116 117// Foreach acts the same as g_slist_foreach(). 118// No user_data argument is implemented because of Go clojure capabilities. 119func (v *SList) Foreach(fn func(item interface{})) { 120 for l := v; l != nil; l = l.Next() { 121 fn(l.Data()) 122 } 123} 124 125// Free is a wrapper around g_slist_free(). 126func (v *SList) Free() { 127 C.g_slist_free(v.native()) 128} 129 130// FreeFull is a wrapper around g_slist_free_full(). 131func (v *SList) FreeFull() { 132 //TODO implement GDestroyNotify callback 133 C.g_slist_free_full(v.native(), nil) 134} 135 136// GSList * g_slist_alloc () 137// GSList * g_slist_prepend () 138// GSList * g_slist_insert () 139// GSList * g_slist_insert_before () 140// GSList * g_slist_insert_sorted () 141// GSList * g_slist_remove () 142// GSList * g_slist_remove_link () 143// GSList * g_slist_delete_link () 144// GSList * g_slist_remove_all () 145// void g_slist_free_1 () 146// GSList * g_slist_copy () 147// GSList * g_slist_copy_deep () 148// GSList * g_slist_reverse () 149// GSList * g_slist_insert_sorted_with_data () 150// GSList * g_slist_sort () 151// GSList * g_slist_sort_with_data () 152// GSList * g_slist_concat () 153// GSList * g_slist_last () 154// GSList * g_slist_nth () 155// gpointer g_slist_nth_data () 156// GSList * g_slist_find () 157// GSList * g_slist_find_custom () 158// gint g_slist_position () 159// gint g_slist_index () 160