Annotation of embedaddon/php/ext/spl/spl_fixedarray.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.3   misho       5:   | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      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 = erealloc(array->elements, sizeof(zval *) * size);
                    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: 
1.1.1.3   misho     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: 
1.1       misho     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);
1.1.1.2   misho     170:        HashTable *ht = zend_std_get_properties(obj TSRMLS_CC);
1.1       misho     171:        int  i = 0;
                    172: 
1.1.1.3   misho     173:        if (intern->array) {
1.1.1.2   misho     174:                int j = zend_hash_num_elements(ht);
1.1       misho     175: 
                    176:                for (i = 0; i < intern->array->size; i++) {
                    177:                        if (intern->array->elements[i]) {
1.1.1.2   misho     178:                                zend_hash_index_update(ht, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL);
1.1       misho     179:                                Z_ADDREF_P(intern->array->elements[i]);
                    180:                        } else {
1.1.1.2   misho     181:                                zend_hash_index_update(ht, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL);
1.1       misho     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) {
1.1.1.2   misho     187:                                zend_hash_index_del(ht, i);
1.1       misho     188:                        }
                    189:                }
                    190:        }
                    191: 
1.1.1.2   misho     192:        return ht;
1.1       misho     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);
1.1.1.2   misho     235:        object_properties_init(&intern->std, class_type);
1.1       misho     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;
1.1.1.3   misho     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:                }
1.1       misho     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;
1.1.1.3   misho     381:                if (!offset) {
                    382:                        ALLOC_INIT_ZVAL(offset);
                    383:                } else {
                    384:                        SEPARATE_ARG_IF_REF(offset);
                    385:                }
1.1       misho     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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size)) {
                    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: 
1.1.1.4 ! misho     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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
        !           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: 
1.1       misho     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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
                    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: {
1.1.1.3   misho     662:        spl_fixedarray_object *intern;
1.1       misho     663: 
                    664:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
                    665:                return;
                    666:        }
                    667: 
1.1.1.3   misho     668:        intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
1.1       misho     669: 
1.1.1.3   misho     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:        }
1.1       misho     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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes)) {
                    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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
                    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 (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size)) {
                    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 int spl_fixedarray_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_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:                return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
                    958:        } else {
                    959:                *int_key = (ulong) iterator->object->current;
                    960:                return HASH_KEY_IS_LONG;
                    961:        }
                    962: 
                    963: }
                    964: /* }}} */
                    965: 
                    966: static void spl_fixedarray_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
                    967: {
                    968:        spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
                    969:        spl_fixedarray_object *intern   = iterator->object;
                    970: 
                    971:        if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_NEXT) {
                    972:                zend_user_it_move_forward(iter TSRMLS_CC);
                    973:        } else {
                    974:                zend_user_it_invalidate_current(iter TSRMLS_CC);
                    975:                iterator->object->current++;
                    976:        }
                    977: }
                    978: /* }}} */
                    979: 
                    980: /* {{{  proto int SplFixedArray::key() U
                    981:    Return current array key */
                    982: SPL_METHOD(SplFixedArray, key)
                    983: {
                    984:        spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
                    985:        
                    986:        if (zend_parse_parameters_none() == FAILURE) {
                    987:                return;
                    988:        }
                    989: 
                    990:        RETURN_LONG(intern->current);
                    991: }
                    992: /* }}} */
                    993: 
                    994: /* {{{ proto void SplFixedArray::next() U
                    995:    Move to next entry */
                    996: SPL_METHOD(SplFixedArray, next)
                    997: {
                    998:        spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
                    999:        
                   1000:        if (zend_parse_parameters_none() == FAILURE) {
                   1001:                return;
                   1002:        }
                   1003: 
                   1004:        intern->current++;
                   1005: }
                   1006: /* }}} */
                   1007: 
                   1008: /* {{{ proto bool SplFixedArray::valid() U
                   1009:    Check whether the datastructure contains more entries */
                   1010: SPL_METHOD(SplFixedArray, valid)
                   1011: {
                   1012:        spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
                   1013:        
                   1014:        if (zend_parse_parameters_none() == FAILURE) {
                   1015:                return;
                   1016:        }
                   1017: 
                   1018:        RETURN_BOOL(intern->current >= 0 && intern->array && intern->current < intern->array->size);
                   1019: }
                   1020: /* }}} */
                   1021: 
                   1022: /* {{{ proto void SplFixedArray::rewind() U
                   1023:    Rewind the datastructure back to the start */
                   1024: SPL_METHOD(SplFixedArray, rewind)
                   1025: {
                   1026:        spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
                   1027:        
                   1028:        if (zend_parse_parameters_none() == FAILURE) {
                   1029:                return;
                   1030:        }
                   1031: 
                   1032:        intern->current = 0;
                   1033: }
                   1034: /* }}} */
                   1035: 
                   1036: /* {{{ proto mixed|NULL SplFixedArray::current() U
                   1037:    Return current datastructure entry */
                   1038: SPL_METHOD(SplFixedArray, current)
                   1039: {
                   1040:        zval                 *zindex, **value_pp;
                   1041:        spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
                   1042:        
                   1043:        if (zend_parse_parameters_none() == FAILURE) {
                   1044:                return;
                   1045:        }
                   1046: 
                   1047:        ALLOC_INIT_ZVAL(zindex);
                   1048:        ZVAL_LONG(zindex, intern->current);
                   1049: 
                   1050:        value_pp  = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
                   1051: 
                   1052:        zval_ptr_dtor(&zindex);
                   1053: 
                   1054:        if (value_pp) {
                   1055:                RETURN_ZVAL(*value_pp, 1, 0);
                   1056:        }
                   1057:        RETURN_NULL();
                   1058: }
                   1059: /* }}} */
                   1060: 
                   1061: /* iterator handler table */
                   1062: zend_object_iterator_funcs spl_fixedarray_it_funcs = {
                   1063:        spl_fixedarray_it_dtor,
                   1064:        spl_fixedarray_it_valid,
                   1065:        spl_fixedarray_it_get_current_data,
                   1066:        spl_fixedarray_it_get_current_key,
                   1067:        spl_fixedarray_it_move_forward,
                   1068:        spl_fixedarray_it_rewind
                   1069: };
                   1070: 
                   1071: zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
                   1072: {
                   1073:        spl_fixedarray_it      *iterator;
                   1074:        spl_fixedarray_object  *fixedarray_object = (spl_fixedarray_object*)zend_object_store_get_object(object TSRMLS_CC);
                   1075: 
                   1076:        if (by_ref) {
                   1077:                zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
                   1078:                return NULL;
                   1079:        }
                   1080: 
                   1081:        Z_ADDREF_P(object);
                   1082: 
                   1083:        iterator                     = emalloc(sizeof(spl_fixedarray_it));
                   1084:        iterator->intern.it.data     = (void*)object;
                   1085:        iterator->intern.it.funcs    = &spl_fixedarray_it_funcs;
                   1086:        iterator->intern.ce          = ce;
                   1087:        iterator->intern.value       = NULL;
                   1088:        iterator->object             = fixedarray_object;
                   1089: 
                   1090:        return (zend_object_iterator*)iterator;
                   1091: }
                   1092: /* }}} */
                   1093: 
                   1094: ZEND_BEGIN_ARG_INFO_EX(arginfo_splfixedarray_construct, 0, 0, 0)
                   1095:        ZEND_ARG_INFO(0, size)
                   1096: ZEND_END_ARG_INFO()
                   1097: 
                   1098: ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetGet, 0, 0, 1)
                   1099:        ZEND_ARG_INFO(0, index)
                   1100: ZEND_END_ARG_INFO()
                   1101: 
                   1102: ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetSet, 0, 0, 2)
                   1103:        ZEND_ARG_INFO(0, index)
                   1104:        ZEND_ARG_INFO(0, newval)
                   1105: ZEND_END_ARG_INFO()
                   1106: 
                   1107: ZEND_BEGIN_ARG_INFO(arginfo_fixedarray_setSize, 0)
                   1108:        ZEND_ARG_INFO(0, value)
                   1109: ZEND_END_ARG_INFO()
                   1110: 
                   1111: ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_fromArray, 0, 0, 1)
                   1112:        ZEND_ARG_INFO(0, data)
                   1113:        ZEND_ARG_INFO(0, save_indexes)
                   1114: ZEND_END_ARG_INFO()
                   1115: 
                   1116: ZEND_BEGIN_ARG_INFO(arginfo_splfixedarray_void, 0)
                   1117: ZEND_END_ARG_INFO()
                   1118: 
                   1119: static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
                   1120:        SPL_ME(SplFixedArray, __construct,     arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC)
1.1.1.4 ! misho    1121:        SPL_ME(SplFixedArray, __wakeup,        arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
1.1       misho    1122:        SPL_ME(SplFixedArray, count,           arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1123:        SPL_ME(SplFixedArray, toArray,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1124:        SPL_ME(SplFixedArray, fromArray,       arginfo_fixedarray_fromArray,   ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
                   1125:        SPL_ME(SplFixedArray, getSize,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1126:        SPL_ME(SplFixedArray, setSize,         arginfo_fixedarray_setSize,     ZEND_ACC_PUBLIC)
                   1127:        SPL_ME(SplFixedArray, offsetExists,    arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
                   1128:        SPL_ME(SplFixedArray, offsetGet,       arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
                   1129:        SPL_ME(SplFixedArray, offsetSet,       arginfo_fixedarray_offsetSet,   ZEND_ACC_PUBLIC)
                   1130:        SPL_ME(SplFixedArray, offsetUnset,     arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
                   1131:        SPL_ME(SplFixedArray, rewind,          arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1132:        SPL_ME(SplFixedArray, current,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1133:        SPL_ME(SplFixedArray, key,             arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1134:        SPL_ME(SplFixedArray, next,            arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1135:        SPL_ME(SplFixedArray, valid,           arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
                   1136:        PHP_FE_END
                   1137: };
                   1138: /* }}} */
                   1139: 
                   1140: /* {{{ PHP_MINIT_FUNCTION */
                   1141: PHP_MINIT_FUNCTION(spl_fixedarray)
                   1142: {
                   1143:        REGISTER_SPL_STD_CLASS_EX(SplFixedArray, spl_fixedarray_new, spl_funcs_SplFixedArray);
                   1144:        memcpy(&spl_handler_SplFixedArray, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
                   1145: 
                   1146:        spl_handler_SplFixedArray.clone_obj       = spl_fixedarray_object_clone;
                   1147:        spl_handler_SplFixedArray.read_dimension  = spl_fixedarray_object_read_dimension;
                   1148:        spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension;
                   1149:        spl_handler_SplFixedArray.unset_dimension = spl_fixedarray_object_unset_dimension;
                   1150:        spl_handler_SplFixedArray.has_dimension   = spl_fixedarray_object_has_dimension;
                   1151:        spl_handler_SplFixedArray.count_elements  = spl_fixedarray_object_count_elements;
                   1152:        spl_handler_SplFixedArray.get_properties  = spl_fixedarray_object_get_properties;
1.1.1.3   misho    1153:        spl_handler_SplFixedArray.get_gc          = spl_fixedarray_object_get_gc;
1.1       misho    1154: 
                   1155:        REGISTER_SPL_IMPLEMENTS(SplFixedArray, Iterator);
                   1156:        REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess);
                   1157:        REGISTER_SPL_IMPLEMENTS(SplFixedArray, Countable);
                   1158: 
                   1159:        spl_ce_SplFixedArray->get_iterator = spl_fixedarray_get_iterator;
                   1160: 
                   1161:        return SUCCESS;
                   1162: }
                   1163: /* }}} */
                   1164: 
                   1165: 
                   1166: /*
                   1167:  * Local variables:
                   1168:  * tab-width: 4
                   1169:  * c-basic-offset: 4
                   1170:  * End:
                   1171:  * vim600: noet sw=4 ts=4 fdm=marker
                   1172:  * vim<600: noet sw=4 ts=4
                   1173:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>