github.com/viant/toolbox@v0.34.5/unsafe/pointer.go (about) 1 package unsafe 2 3 import ( 4 "fmt" 5 "reflect" 6 "unsafe" 7 ) 8 9 10 //Pointer represents a func returning field value pointer, it takes holder address 11 type Pointer func(structPtr uintptr) interface{} 12 13 14 //FieldPointer create Pointer function for supported field or error 15 func FieldPointer(structType reflect.Type, fieldIndex int) (Pointer, error) { 16 if structType.Kind() != reflect.Struct { 17 return nil, fmt.Errorf("expected struct but had: %T", reflect.New(structType)) 18 } 19 field := structType.Field(fieldIndex) 20 offset := field.Offset 21 var result Pointer 22 switch field.Type.Kind() { 23 case reflect.Int: 24 result = func(structAddr uintptr) interface{} { 25 return (*int)(unsafe.Pointer(structAddr + offset)) 26 } 27 case reflect.Uint: 28 result = func(structAddr uintptr) interface{} { 29 return (*uint)(unsafe.Pointer(structAddr + offset)) 30 } 31 case reflect.Int64: 32 result = func(structAddr uintptr) interface{} { 33 return (*int64)(unsafe.Pointer(structAddr + offset)) 34 } 35 case reflect.Int32: 36 result = func(structAddr uintptr) interface{} { 37 return (*int32)(unsafe.Pointer(structAddr + offset)) 38 } 39 case reflect.Int16: 40 result = func(structAddr uintptr) interface{} { 41 return (*int16)(unsafe.Pointer(structAddr + offset)) 42 } 43 case reflect.Int8: 44 result = func(structAddr uintptr) interface{} { 45 return (*int8)(unsafe.Pointer(structAddr + offset)) 46 } 47 case reflect.Uint64: 48 result = func(structAddr uintptr) interface{} { 49 return (*uint64)(unsafe.Pointer(structAddr + offset)) 50 } 51 case reflect.Uint32: 52 result = func(structAddr uintptr) interface{} { 53 return (*uint32)(unsafe.Pointer(structAddr + offset)) 54 } 55 case reflect.Uint16: 56 result = func(structAddr uintptr) interface{} { 57 return (*uint16)(unsafe.Pointer(structAddr + offset)) 58 } 59 case reflect.Uint8: 60 result = func(structAddr uintptr) interface{} { 61 return (*uint8)(unsafe.Pointer(structAddr + offset)) 62 } 63 case reflect.String: 64 result = func(structAddr uintptr) interface{} { 65 return (*string)(unsafe.Pointer(structAddr + offset)) 66 } 67 case reflect.Float64: 68 result = func(structAddr uintptr) interface{} { 69 return (*float64)(unsafe.Pointer(structAddr + offset)) 70 } 71 72 case reflect.Float32: 73 result = func(structAddr uintptr) interface{} { 74 return (*float32)(unsafe.Pointer(structAddr + offset)) 75 } 76 case reflect.Bool: 77 result = func(structAddr uintptr) interface{} { 78 return (*bool)(unsafe.Pointer(structAddr + offset)) 79 } 80 81 case reflect.Ptr: 82 switch field.Type.Elem().Kind() { 83 case reflect.Int: 84 result = func(structAddr uintptr) interface{} { 85 return (**int)(unsafe.Pointer(structAddr + offset)) 86 } 87 case reflect.Uint: 88 result = func(structAddr uintptr) interface{} { 89 return (**uint)(unsafe.Pointer(structAddr + offset)) 90 } 91 case reflect.Int64: 92 result = func(structAddr uintptr) interface{} { 93 return (**int64)(unsafe.Pointer(structAddr + offset)) 94 } 95 case reflect.Int32: 96 result = func(structAddr uintptr) interface{} { 97 return (**int32)(unsafe.Pointer(structAddr + offset)) 98 } 99 case reflect.Int16: 100 result = func(structAddr uintptr) interface{} { 101 return (**int16)(unsafe.Pointer(structAddr + offset)) 102 } 103 case reflect.Int8: 104 result = func(structAddr uintptr) interface{} { 105 return (**int8)(unsafe.Pointer(structAddr + offset)) 106 } 107 case reflect.Uint64: 108 result = func(structAddr uintptr) interface{} { 109 return (**uint64)(unsafe.Pointer(structAddr + offset)) 110 } 111 case reflect.Uint32: 112 result = func(structAddr uintptr) interface{} { 113 return (**uint32)(unsafe.Pointer(structAddr + offset)) 114 } 115 case reflect.Uint16: 116 result = func(structAddr uintptr) interface{} { 117 return (**uint16)(unsafe.Pointer(structAddr + offset)) 118 } 119 case reflect.Uint8: 120 result = func(structAddr uintptr) interface{} { 121 return (**uint8)(unsafe.Pointer(structAddr + offset)) 122 } 123 case reflect.String: 124 result = func(structAddr uintptr) interface{} { 125 return (**string)(unsafe.Pointer(structAddr + offset)) 126 } 127 case reflect.Float64: 128 result = func(structAddr uintptr) interface{} { 129 return (**float64)(unsafe.Pointer(structAddr + offset)) 130 } 131 132 case reflect.Float32: 133 result = func(structAddr uintptr) interface{} { 134 return (**float32)(unsafe.Pointer(structAddr + offset)) 135 } 136 case reflect.Bool: 137 result = func(structAddr uintptr) interface{} { 138 return (**bool)(unsafe.Pointer(structAddr + offset)) 139 } 140 case reflect.Slice: 141 switch field.Type.Elem().Elem().Kind() { 142 case reflect.Int: 143 result = func(structAddr uintptr) interface{} { 144 return (**[]int)(unsafe.Pointer(structAddr + offset)) 145 } 146 case reflect.Uint: 147 result = func(structAddr uintptr) interface{} { 148 return (**[]uint)(unsafe.Pointer(structAddr + offset)) 149 } 150 case reflect.Int64: 151 result = func(structAddr uintptr) interface{} { 152 return (**[]int64)(unsafe.Pointer(structAddr + offset)) 153 } 154 case reflect.Int32: 155 result = func(structAddr uintptr) interface{} { 156 return (**[]int32)(unsafe.Pointer(structAddr + offset)) 157 } 158 case reflect.Int16: 159 result = func(structAddr uintptr) interface{} { 160 return (**[]int16)(unsafe.Pointer(structAddr + offset)) 161 } 162 case reflect.Int8: 163 result = func(structAddr uintptr) interface{} { 164 return (**[]int8)(unsafe.Pointer(structAddr + offset)) 165 } 166 case reflect.Uint64: 167 result = func(structAddr uintptr) interface{} { 168 return (**[]uint64)(unsafe.Pointer(structAddr + offset)) 169 } 170 case reflect.Uint32: 171 result = func(structAddr uintptr) interface{} { 172 return (**[]uint32)(unsafe.Pointer(structAddr + offset)) 173 } 174 case reflect.Uint16: 175 result = func(structAddr uintptr) interface{} { 176 return (**[]uint16)(unsafe.Pointer(structAddr + offset)) 177 } 178 case reflect.Uint8: 179 result = func(structAddr uintptr) interface{} { 180 return (**[]uint8)(unsafe.Pointer(structAddr + offset)) 181 } 182 case reflect.String: 183 result = func(structAddr uintptr) interface{} { 184 return (**[]string)(unsafe.Pointer(structAddr + offset)) 185 } 186 case reflect.Float64: 187 result = func(structAddr uintptr) interface{} { 188 return (**[]float64)(unsafe.Pointer(structAddr + offset)) 189 } 190 191 case reflect.Float32: 192 result = func(structAddr uintptr) interface{} { 193 return (**[]float32)(unsafe.Pointer(structAddr + offset)) 194 } 195 case reflect.Bool: 196 result = func(structAddr uintptr) interface{} { 197 return (**[]bool)(unsafe.Pointer(structAddr + offset)) 198 } 199 default: 200 return raiseUnsupportedTypeError(structType, field) 201 } 202 203 default: 204 return raiseUnsupportedTypeError(structType, field) 205 } 206 case reflect.Slice: 207 switch field.Type.Elem().Kind() { 208 case reflect.Int: 209 result = func(structAddr uintptr) interface{} { 210 return (*[]int)(unsafe.Pointer(structAddr + offset)) 211 } 212 case reflect.Uint: 213 result = func(structAddr uintptr) interface{} { 214 return (*[]uint)(unsafe.Pointer(structAddr + offset)) 215 } 216 case reflect.Int64: 217 result = func(structAddr uintptr) interface{} { 218 return (*[]int64)(unsafe.Pointer(structAddr + offset)) 219 } 220 case reflect.Int32: 221 result = func(structAddr uintptr) interface{} { 222 return (*[]int32)(unsafe.Pointer(structAddr + offset)) 223 } 224 case reflect.Int16: 225 result = func(structAddr uintptr) interface{} { 226 return (*[]int16)(unsafe.Pointer(structAddr + offset)) 227 } 228 case reflect.Int8: 229 result = func(structAddr uintptr) interface{} { 230 return (*[]int8)(unsafe.Pointer(structAddr + offset)) 231 } 232 case reflect.Uint64: 233 result = func(structAddr uintptr) interface{} { 234 return (*[]uint64)(unsafe.Pointer(structAddr + offset)) 235 } 236 case reflect.Uint32: 237 result = func(structAddr uintptr) interface{} { 238 return (*[]uint32)(unsafe.Pointer(structAddr + offset)) 239 } 240 case reflect.Uint16: 241 result = func(structAddr uintptr) interface{} { 242 return (*[]uint16)(unsafe.Pointer(structAddr + offset)) 243 } 244 case reflect.Uint8: 245 result = func(structAddr uintptr) interface{} { 246 return (*[]uint8)(unsafe.Pointer(structAddr + offset)) 247 } 248 case reflect.String: 249 result = func(structAddr uintptr) interface{} { 250 return (*[]string)(unsafe.Pointer(structAddr + offset)) 251 } 252 case reflect.Float64: 253 result = func(structAddr uintptr) interface{} { 254 return (*[]float64)(unsafe.Pointer(structAddr + offset)) 255 } 256 257 case reflect.Float32: 258 result = func(structAddr uintptr) interface{} { 259 return (*[]float32)(unsafe.Pointer(structAddr + offset)) 260 } 261 case reflect.Bool: 262 result = func(structAddr uintptr) interface{} { 263 return (*[]bool)(unsafe.Pointer(structAddr + offset)) 264 } 265 default: 266 return raiseUnsupportedTypeError(structType, field) 267 } 268 default: 269 return raiseUnsupportedTypeError(structType, field) 270 } 271 return result, nil 272 } 273 274 func raiseUnsupportedTypeError(holder reflect.Type, field reflect.StructField) (Pointer, error) { 275 return nil, fmt.Errorf("unsupported type: %v, at %T.%s", field.Type.Name(), reflect.New(holder).Interface(), field.Name) 276 }