summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Kneuss <colder@php.net>2008-07-13 15:59:38 +0000
committerEtienne Kneuss <colder@php.net>2008-07-13 15:59:38 +0000
commitb111b673e695c06f13e1e7df6bbfaf5de0362dc9 (patch)
tree89d1f539a2defc6810679ab81844635a8efd1ffd
parent102ab5c862e601c30867efc925cd510fca91e1df (diff)
downloadphp-git-b111b673e695c06f13e1e7df6bbfaf5de0362dc9.tar.gz
Implement toArray,fromArray and get_properties (Thanks Tony for the patches)
-rw-r--r--ext/spl/spl_fixedarray.c162
-rw-r--r--ext/spl/tests/fixedarray_016.phpt13
-rw-r--r--ext/spl/tests/fixedarray_017.phpt13
-rw-r--r--ext/spl/tests/fixedarray_018.phpt2
-rw-r--r--ext/spl/tests/fixedarray_019.phpt2
-rw-r--r--ext/spl/tests/fixedarray_020.phpt36
6 files changed, 178 insertions, 50 deletions
diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c
index 3fa03d587e..3bf7017ce4 100644
--- a/ext/spl/spl_fixedarray.c
+++ b/ext/spl/spl_fixedarray.c
@@ -145,46 +145,24 @@ static void spl_fixedarray_copy(spl_fixedarray *to, spl_fixedarray *from TSRMLS_
}
/* }}} */
-static HashTable* spl_fixedarray_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */
+static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {{{{ */
{
spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC);
- HashTable *rv;
- zval *tmp, zrv, *fixedarray_array;
- zstr pnstr;
- int pnlen;
int i = 0;
- *is_temp = 1;
-
- ALLOC_HASHTABLE(rv);
- ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0);
-
- INIT_PZVAL(&zrv);
- Z_ARRVAL(zrv) = rv;
-
- zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-
- ALLOC_INIT_ZVAL(fixedarray_array);
- array_init(fixedarray_array);
-
-
if (intern->array) {
for (i = 0; i < intern->array->size; i++) {
if (intern->array->elements[i]) {
- add_index_zval(fixedarray_array, i, (zval *)intern->array->elements[i]);
+ zend_hash_index_update(intern->std.properties, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL);
Z_ADDREF_P(intern->array->elements[i]);
} else {
- add_index_zval(fixedarray_array, i, (zval *)EG(uninitialized_zval_ptr));
+ zend_hash_index_update(intern->std.properties, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL);
Z_ADDREF_P(EG(uninitialized_zval_ptr));
}
}
}
- pnstr = spl_gen_private_prop_name(spl_ce_SplFixedArray, "array", sizeof("array")-1, &pnlen TSRMLS_CC);
- add_u_assoc_zval_ex(&zrv, ZEND_STR_TYPE, pnstr, pnlen+1, fixedarray_array);
- efree(pnstr.v);
-
- return rv;
+ return intern->std.properties;
}
/* }}}} */
@@ -586,6 +564,118 @@ SPL_METHOD(SplFixedArray, count)
}
/* }}} */
+/* {{{ proto object SplFixedArray::toArray()
+*/
+SPL_METHOD(SplFixedArray, toArray)
+{
+ spl_fixedarray_object *intern;
+ zval *ret, *tmp;
+ HashTable *ret_ht, *obj_ht;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
+ return;
+ }
+
+ intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ ALLOC_HASHTABLE(ret_ht);
+ zend_hash_init(ret_ht, 0, NULL, ZVAL_PTR_DTOR, 0);
+ ALLOC_INIT_ZVAL(ret);
+ Z_TYPE_P(ret) = IS_ARRAY;
+ obj_ht = spl_fixedarray_object_get_properties(getThis() TSRMLS_CC);
+ zend_hash_copy(ret_ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+ Z_ARRVAL_P(ret) = ret_ht;
+
+ RETURN_ZVAL(ret, 1, 1);
+}
+/* }}} */
+
+/* {{{ proto object SplFixedArray::fromArray(array data[, bool save_indexes])
+*/
+SPL_METHOD(SplFixedArray, fromArray)
+{
+ zval *data;
+ spl_fixedarray *array;
+ spl_fixedarray_object *intern;
+ int num;
+ zend_bool save_indexes = 1;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes)) {
+ return;
+ }
+
+ array = ecalloc(1, sizeof(*array));
+ num = zend_hash_num_elements(Z_ARRVAL_P(data));
+
+ if (num > 0 && save_indexes) {
+ zval **element, *value;
+ zstr str_index;
+ ulong num_index, max_index = 0;
+ long tmp;
+
+ for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
+ zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+ zend_hash_move_forward(Z_ARRVAL_P(data))
+ ) {
+ if (zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0) != HASH_KEY_IS_LONG || (long)num_index < 0) {
+ efree(array);
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array must contain only positive integer keys");
+ return;
+ }
+
+ if (num_index > max_index) {
+ max_index = num_index;
+ }
+ }
+
+ tmp = max_index + 1;
+ if (tmp <= 0) {
+ efree(array);
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "integer overflow detected");
+ return;
+ }
+ spl_fixedarray_init(array, tmp TSRMLS_CC);
+
+ for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
+ zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+ zend_hash_move_forward(Z_ARRVAL_P(data))
+ ) {
+
+ zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0);
+ value = *element;
+
+ SEPARATE_ARG_IF_REF(value);
+ array->elements[num_index] = value;
+ }
+
+ } else if (num > 0 && !save_indexes) {
+ zval **element, *value;
+ long i = 0;
+
+ spl_fixedarray_init(array, num TSRMLS_CC);
+
+ for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
+ zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+ zend_hash_move_forward(Z_ARRVAL_P(data))
+ ) {
+
+ value = *element;
+
+ SEPARATE_ARG_IF_REF(value);
+ array->elements[i] = value;
+ i++;
+ }
+ } else {
+ spl_fixedarray_init(array, 0 TSRMLS_CC);
+ }
+
+ object_init_ex(return_value, spl_ce_SplFixedArray);
+ Z_TYPE_P(return_value) = IS_OBJECT;
+
+ intern = (spl_fixedarray_object *)zend_object_store_get_object(return_value TSRMLS_CC);
+ intern->array = array;
+}
+
/* {{{ proto int SplFixedArray::getSize(void)
*/
SPL_METHOD(SplFixedArray, getSize)
@@ -936,15 +1026,23 @@ ZEND_BEGIN_ARG_INFO(arginfo_fixedarray_setSize, 0)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_fromArray, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, save_indexes)
+ZEND_END_ARG_INFO()
+
static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
SPL_ME(SplFixedArray, __construct, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, count, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, toArray, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, fromArray, arginfo_fixedarray_fromArray, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
SPL_ME(SplFixedArray, getSize, NULL, ZEND_ACC_PUBLIC)
- SPL_ME(SplFixedArray, setSize, arginfo_fixedarray_setSize, ZEND_ACC_PUBLIC)
- SPL_ME(SplFixedArray, offsetExists, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
- SPL_ME(SplFixedArray, offsetGet, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
- SPL_ME(SplFixedArray, offsetSet, arginfo_fixedarray_offsetSet, ZEND_ACC_PUBLIC)
- SPL_ME(SplFixedArray, offsetUnset, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, setSize, arginfo_fixedarray_setSize, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, offsetExists, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, offsetGet, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, offsetSet, arginfo_fixedarray_offsetSet, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, offsetUnset, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, rewind, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, current, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, key, NULL, ZEND_ACC_PUBLIC)
@@ -966,7 +1064,7 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
spl_handler_SplFixedArray.unset_dimension = spl_fixedarray_object_unset_dimension;
spl_handler_SplFixedArray.has_dimension = spl_fixedarray_object_has_dimension;
spl_handler_SplFixedArray.count_elements = spl_fixedarray_object_count_elements;
- spl_handler_SplFixedArray.get_debug_info = spl_fixedarray_object_get_debug_info;
+ spl_handler_SplFixedArray.get_properties = spl_fixedarray_object_get_properties;
REGISTER_SPL_IMPLEMENTS(SplFixedArray, Iterator);
REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess);
diff --git a/ext/spl/tests/fixedarray_016.phpt b/ext/spl/tests/fixedarray_016.phpt
index b22b79863b..26c5c4e373 100644
--- a/ext/spl/tests/fixedarray_016.phpt
+++ b/ext/spl/tests/fixedarray_016.phpt
@@ -9,12 +9,9 @@ var_dump(empty($a[0]), empty($a[1]), $a);
--EXPECTF--
bool(false)
bool(true)
-object(SplFixedArray)#1 (1) {
- [u"array":u"SplFixedArray":private]=>
- array(2) {
- [0]=>
- unicode(3) "foo"
- [1]=>
- NULL
- }
+object(SplFixedArray)#%d (2) {
+ [0]=>
+ unicode(3) "foo"
+ [1]=>
+ NULL
}
diff --git a/ext/spl/tests/fixedarray_017.phpt b/ext/spl/tests/fixedarray_017.phpt
index b22b79863b..26c5c4e373 100644
--- a/ext/spl/tests/fixedarray_017.phpt
+++ b/ext/spl/tests/fixedarray_017.phpt
@@ -9,12 +9,9 @@ var_dump(empty($a[0]), empty($a[1]), $a);
--EXPECTF--
bool(false)
bool(true)
-object(SplFixedArray)#1 (1) {
- [u"array":u"SplFixedArray":private]=>
- array(2) {
- [0]=>
- unicode(3) "foo"
- [1]=>
- NULL
- }
+object(SplFixedArray)#%d (2) {
+ [0]=>
+ unicode(3) "foo"
+ [1]=>
+ NULL
}
diff --git a/ext/spl/tests/fixedarray_018.phpt b/ext/spl/tests/fixedarray_018.phpt
index 4965bb5279..f293967453 100644
--- a/ext/spl/tests/fixedarray_018.phpt
+++ b/ext/spl/tests/fixedarray_018.phpt
@@ -1,5 +1,5 @@
--TEST--
-SPL: SplFixedArray with overriden count()
+SPL: FixedArray: with overriden count()
--FILE--
<?php
$obj = new SplFixedArray(2);
diff --git a/ext/spl/tests/fixedarray_019.phpt b/ext/spl/tests/fixedarray_019.phpt
index e8537cabd7..5e3c356e63 100644
--- a/ext/spl/tests/fixedarray_019.phpt
+++ b/ext/spl/tests/fixedarray_019.phpt
@@ -1,5 +1,5 @@
--TEST--
-SPL: SplFixedArray with overriden iterator methods
+SPL: FixedArray: with overriden iterator methods
--FILE--
<?php
class SplFixedArray2 extends SplFixedArray {
diff --git a/ext/spl/tests/fixedarray_020.phpt b/ext/spl/tests/fixedarray_020.phpt
new file mode 100644
index 0000000000..c0ff6e3b43
--- /dev/null
+++ b/ext/spl/tests/fixedarray_020.phpt
@@ -0,0 +1,36 @@
+--TEST--
+SPL: FixedArray: fromArray/toArray + get_properties
+--FILE--
+<?php
+$a = array(1=>'foo', 2=>'bar', 0=>'gee');
+$fa = SplFixedArray::fromArray($a, false);
+var_dump(count($fa), $fa->toArray() === array_values($a));
+
+$fa = SplFixedArray::fromArray($a, true);
+var_dump(count($fa), $fa->toArray() === $a, $fa->toArray() === (array)$fa);
+
+try {
+ echo "From Array with string keys, no preserve\n";
+ SplFixedArray::fromArray(array("foo"=>"bar"), false);
+ echo "No exception\n";
+} catch (Exception $e) {
+ echo "Exception: ".$e->getMessage()."\n";
+}
+try {
+ echo "From Array with string keys, preserve\n";
+ SplFixedArray::fromArray(array("foo"=>"bar"), true);
+ echo "No exception\n";
+} catch (Exception $e) {
+ echo "Exception: ".$e->getMessage()."\n";
+}
+?>
+--EXPECT--
+int(3)
+bool(true)
+int(3)
+bool(false)
+bool(true)
+From Array with string keys, no preserve
+No exception
+From Array with string keys, preserve
+Exception: array must contain only positive integer keys