1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 The PHP Group | |
6 | +----------------------------------------------------------------------+ |
7 | | This source file is subject to version 3.01 of the PHP license, | |
8 | | that is bundled with this package in the file LICENSE, and is | |
9 | | available through the world-wide-web at the following url: | |
10 | | http://www.php.net/license/3_01.txt | |
11 | | If you did not receive a copy of the PHP license and are unable to | |
12 | | obtain it through the world-wide-web, please send a note to | |
13 | | license@php.net so we can mail you a copy immediately. | |
14 | +----------------------------------------------------------------------+ |
15 | | Author: Antony Dovgal <tony@daylessday.org> | |
16 | | Etienne Kneuss <colder@php.net> | |
17 | +----------------------------------------------------------------------+ |
18 | */ |
19 | |
20 | /* $Id$ */ |
21 | |
22 | #ifdef HAVE_CONFIG_H |
23 | #include "config.h" |
24 | #endif |
25 | |
26 | #include "php.h" |
27 | #include "php_ini.h" |
28 | #include "ext/standard/info.h" |
29 | #include "zend_exceptions.h" |
30 | |
31 | #include "php_spl.h" |
32 | #include "spl_functions.h" |
33 | #include "spl_engine.h" |
34 | #include "spl_fixedarray.h" |
35 | #include "spl_exceptions.h" |
36 | #include "spl_iterators.h" |
37 | |
38 | zend_object_handlers spl_handler_SplFixedArray; |
39 | PHPAPI zend_class_entry *spl_ce_SplFixedArray; |
40 | |
41 | #ifdef COMPILE_DL_SPL_FIXEDARRAY |
42 | ZEND_GET_MODULE(spl_fixedarray) |
43 | #endif |
44 | |
45 | typedef struct _spl_fixedarray { /* {{{ */ |
46 | long size; |
47 | zval **elements; |
48 | } spl_fixedarray; |
49 | /* }}} */ |
50 | |
51 | typedef struct _spl_fixedarray_object { /* {{{ */ |
52 | zend_object std; |
53 | spl_fixedarray *array; |
54 | zval *retval; |
55 | zend_function *fptr_offset_get; |
56 | zend_function *fptr_offset_set; |
57 | zend_function *fptr_offset_has; |
58 | zend_function *fptr_offset_del; |
59 | zend_function *fptr_count; |
60 | int current; |
61 | int flags; |
62 | zend_class_entry *ce_get_iterator; |
63 | } spl_fixedarray_object; |
64 | /* }}} */ |
65 | |
66 | typedef struct _spl_fixedarray_it { /* {{{ */ |
67 | zend_user_iterator intern; |
68 | spl_fixedarray_object *object; |
69 | } spl_fixedarray_it; |
70 | /* }}} */ |
71 | |
72 | #define SPL_FIXEDARRAY_OVERLOADED_REWIND 0x0001 |
73 | #define SPL_FIXEDARRAY_OVERLOADED_VALID 0x0002 |
74 | #define SPL_FIXEDARRAY_OVERLOADED_KEY 0x0004 |
75 | #define SPL_FIXEDARRAY_OVERLOADED_CURRENT 0x0008 |
76 | #define SPL_FIXEDARRAY_OVERLOADED_NEXT 0x0010 |
77 | |
78 | static void spl_fixedarray_init(spl_fixedarray *array, long size TSRMLS_DC) /* {{{ */ |
79 | { |
80 | if (size > 0) { |
81 | array->size = 0; /* reset size in case ecalloc() fails */ |
82 | array->elements = ecalloc(size, sizeof(zval *)); |
83 | array->size = size; |
84 | } else { |
85 | array->elements = NULL; |
86 | array->size = 0; |
87 | } |
88 | } |
89 | /* }}} */ |
90 | |
91 | static void spl_fixedarray_resize(spl_fixedarray *array, long size TSRMLS_DC) /* {{{ */ |
92 | { |
93 | if (size == array->size) { |
94 | /* nothing to do */ |
95 | return; |
96 | } |
97 | |
98 | /* first initialization */ |
99 | if (array->size == 0) { |
100 | spl_fixedarray_init(array, size TSRMLS_CC); |
101 | return; |
102 | } |
103 | |
104 | /* clearing the array */ |
105 | if (size == 0) { |
106 | long i; |
107 | |
108 | for (i = 0; i < array->size; i++) { |
109 | if (array->elements[i]) { |
110 | zval_ptr_dtor(&(array->elements[i])); |
111 | } |
112 | } |
113 | |
114 | if (array->elements) { |
115 | efree(array->elements); |
116 | array->elements = NULL; |
117 | } |
118 | } else if (size > array->size) { |
119 | array->elements = safe_erealloc(array->elements, size, sizeof(zval *), 0); |
120 | memset(array->elements + array->size, '\0', sizeof(zval *) * (size - array->size)); |
121 | } else { /* size < array->size */ |
122 | long i; |
123 | |
124 | for (i = size; i < array->size; i++) { |
125 | if (array->elements[i]) { |
126 | zval_ptr_dtor(&(array->elements[i])); |
127 | } |
128 | } |
129 | array->elements = erealloc(array->elements, sizeof(zval *) * size); |
130 | } |
131 | |
132 | array->size = size; |
133 | } |
134 | /* }}} */ |
135 | |
136 | static void spl_fixedarray_copy(spl_fixedarray *to, spl_fixedarray *from TSRMLS_DC) /* {{{ */ |
137 | { |
138 | int i; |
139 | for (i = 0; i < from->size; i++) { |
140 | if (from->elements[i]) { |
141 | Z_ADDREF_P(from->elements[i]); |
142 | to->elements[i] = from->elements[i]; |
143 | } else { |
144 | to->elements[i] = NULL; |
145 | } |
146 | } |
147 | } |
148 | /* }}} */ |
149 | |
150 | static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{{ */ |
151 | { |
152 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC); |
153 | HashTable *ht = zend_std_get_properties(obj TSRMLS_CC); |
154 | |
155 | if (intern->array) { |
156 | *table = intern->array->elements; |
157 | *n = intern->array->size; |
158 | } else { |
159 | *table = NULL; |
160 | *n = 0; |
161 | } |
162 | |
163 | return ht; |
164 | } |
165 | /* }}}} */ |
166 | |
167 | static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {{{{ */ |
168 | { |
169 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC); |
170 | HashTable *ht = zend_std_get_properties(obj TSRMLS_CC); |
171 | int i = 0; |
172 | |
173 | if (intern->array) { |
174 | int j = zend_hash_num_elements(ht); |
175 | |
176 | for (i = 0; i < intern->array->size; i++) { |
177 | if (intern->array->elements[i]) { |
178 | zend_hash_index_update(ht, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL); |
179 | Z_ADDREF_P(intern->array->elements[i]); |
180 | } else { |
181 | zend_hash_index_update(ht, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL); |
182 | Z_ADDREF_P(EG(uninitialized_zval_ptr)); |
183 | } |
184 | } |
185 | if (j > intern->array->size) { |
186 | for (i = intern->array->size; i < j; ++i) { |
187 | zend_hash_index_del(ht, i); |
188 | } |
189 | } |
190 | } |
191 | |
192 | return ht; |
193 | } |
194 | /* }}}} */ |
195 | |
196 | static void spl_fixedarray_object_free_storage(void *object TSRMLS_DC) /* {{{ */ |
197 | { |
198 | spl_fixedarray_object *intern = (spl_fixedarray_object *)object; |
199 | long i; |
200 | |
201 | if (intern->array) { |
202 | for (i = 0; i < intern->array->size; i++) { |
203 | if (intern->array->elements[i]) { |
204 | zval_ptr_dtor(&(intern->array->elements[i])); |
205 | } |
206 | } |
207 | |
208 | if (intern->array->size > 0 && intern->array->elements) { |
209 | efree(intern->array->elements); |
210 | } |
211 | efree(intern->array); |
212 | } |
213 | |
214 | zend_object_std_dtor(&intern->std TSRMLS_CC); |
215 | zval_ptr_dtor(&intern->retval); |
216 | |
217 | efree(object); |
218 | } |
219 | /* }}} */ |
220 | |
221 | zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); |
222 | |
223 | static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_type, spl_fixedarray_object **obj, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */ |
224 | { |
225 | zend_object_value retval; |
226 | spl_fixedarray_object *intern; |
227 | zend_class_entry *parent = class_type; |
228 | int inherited = 0; |
229 | |
230 | intern = ecalloc(1, sizeof(spl_fixedarray_object)); |
231 | *obj = intern; |
232 | ALLOC_INIT_ZVAL(intern->retval); |
233 | |
234 | zend_object_std_init(&intern->std, class_type TSRMLS_CC); |
235 | object_properties_init(&intern->std, class_type); |
236 | |
237 | intern->current = 0; |
238 | intern->flags = 0; |
239 | |
240 | if (orig && clone_orig) { |
241 | spl_fixedarray_object *other = (spl_fixedarray_object*)zend_object_store_get_object(orig TSRMLS_CC); |
242 | intern->ce_get_iterator = other->ce_get_iterator; |
243 | if (!other->array) { |
244 | /* leave a empty object, will be dtor later by CLONE handler */ |
245 | zend_throw_exception(spl_ce_RuntimeException, "The instance wasn't initialized properly" , 0 TSRMLS_CC); |
246 | } else { |
247 | intern->array = emalloc(sizeof(spl_fixedarray)); |
248 | spl_fixedarray_init(intern->array, other->array->size TSRMLS_CC); |
249 | spl_fixedarray_copy(intern->array, other->array TSRMLS_CC); |
250 | } |
251 | } |
252 | |
253 | while (parent) { |
254 | if (parent == spl_ce_SplFixedArray) { |
255 | retval.handlers = &spl_handler_SplFixedArray; |
256 | class_type->get_iterator = spl_fixedarray_get_iterator; |
257 | break; |
258 | } |
259 | |
260 | parent = parent->parent; |
261 | inherited = 1; |
262 | } |
263 | |
264 | retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_fixedarray_object_free_storage, NULL TSRMLS_CC); |
265 | |
266 | if (!parent) { /* this must never happen */ |
267 | php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray" ); |
268 | } |
269 | if (!class_type->iterator_funcs.zf_current) { |
270 | zend_hash_find(&class_type->function_table, "rewind" , sizeof("rewind" ), (void **) &class_type->iterator_funcs.zf_rewind); |
271 | zend_hash_find(&class_type->function_table, "valid" , sizeof("valid" ), (void **) &class_type->iterator_funcs.zf_valid); |
272 | zend_hash_find(&class_type->function_table, "key" , sizeof("key" ), (void **) &class_type->iterator_funcs.zf_key); |
273 | zend_hash_find(&class_type->function_table, "current" , sizeof("current" ), (void **) &class_type->iterator_funcs.zf_current); |
274 | zend_hash_find(&class_type->function_table, "next" , sizeof("next" ), (void **) &class_type->iterator_funcs.zf_next); |
275 | } |
276 | if (inherited) { |
277 | if (class_type->iterator_funcs.zf_rewind->common.scope != parent) { |
278 | intern->flags |= SPL_FIXEDARRAY_OVERLOADED_REWIND; |
279 | } |
280 | if (class_type->iterator_funcs.zf_valid->common.scope != parent) { |
281 | intern->flags |= SPL_FIXEDARRAY_OVERLOADED_VALID; |
282 | } |
283 | if (class_type->iterator_funcs.zf_key->common.scope != parent) { |
284 | intern->flags |= SPL_FIXEDARRAY_OVERLOADED_KEY; |
285 | } |
286 | if (class_type->iterator_funcs.zf_current->common.scope != parent) { |
287 | intern->flags |= SPL_FIXEDARRAY_OVERLOADED_CURRENT; |
288 | } |
289 | if (class_type->iterator_funcs.zf_next->common.scope != parent) { |
290 | intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT; |
291 | } |
292 | |
293 | zend_hash_find(&class_type->function_table, "offsetget" , sizeof("offsetget" ), (void **) &intern->fptr_offset_get); |
294 | if (intern->fptr_offset_get->common.scope == parent) { |
295 | intern->fptr_offset_get = NULL; |
296 | } |
297 | zend_hash_find(&class_type->function_table, "offsetset" , sizeof("offsetset" ), (void **) &intern->fptr_offset_set); |
298 | if (intern->fptr_offset_set->common.scope == parent) { |
299 | intern->fptr_offset_set = NULL; |
300 | } |
301 | zend_hash_find(&class_type->function_table, "offsetexists" , sizeof("offsetexists" ), (void **) &intern->fptr_offset_has); |
302 | if (intern->fptr_offset_has->common.scope == parent) { |
303 | intern->fptr_offset_has = NULL; |
304 | } |
305 | zend_hash_find(&class_type->function_table, "offsetunset" , sizeof("offsetunset" ), (void **) &intern->fptr_offset_del); |
306 | if (intern->fptr_offset_del->common.scope == parent) { |
307 | intern->fptr_offset_del = NULL; |
308 | } |
309 | zend_hash_find(&class_type->function_table, "count" , sizeof("count" ), (void **) &intern->fptr_count); |
310 | if (intern->fptr_count->common.scope == parent) { |
311 | intern->fptr_count = NULL; |
312 | } |
313 | } |
314 | |
315 | return retval; |
316 | } |
317 | /* }}} */ |
318 | |
319 | static zend_object_value spl_fixedarray_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ |
320 | { |
321 | spl_fixedarray_object *tmp; |
322 | return spl_fixedarray_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC); |
323 | } |
324 | /* }}} */ |
325 | |
326 | static zend_object_value spl_fixedarray_object_clone(zval *zobject TSRMLS_DC) /* {{{ */ |
327 | { |
328 | zend_object_value new_obj_val; |
329 | zend_object *old_object; |
330 | zend_object *new_object; |
331 | zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); |
332 | spl_fixedarray_object *intern; |
333 | |
334 | old_object = zend_objects_get_address(zobject TSRMLS_CC); |
335 | new_obj_val = spl_fixedarray_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC); |
336 | new_object = &intern->std; |
337 | |
338 | zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC); |
339 | |
340 | return new_obj_val; |
341 | } |
342 | /* }}} */ |
343 | |
344 | static inline zval **spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */ |
345 | { |
346 | long index; |
347 | |
348 | /* we have to return NULL on error here to avoid memleak because of |
349 | * ZE duplicating uninitialized_zval_ptr */ |
350 | if (!offset) { |
351 | zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range" , 0 TSRMLS_CC); |
352 | return NULL; |
353 | } |
354 | |
355 | if (Z_TYPE_P(offset) != IS_LONG) { |
356 | index = spl_offset_convert_to_long(offset TSRMLS_CC); |
357 | } else { |
358 | index = Z_LVAL_P(offset); |
359 | } |
360 | |
361 | if (index < 0 || intern->array == NULL || index >= intern->array->size) { |
362 | zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range" , 0 TSRMLS_CC); |
363 | return NULL; |
364 | } else if(!intern->array->elements[index]) { |
365 | return NULL; |
366 | } else { |
367 | return &intern->array->elements[index]; |
368 | } |
369 | } |
370 | /* }}} */ |
371 | |
372 | static zval *spl_fixedarray_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */ |
373 | { |
374 | spl_fixedarray_object *intern; |
375 | zval **retval; |
376 | |
377 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
378 | |
379 | if (intern->fptr_offset_get) { |
380 | zval *rv; |
381 | if (!offset) { |
382 | ALLOC_INIT_ZVAL(offset); |
383 | } else { |
384 | SEPARATE_ARG_IF_REF(offset); |
385 | } |
386 | zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_get, "offsetGet" , &rv, offset); |
387 | zval_ptr_dtor(&offset); |
388 | if (rv) { |
389 | zval_ptr_dtor(&intern->retval); |
390 | MAKE_STD_ZVAL(intern->retval); |
391 | ZVAL_ZVAL(intern->retval, rv, 1, 1); |
392 | return intern->retval; |
393 | } |
394 | return EG(uninitialized_zval_ptr); |
395 | } |
396 | |
397 | retval = spl_fixedarray_object_read_dimension_helper(intern, offset TSRMLS_CC); |
398 | if (retval) { |
399 | return *retval; |
400 | } |
401 | return NULL; |
402 | } |
403 | /* }}} */ |
404 | |
405 | static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value TSRMLS_DC) /* {{{ */ |
406 | { |
407 | long index; |
408 | |
409 | if (!offset) { |
410 | /* '$array[] = value' syntax is not supported */ |
411 | zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range" , 0 TSRMLS_CC); |
412 | return; |
413 | } |
414 | |
415 | if (Z_TYPE_P(offset) != IS_LONG) { |
416 | index = spl_offset_convert_to_long(offset TSRMLS_CC); |
417 | } else { |
418 | index = Z_LVAL_P(offset); |
419 | } |
420 | |
421 | if (index < 0 || intern->array == NULL || index >= intern->array->size) { |
422 | zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range" , 0 TSRMLS_CC); |
423 | return; |
424 | } else { |
425 | if (intern->array->elements[index]) { |
426 | zval_ptr_dtor(&(intern->array->elements[index])); |
427 | } |
428 | SEPARATE_ARG_IF_REF(value); |
429 | intern->array->elements[index] = value; |
430 | } |
431 | } |
432 | /* }}} */ |
433 | |
434 | static void spl_fixedarray_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */ |
435 | { |
436 | spl_fixedarray_object *intern; |
437 | |
438 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
439 | |
440 | if (intern->fptr_offset_set) { |
441 | if (!offset) { |
442 | ALLOC_INIT_ZVAL(offset); |
443 | } else { |
444 | SEPARATE_ARG_IF_REF(offset); |
445 | } |
446 | SEPARATE_ARG_IF_REF(value); |
447 | zend_call_method_with_2_params(&object, intern->std.ce, &intern->fptr_offset_set, "offsetSet" , NULL, offset, value); |
448 | zval_ptr_dtor(&value); |
449 | zval_ptr_dtor(&offset); |
450 | return; |
451 | } |
452 | |
453 | spl_fixedarray_object_write_dimension_helper(intern, offset, value TSRMLS_CC); |
454 | } |
455 | /* }}} */ |
456 | |
457 | static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */ |
458 | { |
459 | long index; |
460 | |
461 | if (Z_TYPE_P(offset) != IS_LONG) { |
462 | index = spl_offset_convert_to_long(offset TSRMLS_CC); |
463 | } else { |
464 | index = Z_LVAL_P(offset); |
465 | } |
466 | |
467 | if (index < 0 || intern->array == NULL || index >= intern->array->size) { |
468 | zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range" , 0 TSRMLS_CC); |
469 | return; |
470 | } else { |
471 | if (intern->array->elements[index]) { |
472 | zval_ptr_dtor(&(intern->array->elements[index])); |
473 | } |
474 | intern->array->elements[index] = NULL; |
475 | } |
476 | } |
477 | /* }}} */ |
478 | |
479 | static void spl_fixedarray_object_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */ |
480 | { |
481 | spl_fixedarray_object *intern; |
482 | |
483 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
484 | |
485 | if (intern->fptr_offset_del) { |
486 | SEPARATE_ARG_IF_REF(offset); |
487 | zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset" , NULL, offset); |
488 | zval_ptr_dtor(&offset); |
489 | return; |
490 | } |
491 | |
492 | spl_fixedarray_object_unset_dimension_helper(intern, offset TSRMLS_CC); |
493 | |
494 | } |
495 | /* }}} */ |
496 | |
497 | static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_object *intern, zval *offset, int check_empty TSRMLS_DC) /* {{{ */ |
498 | { |
499 | long index; |
500 | int retval; |
501 | |
502 | if (Z_TYPE_P(offset) != IS_LONG) { |
503 | index = spl_offset_convert_to_long(offset TSRMLS_CC); |
504 | } else { |
505 | index = Z_LVAL_P(offset); |
506 | } |
507 | |
508 | if (index < 0 || intern->array == NULL || index >= intern->array->size) { |
509 | retval = 0; |
510 | } else { |
511 | if (!intern->array->elements[index]) { |
512 | retval = 0; |
513 | } else if (check_empty) { |
514 | if (zend_is_true(intern->array->elements[index])) { |
515 | retval = 1; |
516 | } else { |
517 | retval = 0; |
518 | } |
519 | } else { /* != NULL and !check_empty */ |
520 | retval = 1; |
521 | } |
522 | } |
523 | |
524 | return retval; |
525 | } |
526 | /* }}} */ |
527 | |
528 | static int spl_fixedarray_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */ |
529 | { |
530 | spl_fixedarray_object *intern; |
531 | |
532 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
533 | |
534 | if (intern->fptr_offset_get) { |
535 | zval *rv; |
536 | SEPARATE_ARG_IF_REF(offset); |
537 | zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_has, "offsetExists" , &rv, offset); |
538 | zval_ptr_dtor(&offset); |
539 | if (rv) { |
540 | zval_ptr_dtor(&intern->retval); |
541 | MAKE_STD_ZVAL(intern->retval); |
542 | ZVAL_ZVAL(intern->retval, rv, 1, 1); |
543 | return zend_is_true(intern->retval); |
544 | } |
545 | return 0; |
546 | } |
547 | |
548 | return spl_fixedarray_object_has_dimension_helper(intern, offset, check_empty TSRMLS_CC); |
549 | } |
550 | /* }}} */ |
551 | |
552 | static int spl_fixedarray_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ |
553 | { |
554 | spl_fixedarray_object *intern; |
555 | |
556 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
557 | if (intern->fptr_count) { |
558 | zval *rv; |
559 | zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count" , &rv); |
560 | if (rv) { |
561 | zval_ptr_dtor(&intern->retval); |
562 | MAKE_STD_ZVAL(intern->retval); |
563 | ZVAL_ZVAL(intern->retval, rv, 1, 1); |
564 | convert_to_long(intern->retval); |
565 | *count = (long) Z_LVAL_P(intern->retval); |
566 | return SUCCESS; |
567 | } |
568 | } else if (intern->array) { |
569 | *count = intern->array->size; |
570 | return SUCCESS; |
571 | } |
572 | |
573 | *count = 0; |
574 | return SUCCESS; |
575 | } |
576 | /* }}} */ |
577 | |
578 | /* {{{ proto void SplFixedArray::__construct([int size]) |
579 | */ |
580 | SPL_METHOD(SplFixedArray, __construct) |
581 | { |
582 | zval *object = getThis(); |
583 | spl_fixedarray_object *intern; |
584 | long size = 0; |
585 | |
586 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l" , &size) == FAILURE) { |
587 | return; |
588 | } |
589 | |
590 | if (size < 0) { |
591 | zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array size cannot be less than zero" ); |
592 | return; |
593 | } |
594 | |
595 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
596 | |
597 | if (intern->array) { |
598 | /* called __construct() twice, bail out */ |
599 | return; |
600 | } |
601 | |
602 | intern->array = emalloc(sizeof(spl_fixedarray)); |
603 | spl_fixedarray_init(intern->array, size TSRMLS_CC); |
604 | } |
605 | /* }}} */ |
606 | |
607 | /* {{{ proto void SplFixedArray::__wakeup() |
608 | */ |
609 | SPL_METHOD(SplFixedArray, __wakeup) |
610 | { |
611 | spl_fixedarray_object *intern = (spl_fixedarray_object *) zend_object_store_get_object(getThis() TSRMLS_CC); |
612 | HashPosition ptr; |
613 | HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC); |
614 | zval **data; |
615 | |
616 | if (zend_parse_parameters_none() == FAILURE) { |
617 | return; |
618 | } |
619 | |
620 | if (!intern->array) { |
621 | int index = 0; |
622 | int size = zend_hash_num_elements(intern_ht); |
623 | |
624 | intern->array = emalloc(sizeof(spl_fixedarray)); |
625 | spl_fixedarray_init(intern->array, size TSRMLS_CC); |
626 | |
627 | for (zend_hash_internal_pointer_reset_ex(intern_ht, &ptr); zend_hash_get_current_data_ex(intern_ht, (void **) &data, &ptr) == SUCCESS; zend_hash_move_forward_ex(intern_ht, &ptr)) { |
628 | Z_ADDREF_PP(data); |
629 | intern->array->elements[index++] = *data; |
630 | } |
631 | |
632 | /* Remove the unserialised properties, since we now have the elements |
633 | * within the spl_fixedarray_object structure. */ |
634 | zend_hash_clean(intern_ht); |
635 | } |
636 | } |
637 | /* }}} */ |
638 | |
639 | /* {{{ proto int SplFixedArray::count(void) |
640 | */ |
641 | SPL_METHOD(SplFixedArray, count) |
642 | { |
643 | zval *object = getThis(); |
644 | spl_fixedarray_object *intern; |
645 | |
646 | if (zend_parse_parameters_none() == FAILURE) { |
647 | return; |
648 | } |
649 | |
650 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
651 | if (intern->array) { |
652 | RETURN_LONG(intern->array->size); |
653 | } |
654 | RETURN_LONG(0); |
655 | } |
656 | /* }}} */ |
657 | |
658 | /* {{{ proto object SplFixedArray::toArray() |
659 | */ |
660 | SPL_METHOD(SplFixedArray, toArray) |
661 | { |
662 | spl_fixedarray_object *intern; |
663 | |
664 | if (zend_parse_parameters_none() == FAILURE) { |
665 | return; |
666 | } |
667 | |
668 | intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC); |
669 | |
670 | array_init(return_value); |
671 | if (intern->array) { |
672 | int i = 0; |
673 | for (; i < intern->array->size; i++) { |
674 | if (intern->array->elements[i]) { |
675 | zend_hash_index_update(Z_ARRVAL_P(return_value), i, (void *)&intern->array->elements[i], sizeof(zval *), NULL); |
676 | Z_ADDREF_P(intern->array->elements[i]); |
677 | } else { |
678 | zend_hash_index_update(Z_ARRVAL_P(return_value), i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL); |
679 | Z_ADDREF_P(EG(uninitialized_zval_ptr)); |
680 | } |
681 | } |
682 | } |
683 | } |
684 | /* }}} */ |
685 | |
686 | /* {{{ proto object SplFixedArray::fromArray(array data[, bool save_indexes]) |
687 | */ |
688 | SPL_METHOD(SplFixedArray, fromArray) |
689 | { |
690 | zval *data; |
691 | spl_fixedarray *array; |
692 | spl_fixedarray_object *intern; |
693 | int num; |
694 | zend_bool save_indexes = 1; |
695 | |
696 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b" , &data, &save_indexes) == FAILURE) { |
697 | return; |
698 | } |
699 | |
700 | array = ecalloc(1, sizeof(*array)); |
701 | num = zend_hash_num_elements(Z_ARRVAL_P(data)); |
702 | |
703 | if (num > 0 && save_indexes) { |
704 | zval **element, *value; |
705 | char *str_index; |
706 | ulong num_index, max_index = 0; |
707 | long tmp; |
708 | |
709 | for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data)); |
710 | zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS; |
711 | zend_hash_move_forward(Z_ARRVAL_P(data)) |
712 | ) { |
713 | if (zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0) != HASH_KEY_IS_LONG || (long)num_index < 0) { |
714 | efree(array); |
715 | zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array must contain only positive integer keys" ); |
716 | return; |
717 | } |
718 | |
719 | if (num_index > max_index) { |
720 | max_index = num_index; |
721 | } |
722 | } |
723 | |
724 | tmp = max_index + 1; |
725 | if (tmp <= 0) { |
726 | efree(array); |
727 | zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "integer overflow detected" ); |
728 | return; |
729 | } |
730 | spl_fixedarray_init(array, tmp TSRMLS_CC); |
731 | |
732 | for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data)); |
733 | zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS; |
734 | zend_hash_move_forward(Z_ARRVAL_P(data)) |
735 | ) { |
736 | |
737 | zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0); |
738 | value = *element; |
739 | |
740 | SEPARATE_ARG_IF_REF(value); |
741 | array->elements[num_index] = value; |
742 | } |
743 | |
744 | } else if (num > 0 && !save_indexes) { |
745 | zval **element, *value; |
746 | long i = 0; |
747 | |
748 | spl_fixedarray_init(array, num TSRMLS_CC); |
749 | |
750 | for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data)); |
751 | zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS; |
752 | zend_hash_move_forward(Z_ARRVAL_P(data)) |
753 | ) { |
754 | |
755 | value = *element; |
756 | |
757 | SEPARATE_ARG_IF_REF(value); |
758 | array->elements[i] = value; |
759 | i++; |
760 | } |
761 | } else { |
762 | spl_fixedarray_init(array, 0 TSRMLS_CC); |
763 | } |
764 | |
765 | object_init_ex(return_value, spl_ce_SplFixedArray); |
766 | Z_TYPE_P(return_value) = IS_OBJECT; |
767 | |
768 | intern = (spl_fixedarray_object *)zend_object_store_get_object(return_value TSRMLS_CC); |
769 | intern->array = array; |
770 | } |
771 | /* }}} */ |
772 | |
773 | /* {{{ proto int SplFixedArray::getSize(void) |
774 | */ |
775 | SPL_METHOD(SplFixedArray, getSize) |
776 | { |
777 | zval *object = getThis(); |
778 | spl_fixedarray_object *intern; |
779 | |
780 | if (zend_parse_parameters_none() == FAILURE) { |
781 | return; |
782 | } |
783 | |
784 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
785 | if (intern->array) { |
786 | RETURN_LONG(intern->array->size); |
787 | } |
788 | RETURN_LONG(0); |
789 | } |
790 | /* }}} */ |
791 | |
792 | /* {{{ proto bool SplFixedArray::setSize(int size) |
793 | */ |
794 | SPL_METHOD(SplFixedArray, setSize) |
795 | { |
796 | zval *object = getThis(); |
797 | spl_fixedarray_object *intern; |
798 | long size; |
799 | |
800 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l" , &size) == FAILURE) { |
801 | return; |
802 | } |
803 | |
804 | if (size < 0) { |
805 | zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array size cannot be less than zero" ); |
806 | return; |
807 | } |
808 | |
809 | intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); |
810 | if (!intern->array) { |
811 | intern->array = ecalloc(1, sizeof(spl_fixedarray)); |
812 | } |
813 | |
814 | spl_fixedarray_resize(intern->array, size TSRMLS_CC); |
815 | RETURN_TRUE; |
816 | } |
817 | /* }}} */ |
818 | |
819 | /* {{{ proto bool SplFixedArray::offsetExists(mixed $index) U |
820 | Returns whether the requested $index exists. */ |
821 | SPL_METHOD(SplFixedArray, offsetExists) |
822 | { |
823 | zval *zindex; |
824 | spl_fixedarray_object *intern; |
825 | |
826 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z" , &zindex) == FAILURE) { |
827 | return; |
828 | } |
829 | |
830 | intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC); |
831 | |
832 | RETURN_BOOL(spl_fixedarray_object_has_dimension_helper(intern, zindex, 0 TSRMLS_CC)); |
833 | } /* }}} */ |
834 | |
835 | /* {{{ proto mixed SplFixedArray::offsetGet(mixed $index) U |
836 | Returns the value at the specified $index. */ |
837 | SPL_METHOD(SplFixedArray, offsetGet) |
838 | { |
839 | zval *zindex, **value_pp; |
840 | spl_fixedarray_object *intern; |
841 | |
842 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z" , &zindex) == FAILURE) { |
843 | return; |
844 | } |
845 | |
846 | intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC); |
847 | value_pp = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC); |
848 | |
849 | if (value_pp) { |
850 | RETURN_ZVAL(*value_pp, 1, 0); |
851 | } |
852 | RETURN_NULL(); |
853 | } /* }}} */ |
854 | |
855 | /* {{{ proto void SplFixedArray::offsetSet(mixed $index, mixed $newval) U |
856 | Sets the value at the specified $index to $newval. */ |
857 | SPL_METHOD(SplFixedArray, offsetSet) |
858 | { |
859 | zval *zindex, *value; |
860 | spl_fixedarray_object *intern; |
861 | |
862 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz" , &zindex, &value) == FAILURE) { |
863 | return; |
864 | } |
865 | |
866 | intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC); |
867 | spl_fixedarray_object_write_dimension_helper(intern, zindex, value TSRMLS_CC); |
868 | |
869 | } /* }}} */ |
870 | |
871 | /* {{{ proto void SplFixedArray::offsetUnset(mixed $index) U |
872 | Unsets the value at the specified $index. */ |
873 | SPL_METHOD(SplFixedArray, offsetUnset) |
874 | { |
875 | zval *zindex; |
876 | spl_fixedarray_object *intern; |
877 | |
878 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z" , &zindex) == FAILURE) { |
879 | return; |
880 | } |
881 | |
882 | intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC); |
883 | spl_fixedarray_object_unset_dimension_helper(intern, zindex TSRMLS_CC); |
884 | |
885 | } /* }}} */ |
886 | |
887 | static void spl_fixedarray_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ |
888 | { |
889 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
890 | |
891 | zend_user_it_invalidate_current(iter TSRMLS_CC); |
892 | zval_ptr_dtor((zval**)&iterator->intern.it.data); |
893 | |
894 | efree(iterator); |
895 | } |
896 | /* }}} */ |
897 | |
898 | static void spl_fixedarray_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ |
899 | { |
900 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
901 | spl_fixedarray_object *intern = iterator->object; |
902 | |
903 | if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_REWIND) { |
904 | zend_user_it_rewind(iter TSRMLS_CC); |
905 | } else { |
906 | iterator->object->current = 0; |
907 | } |
908 | } |
909 | /* }}} */ |
910 | |
911 | static int spl_fixedarray_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ |
912 | { |
913 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
914 | spl_fixedarray_object *intern = iterator->object; |
915 | |
916 | if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_VALID) { |
917 | return zend_user_it_valid(iter TSRMLS_CC); |
918 | } |
919 | |
920 | if (iterator->object->current >= 0 && iterator->object->array && iterator->object->current < iterator->object->array->size) { |
921 | return SUCCESS; |
922 | } |
923 | |
924 | return FAILURE; |
925 | } |
926 | /* }}} */ |
927 | |
928 | static void spl_fixedarray_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */ |
929 | { |
930 | zval *zindex; |
931 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
932 | spl_fixedarray_object *intern = iterator->object; |
933 | |
934 | if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_CURRENT) { |
935 | zend_user_it_get_current_data(iter, data TSRMLS_CC); |
936 | } else { |
937 | ALLOC_INIT_ZVAL(zindex); |
938 | ZVAL_LONG(zindex, iterator->object->current); |
939 | |
940 | *data = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC); |
941 | |
942 | if (*data == NULL) { |
943 | *data = &EG(uninitialized_zval_ptr); |
944 | } |
945 | |
946 | zval_ptr_dtor(&zindex); |
947 | } |
948 | } |
949 | /* }}} */ |
950 | |
951 | static void spl_fixedarray_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */ |
952 | { |
953 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
954 | spl_fixedarray_object *intern = iterator->object; |
955 | |
956 | if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_KEY) { |
957 | zend_user_it_get_current_key(iter, key TSRMLS_CC); |
958 | } else { |
959 | ZVAL_LONG(key, iterator->object->current); |
960 | } |
961 | } |
962 | /* }}} */ |
963 | |
964 | static void spl_fixedarray_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ |
965 | { |
966 | spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter; |
967 | spl_fixedarray_object *intern = iterator->object; |
968 | |
969 | if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_NEXT) { |
970 | zend_user_it_move_forward(iter TSRMLS_CC); |
971 | } else { |
972 | zend_user_it_invalidate_current(iter TSRMLS_CC); |
973 | iterator->object->current++; |
974 | } |
975 | } |
976 | /* }}} */ |
977 | |
978 | /* {{{ proto int SplFixedArray::key() U |
979 | Return current array key */ |
980 | SPL_METHOD(SplFixedArray, key) |
981 | { |
982 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC); |
983 | |
984 | if (zend_parse_parameters_none() == FAILURE) { |
985 | return; |
986 | } |
987 | |
988 | RETURN_LONG(intern->current); |
989 | } |
990 | /* }}} */ |
991 | |
992 | /* {{{ proto void SplFixedArray::next() U |
993 | Move to next entry */ |
994 | SPL_METHOD(SplFixedArray, next) |
995 | { |
996 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC); |
997 | |
998 | if (zend_parse_parameters_none() == FAILURE) { |
999 | return; |
1000 | } |
1001 | |
1002 | intern->current++; |
1003 | } |
1004 | /* }}} */ |
1005 | |
1006 | /* {{{ proto bool SplFixedArray::valid() U |
1007 | Check whether the datastructure contains more entries */ |
1008 | SPL_METHOD(SplFixedArray, valid) |
1009 | { |
1010 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC); |
1011 | |
1012 | if (zend_parse_parameters_none() == FAILURE) { |
1013 | return; |
1014 | } |
1015 | |
1016 | RETURN_BOOL(intern->current >= 0 && intern->array && intern->current < intern->array->size); |
1017 | } |
1018 | /* }}} */ |
1019 | |
1020 | /* {{{ proto void SplFixedArray::rewind() U |
1021 | Rewind the datastructure back to the start */ |
1022 | SPL_METHOD(SplFixedArray, rewind) |
1023 | { |
1024 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC); |
1025 | |
1026 | if (zend_parse_parameters_none() == FAILURE) { |
1027 | return; |
1028 | } |
1029 | |
1030 | intern->current = 0; |
1031 | } |
1032 | /* }}} */ |
1033 | |
1034 | /* {{{ proto mixed|NULL SplFixedArray::current() U |
1035 | Return current datastructure entry */ |
1036 | SPL_METHOD(SplFixedArray, current) |
1037 | { |
1038 | zval *zindex, **value_pp; |
1039 | spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC); |
1040 | |
1041 | if (zend_parse_parameters_none() == FAILURE) { |
1042 | return; |
1043 | } |
1044 | |
1045 | ALLOC_INIT_ZVAL(zindex); |
1046 | ZVAL_LONG(zindex, intern->current); |
1047 | |
1048 | value_pp = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC); |
1049 | |
1050 | zval_ptr_dtor(&zindex); |
1051 | |
1052 | if (value_pp) { |
1053 | RETURN_ZVAL(*value_pp, 1, 0); |
1054 | } |
1055 | RETURN_NULL(); |
1056 | } |
1057 | /* }}} */ |
1058 | |
1059 | /* iterator handler table */ |
1060 | zend_object_iterator_funcs spl_fixedarray_it_funcs = { |
1061 | spl_fixedarray_it_dtor, |
1062 | spl_fixedarray_it_valid, |
1063 | spl_fixedarray_it_get_current_data, |
1064 | spl_fixedarray_it_get_current_key, |
1065 | spl_fixedarray_it_move_forward, |
1066 | spl_fixedarray_it_rewind |
1067 | }; |
1068 | |
1069 | zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */ |
1070 | { |
1071 | spl_fixedarray_it *iterator; |
1072 | spl_fixedarray_object *fixedarray_object = (spl_fixedarray_object*)zend_object_store_get_object(object TSRMLS_CC); |
1073 | |
1074 | if (by_ref) { |
1075 | zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference" , 0 TSRMLS_CC); |
1076 | return NULL; |
1077 | } |
1078 | |
1079 | Z_ADDREF_P(object); |
1080 | |
1081 | iterator = emalloc(sizeof(spl_fixedarray_it)); |
1082 | iterator->intern.it.data = (void*)object; |
1083 | iterator->intern.it.funcs = &spl_fixedarray_it_funcs; |
1084 | iterator->intern.ce = ce; |
1085 | iterator->intern.value = NULL; |
1086 | iterator->object = fixedarray_object; |
1087 | |
1088 | return (zend_object_iterator*)iterator; |
1089 | } |
1090 | /* }}} */ |
1091 | |
1092 | ZEND_BEGIN_ARG_INFO_EX(arginfo_splfixedarray_construct, 0, 0, 0) |
1093 | ZEND_ARG_INFO(0, size) |
1094 | ZEND_END_ARG_INFO() |
1095 | |
1096 | ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetGet, 0, 0, 1) |
1097 | ZEND_ARG_INFO(0, index) |
1098 | ZEND_END_ARG_INFO() |
1099 | |
1100 | ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetSet, 0, 0, 2) |
1101 | ZEND_ARG_INFO(0, index) |
1102 | ZEND_ARG_INFO(0, newval) |
1103 | ZEND_END_ARG_INFO() |
1104 | |
1105 | ZEND_BEGIN_ARG_INFO(arginfo_fixedarray_setSize, 0) |
1106 | ZEND_ARG_INFO(0, value) |
1107 | ZEND_END_ARG_INFO() |
1108 | |
1109 | ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_fromArray, 0, 0, 1) |
1110 | ZEND_ARG_INFO(0, data) |
1111 | ZEND_ARG_INFO(0, save_indexes) |
1112 | ZEND_END_ARG_INFO() |
1113 | |
1114 | ZEND_BEGIN_ARG_INFO(arginfo_splfixedarray_void, 0) |
1115 | ZEND_END_ARG_INFO() |
1116 | |
1117 | static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */ |
1118 | SPL_ME(SplFixedArray, __construct, arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC) |
1119 | SPL_ME(SplFixedArray, __wakeup, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1120 | SPL_ME(SplFixedArray, count, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1121 | SPL_ME(SplFixedArray, toArray, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1122 | SPL_ME(SplFixedArray, fromArray, arginfo_fixedarray_fromArray, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) |
1123 | SPL_ME(SplFixedArray, getSize, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1124 | SPL_ME(SplFixedArray, setSize, arginfo_fixedarray_setSize, ZEND_ACC_PUBLIC) |
1125 | SPL_ME(SplFixedArray, offsetExists, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) |
1126 | SPL_ME(SplFixedArray, offsetGet, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) |
1127 | SPL_ME(SplFixedArray, offsetSet, arginfo_fixedarray_offsetSet, ZEND_ACC_PUBLIC) |
1128 | SPL_ME(SplFixedArray, offsetUnset, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) |
1129 | SPL_ME(SplFixedArray, rewind, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1130 | SPL_ME(SplFixedArray, current, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1131 | SPL_ME(SplFixedArray, key, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1132 | SPL_ME(SplFixedArray, next, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1133 | SPL_ME(SplFixedArray, valid, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) |
1134 | PHP_FE_END |
1135 | }; |
1136 | /* }}} */ |
1137 | |
1138 | /* {{{ PHP_MINIT_FUNCTION */ |
1139 | PHP_MINIT_FUNCTION(spl_fixedarray) |
1140 | { |
1141 | REGISTER_SPL_STD_CLASS_EX(SplFixedArray, spl_fixedarray_new, spl_funcs_SplFixedArray); |
1142 | memcpy(&spl_handler_SplFixedArray, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); |
1143 | |
1144 | spl_handler_SplFixedArray.clone_obj = spl_fixedarray_object_clone; |
1145 | spl_handler_SplFixedArray.read_dimension = spl_fixedarray_object_read_dimension; |
1146 | spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension; |
1147 | spl_handler_SplFixedArray.unset_dimension = spl_fixedarray_object_unset_dimension; |
1148 | spl_handler_SplFixedArray.has_dimension = spl_fixedarray_object_has_dimension; |
1149 | spl_handler_SplFixedArray.count_elements = spl_fixedarray_object_count_elements; |
1150 | spl_handler_SplFixedArray.get_properties = spl_fixedarray_object_get_properties; |
1151 | spl_handler_SplFixedArray.get_gc = spl_fixedarray_object_get_gc; |
1152 | |
1153 | REGISTER_SPL_IMPLEMENTS(SplFixedArray, Iterator); |
1154 | REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess); |
1155 | REGISTER_SPL_IMPLEMENTS(SplFixedArray, Countable); |
1156 | |
1157 | spl_ce_SplFixedArray->get_iterator = spl_fixedarray_get_iterator; |
1158 | |
1159 | return SUCCESS; |
1160 | } |
1161 | /* }}} */ |
1162 | |
1163 | |
1164 | /* |
1165 | * Local variables: |
1166 | * tab-width: 4 |
1167 | * c-basic-offset: 4 |
1168 | * End: |
1169 | * vim600: noet sw=4 ts=4 fdm=marker |
1170 | * vim<600: noet sw=4 ts=4 |
1171 | */ |
1172 | |