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