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  }