summaryrefslogtreecommitdiff
path: root/ext/spl/spl_observer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/spl_observer.c')
-rw-r--r--ext/spl/spl_observer.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index 462c638b25..e4342a8788 100644
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2017 The PHP Group |
+ | Copyright (c) 1997-2018 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -51,7 +51,7 @@ ZEND_END_ARG_INFO();
static const zend_function_entry spl_funcs_SplObserver[] = {
SPL_ABSTRACT_ME(SplObserver, update, arginfo_SplObserver_update)
- {NULL, NULL, NULL}
+ PHP_FE_END
};
ZEND_BEGIN_ARG_INFO(arginfo_SplSubject_attach, 0)
@@ -69,7 +69,7 @@ static const zend_function_entry spl_funcs_SplSubject[] = {
SPL_ABSTRACT_ME(SplSubject, attach, arginfo_SplSubject_attach)
SPL_ABSTRACT_ME(SplSubject, detach, arginfo_SplSubject_attach)
SPL_ABSTRACT_ME(SplSubject, notify, arginfo_SplSubject_void)
- {NULL, NULL, NULL}
+ PHP_FE_END
};
PHPAPI zend_class_entry *spl_ce_SplObserver;
@@ -117,32 +117,34 @@ void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */
} /* }}} */
-static zend_string *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this, zval *obj) {
+static int spl_object_storage_get_hash(zend_hash_key *key, spl_SplObjectStorage *intern, zval *this, zval *obj) {
if (intern->fptr_get_hash) {
zval rv;
zend_call_method_with_1_params(this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj);
if (!Z_ISUNDEF(rv)) {
if (Z_TYPE(rv) == IS_STRING) {
- return Z_STR(rv);
+ key->key = Z_STR(rv);
+ return SUCCESS;
} else {
zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0);
zval_ptr_dtor(&rv);
- return NULL;
+ return FAILURE;
}
} else {
- return NULL;
+ return FAILURE;
}
} else {
- zend_string *hash = zend_string_alloc(sizeof(zend_object*), 0);
- memcpy(ZSTR_VAL(hash), (void*)&Z_OBJ_P(obj), sizeof(zend_object*));
- ZSTR_VAL(hash)[ZSTR_LEN(hash)] = '\0';
- return hash;
+ key->key = NULL;
+ key->h = Z_OBJ_HANDLE_P(obj);
+ return SUCCESS;
}
}
-static void spl_object_storage_free_hash(spl_SplObjectStorage *intern, zend_string *hash) {
- zend_string_release(hash);
+static void spl_object_storage_free_hash(spl_SplObjectStorage *intern, zend_hash_key *key) {
+ if (key->key) {
+ zend_string_release(key->key);
+ }
}
static void spl_object_storage_dtor(zval *element) /* {{{ */
@@ -153,21 +155,24 @@ static void spl_object_storage_dtor(zval *element) /* {{{ */
efree(el);
} /* }}} */
-spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern, zend_string *hash) /* {{{ */
+static spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern, zend_hash_key *key) /* {{{ */
{
- return (spl_SplObjectStorageElement*)zend_hash_find_ptr(&intern->storage, hash);
+ if (key->key) {
+ return zend_hash_find_ptr(&intern->storage, key->key);
+ } else {
+ return zend_hash_index_find_ptr(&intern->storage, key->h);
+ }
} /* }}} */
spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *obj, zval *inf) /* {{{ */
{
spl_SplObjectStorageElement *pelement, element;
- zend_string *hash = spl_object_storage_get_hash(intern, this, obj);
-
- if (!hash) {
+ zend_hash_key key;
+ if (spl_object_storage_get_hash(&key, intern, this, obj) == FAILURE) {
return NULL;
}
- pelement = spl_object_storage_get(intern, hash);
+ pelement = spl_object_storage_get(intern, &key);
if (pelement) {
zval_ptr_dtor(&pelement->inf);
@@ -176,7 +181,7 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
} else {
ZVAL_NULL(&pelement->inf);
}
- spl_object_storage_free_hash(intern, hash);
+ spl_object_storage_free_hash(intern, &key);
return pelement;
}
@@ -186,20 +191,28 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
} else {
ZVAL_NULL(&element.inf);
}
- pelement = zend_hash_update_mem(&intern->storage, hash, &element, sizeof(spl_SplObjectStorageElement));
- spl_object_storage_free_hash(intern, hash);
+ if (key.key) {
+ pelement = zend_hash_update_mem(&intern->storage, key.key, &element, sizeof(spl_SplObjectStorageElement));
+ } else {
+ pelement = zend_hash_index_update_mem(&intern->storage, key.h, &element, sizeof(spl_SplObjectStorageElement));
+ }
+ spl_object_storage_free_hash(intern, &key);
return pelement;
} /* }}} */
-int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *this, zval *obj) /* {{{ */
+static int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *this, zval *obj) /* {{{ */
{
int ret = FAILURE;
- zend_string *hash = spl_object_storage_get_hash(intern, this, obj);
- if (!hash) {
+ zend_hash_key key;
+ if (spl_object_storage_get_hash(&key, intern, this, obj) == FAILURE) {
return ret;
}
- ret = zend_hash_del(&intern->storage, hash);
- spl_object_storage_free_hash(intern, hash);
+ if (key.key) {
+ ret = zend_hash_del(&intern->storage, key.key);
+ } else {
+ ret = zend_hash_index_del(&intern->storage, key.h);
+ }
+ spl_object_storage_free_hash(intern, &key);
return ret;
} /* }}}*/
@@ -369,13 +382,17 @@ static zend_object *spl_SplObjectStorage_new(zend_class_entry *class_type)
int spl_object_storage_contains(spl_SplObjectStorage *intern, zval *this, zval *obj) /* {{{ */
{
int found;
- zend_string *hash = spl_object_storage_get_hash(intern, this, obj);
- if (!hash) {
+ zend_hash_key key;
+ if (spl_object_storage_get_hash(&key, intern, this, obj) == FAILURE) {
return 0;
}
- found = zend_hash_exists(&intern->storage, hash);
- spl_object_storage_free_hash(intern, hash);
+ if (key.key) {
+ found = zend_hash_exists(&intern->storage, key.key);
+ } else {
+ found = zend_hash_index_exists(&intern->storage, key.h);
+ }
+ spl_object_storage_free_hash(intern, &key);
return found;
} /* }}} */
@@ -430,19 +447,18 @@ SPL_METHOD(SplObjectStorage, offsetGet)
zval *obj;
spl_SplObjectStorageElement *element;
spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(getThis());
- zend_string *hash;
+ zend_hash_key key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) {
return;
}
- hash = spl_object_storage_get_hash(intern, getThis(), obj);
- if (!hash) {
+ if (spl_object_storage_get_hash(&key, intern, getThis(), obj) == FAILURE) {
return;
}
- element = spl_object_storage_get(intern, hash);
- spl_object_storage_free_hash(intern, hash);
+ element = spl_object_storage_get(intern, &key);
+ spl_object_storage_free_hash(intern, &key);
if (!element) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Object not found");
@@ -777,7 +793,7 @@ SPL_METHOD(SplObjectStorage, unserialize)
while (count-- > 0) {
spl_SplObjectStorageElement *pelement;
- zend_string *hash;
+ zend_hash_key key;
if (*p != ';') {
goto outexcept;
@@ -803,14 +819,13 @@ SPL_METHOD(SplObjectStorage, unserialize)
goto outexcept;
}
- hash = spl_object_storage_get_hash(intern, getThis(), &entry);
- if (!hash) {
+ if (spl_object_storage_get_hash(&key, intern, getThis(), &entry) == FAILURE) {
zval_ptr_dtor(&entry);
zval_ptr_dtor(&inf);
goto outexcept;
}
- pelement = spl_object_storage_get(intern, hash);
- spl_object_storage_free_hash(intern, hash);
+ pelement = spl_object_storage_get(intern, &key);
+ spl_object_storage_free_hash(intern, &key);
if (pelement) {
if (!Z_ISUNDEF(pelement->inf)) {
var_push_dtor(&var_hash, &pelement->inf);
@@ -852,7 +867,7 @@ SPL_METHOD(SplObjectStorage, unserialize)
outexcept:
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
- zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Error at offset %pd of %d bytes", (zend_long)((char*)p - buf), buf_len);
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Error at offset %zd of %zd bytes", ((char*)p - buf), buf_len);
return;
} /* }}} */
@@ -911,7 +926,7 @@ static const zend_function_entry spl_funcs_SplObjectStorage[] = {
SPL_MA(SplObjectStorage, offsetSet, SplObjectStorage, attach, arginfo_attach, 0)
SPL_MA(SplObjectStorage, offsetUnset, SplObjectStorage, detach, arginfo_offsetGet, 0)
SPL_ME(SplObjectStorage, offsetGet, arginfo_offsetGet, 0)
- {NULL, NULL, NULL}
+ PHP_FE_END
};
typedef enum {
@@ -1220,7 +1235,7 @@ static const zend_function_entry spl_funcs_MultipleIterator[] = {
SPL_ME(MultipleIterator, key, arginfo_splobject_void, 0)
SPL_ME(MultipleIterator, current, arginfo_splobject_void, 0)
SPL_ME(MultipleIterator, next, arginfo_splobject_void, 0)
- {NULL, NULL, NULL}
+ PHP_FE_END
};
/* {{{ PHP_MINIT_FUNCTION(spl_observer) */