EXPERIMENTAL: GoPackedArray converts a zend_array to a Go slice
(arr unsafe.Pointer)
| 166 | |
| 167 | // EXPERIMENTAL: GoPackedArray converts a zend_array to a Go slice |
| 168 | func GoPackedArray[T any](arr unsafe.Pointer) ([]T, error) { |
| 169 | if arr == nil { |
| 170 | return nil, errors.New("GoPackedArray received a nil value") |
| 171 | } |
| 172 | |
| 173 | array := (*C.zend_array)(arr) |
| 174 | |
| 175 | if array == nil { |
| 176 | return nil, fmt.Errorf("GoPackedArray received *zval that wasn't a HashTable") |
| 177 | } |
| 178 | |
| 179 | nNumUsed := array.nNumUsed |
| 180 | result := make([]T, 0, nNumUsed) |
| 181 | |
| 182 | if htIsPacked(array) { |
| 183 | for i := C.uint32_t(0); i < nNumUsed; i++ { |
| 184 | v := C.get_ht_packed_data(array, i) |
| 185 | if v != nil && C.zval_get_type(v) != C.IS_UNDEF { |
| 186 | v, err := goValue[T](v) |
| 187 | if err != nil { |
| 188 | return nil, err |
| 189 | } |
| 190 | |
| 191 | result = append(result, v) |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | return result, nil |
| 196 | } |
| 197 | |
| 198 | // fallback if ht isn't packed - equivalent to array_values() |
| 199 | for i := C.uint32_t(0); i < nNumUsed; i++ { |
| 200 | bucket := C.get_ht_bucket_data(array, i) |
| 201 | if bucket != nil && C.zval_get_type(&bucket.val) != C.IS_UNDEF { |
| 202 | v, err := goValue[T](&bucket.val) |
| 203 | if err != nil { |
| 204 | return nil, err |
| 205 | } |
| 206 | |
| 207 | result = append(result, v) |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | return result, nil |
| 212 | } |
| 213 | |
| 214 | // EXPERIMENTAL: PHPMap converts an unordered Go map to a zend_array |
| 215 | func PHPMap[T any](arr map[string]T) unsafe.Pointer { |
nothing calls this directly
no test coverage detected