(arr unsafe.Pointer, ordered bool)
| 85 | } |
| 86 | |
| 87 | func goArray[T any](arr unsafe.Pointer, ordered bool) (map[string]T, []string, error) { |
| 88 | if arr == nil { |
| 89 | return nil, nil, errors.New("received a nil pointer on array conversion") |
| 90 | } |
| 91 | |
| 92 | array := (*C.zend_array)(arr) |
| 93 | |
| 94 | if array == nil { |
| 95 | return nil, nil, fmt.Errorf("received a *zval that wasn't a HashTable on array conversion") |
| 96 | } |
| 97 | |
| 98 | nNumUsed := array.nNumUsed |
| 99 | entries := make(map[string]T, nNumUsed) |
| 100 | var order []string |
| 101 | if ordered { |
| 102 | order = make([]string, 0, nNumUsed) |
| 103 | } |
| 104 | |
| 105 | if htIsPacked(array) { |
| 106 | // if the array is packed, convert all integer keys to strings |
| 107 | // this is probably a bug by the dev using this function |
| 108 | // still, we'll (inefficiently) convert to an associative array |
| 109 | for i := C.uint32_t(0); i < nNumUsed; i++ { |
| 110 | v := C.get_ht_packed_data(array, i) |
| 111 | if v != nil && C.zval_get_type(v) != C.IS_UNDEF { |
| 112 | strIndex := strconv.Itoa(int(i)) |
| 113 | e, err := goValue[T](v) |
| 114 | if err != nil { |
| 115 | return nil, nil, err |
| 116 | } |
| 117 | |
| 118 | entries[strIndex] = e |
| 119 | if ordered { |
| 120 | order = append(order, strIndex) |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | return entries, order, nil |
| 126 | } |
| 127 | |
| 128 | var zeroVal T |
| 129 | |
| 130 | for i := C.uint32_t(0); i < nNumUsed; i++ { |
| 131 | bucket := C.get_ht_bucket_data(array, i) |
| 132 | if bucket == nil || C.zval_get_type(&bucket.val) == C.IS_UNDEF { |
| 133 | continue |
| 134 | } |
| 135 | |
| 136 | v, err := goValue[any](&bucket.val) |
| 137 | if err != nil { |
| 138 | return nil, nil, err |
| 139 | } |
| 140 | |
| 141 | if bucket.key != nil { |
| 142 | keyStr := GoString(unsafe.Pointer(bucket.key)) |
| 143 | if v == nil { |
| 144 | entries[keyStr] = zeroVal |
nothing calls this directly
no test coverage detected