169
void spl_object_storage_detach(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */
169
int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */
171
171
#if HAVE_PACKED_OBJECT_VALUE
172
zend_hash_del(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value));
172
return zend_hash_del(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value));
175
175
zend_object_value zvalue;
176
176
memset(&zvalue, 0, sizeof(zend_object_value));
177
177
zvalue.handle = Z_OBJ_HANDLE_P(obj);
178
178
zvalue.handlers = Z_OBJ_HT_P(obj);
179
zend_hash_del(&intern->storage, (char*)&zvalue, sizeof(zend_object_value));
179
return zend_hash_del(&intern->storage, (char*)&zvalue, sizeof(zend_object_value));
257
257
props = Z_OBJPROP_P(obj);
258
zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
258
260
if (intern->debug_info == NULL) {
259
261
ALLOC_HASHTABLE(intern->debug_info);
260
262
ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0);
269
271
zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
270
272
while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
271
273
php_spl_object_hash(element->obj, md5str TSRMLS_CC);
272
Z_ADDREF_P(element->obj);
273
Z_ADDREF_P(element->inf);
274
274
MAKE_STD_ZVAL(tmp);
276
/* Incrementing the refcount of obj and inf would confuse the garbage collector.
277
* Prefer to null the destructor */
278
Z_ARRVAL_P(tmp)->pDestructor = NULL;
276
279
add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj);
277
280
add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf);
278
281
add_assoc_zval_ex(storage, md5str, 33, tmp);
294
/* overriden for garbage collection
295
* This is very hacky, but unfortunately the garbage collector can only query objects for
296
* dependencies through get_properties */
297
static HashTable *spl_object_storage_get_properties(zval *obj TSRMLS_DC) /* {{{ */
299
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
300
spl_SplObjectStorageElement *element;
303
zval *gcdata_arr = NULL,
306
props = std_object_handlers.get_properties(obj TSRMLS_CC);
308
if (!GC_G(gc_active)) {
309
zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
313
if (props->nApplyCount > 0) {
317
/* clean \x00gcdata, as it may be out of date */
318
if (zend_hash_find(props, "\x00gcdata", sizeof("\x00gcdata"), (void**) &gcdata_arr_pp) == SUCCESS) {
319
gcdata_arr = *gcdata_arr_pp;
320
zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
323
if (gcdata_arr == NULL) {
324
MAKE_STD_ZVAL(gcdata_arr);
325
array_init(gcdata_arr);
326
/* don't decrease refcount of members when destroying */
327
Z_ARRVAL_P(gcdata_arr)->pDestructor = NULL;
329
/* name starts with \x00 to make tampering in user-land more difficult */
330
zend_hash_add(props, "\x00gcdata", sizeof("\x00gcdata"), &gcdata_arr, sizeof(gcdata_arr), NULL);
333
zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
334
while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
335
add_next_index_zval(gcdata_arr, element->obj);
336
add_next_index_zval(gcdata_arr, element->inf);
337
zend_hash_move_forward_ex(&intern->storage, &pos);
291
344
static int spl_object_storage_compare_info(spl_SplObjectStorageElement *e1, spl_SplObjectStorageElement *e2 TSRMLS_DC) /* {{{ */
412
465
spl_SplObjectStorage *intern = (spl_SplObjectStorage *)zend_object_store_get_object(getThis() TSRMLS_CC);
413
466
spl_SplObjectStorage *other;
414
467
spl_SplObjectStorageElement *element;
417
469
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, spl_ce_SplObjectStorage) == FAILURE) {
421
473
other = (spl_SplObjectStorage *)zend_object_store_get_object(obj TSRMLS_CC);
423
zend_hash_internal_pointer_reset_ex(&other->storage, &pos);
424
while (zend_hash_get_current_data_ex(&other->storage, (void **)&element, &pos) == SUCCESS) {
425
spl_object_storage_detach(intern, element->obj TSRMLS_CC);
426
zend_hash_move_forward_ex(&other->storage, &pos);
475
zend_hash_internal_pointer_reset(&other->storage);
476
while (zend_hash_get_current_data(&other->storage, (void **)&element) == SUCCESS) {
477
if (spl_object_storage_detach(intern, element->obj TSRMLS_CC) == FAILURE) {
478
zend_hash_move_forward(&other->storage);
429
482
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
489
558
spl_SplObjectStorageElement *element;
490
559
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
561
if (zend_parse_parameters_none() == FAILURE) {
492
565
if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
502
575
spl_SplObjectStorageElement *element;
503
576
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
578
if (zend_parse_parameters_none() == FAILURE) {
505
582
if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
550
631
php_serialize_data_t var_hash;
551
632
smart_str buf = {0};
634
if (zend_parse_parameters_none() == FAILURE) {
553
638
PHP_VAR_SERIALIZE_INIT(var_hash);
556
641
smart_str_appendl(&buf, "x:i:", 4);
557
642
smart_str_append_long(&buf, zend_hash_num_elements(&intern->storage));
799
884
SPL_METHOD(MultipleIterator, getFlags)
801
886
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
888
if (zend_parse_parameters_none() == FAILURE) {
802
891
RETURN_LONG(intern->flags);
864
953
intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
955
if (zend_parse_parameters_none() == FAILURE) {
866
959
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
867
960
while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
883
976
intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
978
if (zend_parse_parameters_none() == FAILURE) {
885
982
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
886
983
while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
1006
1107
spl_SplObjectStorage *intern;
1007
1108
intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
1110
if (zend_parse_parameters_none() == FAILURE) {
1009
1114
spl_multiple_iterator_get_all(intern, SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT, return_value TSRMLS_CC);
1017
1122
spl_SplObjectStorage *intern;
1018
1123
intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
1125
if (zend_parse_parameters_none() == FAILURE) {
1020
1129
spl_multiple_iterator_get_all(intern, SPL_MULTIPLE_ITERATOR_GET_ALL_KEY, return_value TSRMLS_CC);
1064
1173
REGISTER_SPL_STD_CLASS_EX(SplObjectStorage, spl_SplObjectStorage_new, spl_funcs_SplObjectStorage);
1065
1174
memcpy(&spl_handler_SplObjectStorage, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1176
spl_handler_SplObjectStorage.get_properties = spl_object_storage_get_properties;
1067
1177
spl_handler_SplObjectStorage.get_debug_info = spl_object_storage_debug_info;
1068
1178
spl_handler_SplObjectStorage.compare_objects = spl_object_storage_compare_objects;
1069
1179
spl_handler_SplObjectStorage.clone_obj = spl_object_storage_clone;