1package glib 2 3// #include <glib.h> 4// #include <glib-object.h> 5// #include "glib.go.h" 6import "C" 7import ( 8 "unsafe" 9) 10 11/* 12 * Linked Lists 13 */ 14 15// List is a representation of Glib's GList. 16type List struct { 17 list *C.struct__GList 18 // If set, dataWrap is called every time NthData() 19 // or Data() is called to wrap raw underlying 20 // value into appropriate type. 21 dataWrap func(unsafe.Pointer) interface{} 22} 23 24func WrapList(obj uintptr) *List { 25 return wrapList((*C.struct__GList)(unsafe.Pointer(obj))) 26} 27 28func wrapList(obj *C.struct__GList) *List { 29 if obj == nil { 30 return nil 31 } 32 return &List{list: obj} 33} 34 35func (v *List) wrapNewHead(obj *C.struct__GList) *List { 36 if obj == nil { 37 return nil 38 } 39 return &List{ 40 list: obj, 41 dataWrap: v.dataWrap, 42 } 43} 44 45func (v *List) Native() uintptr { 46 return uintptr(unsafe.Pointer(v.list)) 47} 48 49func (v *List) native() *C.struct__GList { 50 if v == nil || v.list == nil { 51 return nil 52 } 53 return v.list 54} 55 56// DataWapper sets wrap functions, which is called during NthData() 57// and Data(). It's used to cast raw C data into appropriate 58// Go structures and types every time that data is retreived. 59func (v *List) DataWrapper(fn func(unsafe.Pointer) interface{}) { 60 if v == nil { 61 return 62 } 63 v.dataWrap = fn 64} 65 66// Append is a wrapper around g_list_append(). 67func (v *List) Append(data uintptr) *List { 68 glist := C.g_list_append(v.native(), C.gpointer(data)) 69 return v.wrapNewHead(glist) 70} 71 72// Prepend is a wrapper around g_list_prepend(). 73func (v *List) Prepend(data uintptr) *List { 74 glist := C.g_list_prepend(v.native(), C.gpointer(data)) 75 return v.wrapNewHead(glist) 76} 77 78// Insert is a wrapper around g_list_insert(). 79func (v *List) Insert(data uintptr, position int) *List { 80 glist := C.g_list_insert(v.native(), C.gpointer(data), C.gint(position)) 81 return v.wrapNewHead(glist) 82} 83 84// Length is a wrapper around g_list_length(). 85func (v *List) Length() uint { 86 return uint(C.g_list_length(v.native())) 87} 88 89// nthDataRaw is a wrapper around g_list_nth_data(). 90func (v *List) nthDataRaw(n uint) unsafe.Pointer { 91 return unsafe.Pointer(C.g_list_nth_data(v.native(), C.guint(n))) 92} 93 94// Nth() is a wrapper around g_list_nth(). 95func (v *List) Nth(n uint) *List { 96 list := wrapList(C.g_list_nth(v.native(), C.guint(n))) 97 list.DataWrapper(v.dataWrap) 98 return list 99} 100 101// NthData acts the same as g_list_nth_data(), but passes 102// retrieved value before returning through wrap function, set by DataWrapper(). 103// If no wrap function is set, it returns raw unsafe.Pointer. 104func (v *List) NthData(n uint) interface{} { 105 ptr := v.nthDataRaw(n) 106 if v.dataWrap != nil { 107 return v.dataWrap(ptr) 108 } 109 return ptr 110} 111 112// Free is a wrapper around g_list_free(). 113func (v *List) Free() { 114 C.g_list_free(v.native()) 115} 116 117// Next is a wrapper around the next struct field 118func (v *List) Next() *List { 119 return v.wrapNewHead(v.native().next) 120} 121 122// Previous is a wrapper around the prev struct field 123func (v *List) Previous() *List { 124 return v.wrapNewHead(v.native().prev) 125} 126 127// First is a wrapper around g_list_first(). 128func (v *List) First() *List { 129 return v.wrapNewHead(C.g_list_first(v.native())) 130} 131 132// Last is a wrapper around g_list_last(). 133func (v *List) Last() *List { 134 return v.wrapNewHead(C.g_list_last(v.native())) 135} 136 137// Reverse is a wrapper around g_list_reverse(). 138func (v *List) Reverse() *List { 139 return v.wrapNewHead(C.g_list_reverse(v.native())) 140} 141 142// dataRaw is a wrapper around the data struct field 143func (v *List) dataRaw() unsafe.Pointer { 144 return unsafe.Pointer(v.native().data) 145} 146 147// Data acts the same as data struct field, but passes 148// retrieved value before returning through wrap function, set by DataWrapper(). 149// If no wrap function is set, it returns raw unsafe.Pointer. 150func (v *List) Data() interface{} { 151 ptr := v.dataRaw() 152 if v.dataWrap != nil { 153 return v.dataWrap(ptr) 154 } 155 return ptr 156} 157 158// Foreach acts the same as g_list_foreach(). 159// No user_data argument is implemented because of Go clojure capabilities. 160func (v *List) Foreach(fn func(item interface{})) { 161 for l := v; l != nil; l = l.Next() { 162 fn(l.Data()) 163 } 164} 165 166// FreeFull acts the same as g_list_free_full(). 167// Calling list.FreeFull(fn) is equivalent to calling list.Foreach(fn) and 168// list.Free() sequentially. 169func (v *List) FreeFull(fn func(item interface{})) { 170 v.Foreach(fn) 171 v.Free() 172} 173 174// CompareDataFunc is a representation of GCompareDataFunc 175type CompareDataFunc func(a, b uintptr) int 176