Implement ArrayAccess. Fix config.m4, .travis.yml. Update stubs.
This commit is contained in:
parent
dc4a1546eb
commit
7b98857eff
|
@ -14,5 +14,4 @@ script:
|
||||||
- phpize
|
- phpize
|
||||||
- ./configure
|
- ./configure
|
||||||
- make
|
- make
|
||||||
- echo $'n\n' | make test
|
- make test
|
||||||
- sudo make install
|
|
|
@ -1,15 +1,7 @@
|
||||||
PHP_ARG_ENABLE(collections, for collections support,
|
PHP_ARG_ENABLE(collections, for collections support,
|
||||||
[ --enable-collections Enable collections support])
|
[ --enable-collections Enable collections support])
|
||||||
|
|
||||||
PHP_ARG_ENABLE(collections-debug, for debug support,
|
|
||||||
[ --enable-collections-debug Compile with debug symbols], no, no)
|
|
||||||
|
|
||||||
if test "$PHP_COLLECTIONS" != "no"; then
|
if test "$PHP_COLLECTIONS" != "no"; then
|
||||||
if test "$PHP_COLLECTIONS_DEBUG" != "no"; then
|
|
||||||
CFLAGS="-g -O0"
|
|
||||||
else
|
|
||||||
CFLAGS="-O2"
|
|
||||||
fi
|
|
||||||
COLLECTIONS_SRC="src/collections.c
|
COLLECTIONS_SRC="src/collections.c
|
||||||
src/collections_me.c
|
src/collections_me.c
|
||||||
src/collections_methods.c"
|
src/collections_methods.c"
|
||||||
|
|
|
@ -40,6 +40,10 @@ PHP_MINIT_FUNCTION(collections)
|
||||||
collection_handlers = (zend_object_handlers*)emalloc(sizeof(zend_object_handlers));
|
collection_handlers = (zend_object_handlers*)emalloc(sizeof(zend_object_handlers));
|
||||||
memcpy(collection_handlers, &std_object_handlers, sizeof(zend_object_handlers));
|
memcpy(collection_handlers, &std_object_handlers, sizeof(zend_object_handlers));
|
||||||
collection_handlers->count_elements = count_collection;
|
collection_handlers->count_elements = count_collection;
|
||||||
|
collection_handlers->unset_dimension = collection_offset_unset;
|
||||||
|
collection_handlers->write_dimension = collection_offset_set;
|
||||||
|
collection_handlers->read_dimension = collection_offset_get;
|
||||||
|
collection_handlers->has_dimension = collection_offset_exists;
|
||||||
zend_class_entry pair_ce;
|
zend_class_entry pair_ce;
|
||||||
INIT_CLASS_ENTRY_EX(pair_ce, "Pair", sizeof "Pair" - 1, pair_methods);
|
INIT_CLASS_ENTRY_EX(pair_ce, "Pair", sizeof "Pair" - 1, pair_methods);
|
||||||
collections_pair_ce = zend_register_internal_class(&pair_ce);
|
collections_pair_ce = zend_register_internal_class(&pair_ce);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
|
|
||||||
#include "php_collections.h"
|
|
||||||
#include "php_collections_me.h"
|
#include "php_collections_me.h"
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(action_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(action_arginfo, 0)
|
||||||
|
@ -40,10 +39,6 @@ ZEND_BEGIN_ARG_INFO(initial_operation_arginfo, 0)
|
||||||
ZEND_ARG_CALLABLE_INFO(0, operation, 0)
|
ZEND_ARG_CALLABLE_INFO(0, operation, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(key_arginfo, 0)
|
|
||||||
ZEND_ARG_INFO(0, key)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(keys_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(keys_arginfo, 0)
|
||||||
ZEND_ARG_INFO(0, keys)
|
ZEND_ARG_INFO(0, keys)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
@ -86,6 +81,10 @@ ZEND_BEGIN_ARG_INFO(associate_by_to_arginfo, 0)
|
||||||
ZEND_ARG_CALLABLE_INFO(0, key_selector, 0)
|
ZEND_ARG_CALLABLE_INFO(0, key_selector, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
|
ZEND_BEGIN_ARG_INFO(contains_key_arginfo, 0)
|
||||||
|
ZEND_ARG_INFO(0, key)
|
||||||
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(copy_of_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(copy_of_arginfo, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, new_size, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, new_size, IS_LONG, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
@ -132,7 +131,7 @@ const zend_function_entry collection_methods[] = {
|
||||||
PHP_ME(Collection, associateByTo, associate_by_to_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, associateByTo, associate_by_to_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, average, NULL, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, average, NULL, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, containsAll, other_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, containsAll, other_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, containsKey, key_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, containsKey, contains_key_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, containsValue, element_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, containsValue, element_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, copyOf, copy_of_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, copyOf, copy_of_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, copyOfRange, copy_of_range_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, copyOfRange, copy_of_range_arginfo, ZEND_ACC_PUBLIC)
|
||||||
|
@ -189,9 +188,6 @@ const zend_function_entry collection_methods[] = {
|
||||||
PHP_ME(Collection, minusValues, elements_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, minusValues, elements_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, minusValuesAssign, elements_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, minusValuesAssign, elements_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, none, predicate_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, none, predicate_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, offsetUnset, key_arginfo, ZEND_ACC_PUBLIC)
|
|
||||||
PHP_ME(Collection, offsetSet, key_value_arginfo, ZEND_ACC_PUBLIC)
|
|
||||||
PHP_ME(Collection, offsetExists, key_arginfo, ZEND_ACC_PUBLIC)
|
|
||||||
PHP_ME(Collection, onEach, action_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, onEach, action_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, orEmpty, NULL, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, orEmpty, NULL, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, partition, predicate_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, partition, predicate_arginfo, ZEND_ACC_PUBLIC)
|
||||||
|
|
|
@ -111,6 +111,54 @@ int count_collection(zval* obj, zend_long* count)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int collection_offset_exists(zval* object, zval* offset, int check_empty)
|
||||||
|
{
|
||||||
|
zval rv;
|
||||||
|
zval* current = COLLECTION_FETCH(object);
|
||||||
|
if (check_empty)
|
||||||
|
return zend_hash_num_elements(Z_ARRVAL_P(current)) == 0;
|
||||||
|
if (Z_TYPE_P(offset) == IS_LONG)
|
||||||
|
return zend_hash_index_exists(Z_ARRVAL_P(current), Z_LVAL_P(offset));
|
||||||
|
if (Z_TYPE_P(offset) == IS_STRING)
|
||||||
|
return zend_hash_exists(Z_ARRVAL_P(current), Z_STR_P(offset));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void collection_offset_set(zval* object, zval* offset, zval* value)
|
||||||
|
{
|
||||||
|
zval rv;
|
||||||
|
zval* current = COLLECTION_FETCH(object);
|
||||||
|
if (Z_TYPE_P(offset) == IS_LONG)
|
||||||
|
zend_hash_index_update(Z_ARRVAL_P(current), Z_LVAL_P(offset), value);
|
||||||
|
else if (Z_TYPE_P(offset) == IS_STRING)
|
||||||
|
zend_hash_update(Z_ARRVAL_P(current), Z_STR_P(offset), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
zval* collection_offset_get(zval* object, zval* offset, int type, zval* retval)
|
||||||
|
{
|
||||||
|
// Note that we don't handler type. So don't do any fancy things with Collection
|
||||||
|
// such as fetching a reference of a value, etc.
|
||||||
|
zval rv;
|
||||||
|
zval* current = COLLECTION_FETCH(object);
|
||||||
|
zval* found = NULL;
|
||||||
|
if (Z_TYPE_P(offset) == IS_LONG)
|
||||||
|
found = zend_hash_index_find(Z_ARRVAL_P(current), Z_LVAL_P(offset));
|
||||||
|
else if (Z_TYPE_P(offset) == IS_STRING)
|
||||||
|
found = zend_hash_find(Z_ARRVAL_P(current), Z_STR_P(offset));
|
||||||
|
ZVAL_COPY(retval, found);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void collection_offset_unset(zval* object, zval* offset)
|
||||||
|
{
|
||||||
|
zval rv;
|
||||||
|
zval* current = COLLECTION_FETCH(object);
|
||||||
|
if (Z_TYPE_P(offset) == IS_LONG)
|
||||||
|
zend_hash_index_del(Z_ARRVAL_P(current), Z_LVAL_P(offset));
|
||||||
|
else if (Z_TYPE_P(offset) == IS_STRING)
|
||||||
|
zend_hash_del(Z_ARRVAL_P(current), Z_STR_P(offset));
|
||||||
|
}
|
||||||
|
|
||||||
PHP_METHOD(Collection, __construct) {}
|
PHP_METHOD(Collection, __construct) {}
|
||||||
|
|
||||||
PHP_METHOD(Collection, addAll)
|
PHP_METHOD(Collection, addAll)
|
||||||
|
@ -702,26 +750,6 @@ PHP_METHOD(Collection, none)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PHP_METHOD(Collection, offsetUnset)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PHP_METHOD(Collection, offsetSet)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PHP_METHOD(Collection, offsetGet)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PHP_METHOD(Collection, offsetExists)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PHP_METHOD(Collection, onEach)
|
PHP_METHOD(Collection, onEach)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ extern zend_module_entry collections_module_entry;
|
||||||
#define PHP_COLLECTIONS_API
|
#define PHP_COLLECTIONS_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PHP_VERSION_ID < 70300
|
#if PHP_VERSION_ID < 70300
|
||||||
#define GC_ADDREF(p) ++GC_REFCOUNT(p)
|
#define GC_ADDREF(p) ++GC_REFCOUNT(p)
|
||||||
#define GC_DELREF(p) --GC_REFCOUNT(p)
|
#define GC_DELREF(p) --GC_REFCOUNT(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern zend_string* collection_property_name;
|
extern zend_string* collection_property_name;
|
||||||
|
@ -35,6 +35,10 @@ extern PHP_COLLECTIONS_API zend_class_entry* collections_pair_ce;
|
||||||
extern zend_object_handlers* collection_handlers;
|
extern zend_object_handlers* collection_handlers;
|
||||||
|
|
||||||
int count_collection(zval* obj, zend_long* count);
|
int count_collection(zval* obj, zend_long* count);
|
||||||
|
int collection_offset_exists(zval* object, zval* offset, int check_empty);
|
||||||
|
void collection_offset_set(zval* object, zval* offset, zval* value);
|
||||||
|
zval* collection_offset_get(zval* object, zval* offset, int type, zval* rv);
|
||||||
|
void collection_offset_unset(zval* object, zval* offset);
|
||||||
|
|
||||||
extern const zend_function_entry collection_methods[];
|
extern const zend_function_entry collection_methods[];
|
||||||
extern const zend_function_entry pair_methods[];
|
extern const zend_function_entry pair_methods[];
|
||||||
|
|
|
@ -74,10 +74,6 @@ PHP_METHOD(Collection, minusKeysAssign);
|
||||||
PHP_METHOD(Collection, minusValues);
|
PHP_METHOD(Collection, minusValues);
|
||||||
PHP_METHOD(Collection, minusValuesAssign);
|
PHP_METHOD(Collection, minusValuesAssign);
|
||||||
PHP_METHOD(Collection, none);
|
PHP_METHOD(Collection, none);
|
||||||
PHP_METHOD(Collection, offsetUnset);
|
|
||||||
PHP_METHOD(Collection, offsetSet);
|
|
||||||
PHP_METHOD(Collection, offsetGet);
|
|
||||||
PHP_METHOD(Collection, offsetExists);
|
|
||||||
PHP_METHOD(Collection, onEach);
|
PHP_METHOD(Collection, onEach);
|
||||||
PHP_METHOD(Collection, orEmpty);
|
PHP_METHOD(Collection, orEmpty);
|
||||||
PHP_METHOD(Collection, partition);
|
PHP_METHOD(Collection, partition);
|
||||||
|
|
|
@ -581,21 +581,33 @@ class Collection implements ArrayAccess, Countable
|
||||||
function none($predicate) {}
|
function none($predicate) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is implemented in handlers.unset_dimension.
|
||||||
|
* There's no method with name 'offsetUnset'.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
function offsetUnset($key) {}
|
function offsetUnset($key) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is implemented in handlers.write_dimension.
|
||||||
|
* There's no method with name 'offsetSet'.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
function offsetSet($key, $value) {}
|
function offsetSet($key, $value) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is implemented in handlers.read_dimension.
|
||||||
|
* There's no method with name 'offsetGet'.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
function offsetGet($key) {}
|
function offsetGet($key) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is implemented in handlers.has_dimension.
|
||||||
|
* There's no method with name 'offsetExists'.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
function offsetExists($key) {}
|
function offsetExists($key) {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--TEST--
|
--TEST--
|
||||||
Test Collection::count() and countable interface.
|
Test Collection::count() and implementation of interface Countable.
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$array = [1, 2, 3, 4, 5, 6];
|
$array = [1, 2, 3, 4, 5, 6];
|
||||||
|
@ -7,6 +7,6 @@ $collection = Collection::init($array);
|
||||||
if ($collection->count() != count($array))
|
if ($collection->count() != count($array))
|
||||||
echo 'Collection::count() failed.', PHP_EOL;
|
echo 'Collection::count() failed.', PHP_EOL;
|
||||||
if (count($collection) != count($array))
|
if (count($collection) != count($array))
|
||||||
echo 'Test for countable interface failed.', PHP_EOL;
|
echo 'Test for handlers.count_elements failed.', PHP_EOL;
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
--TEST--
|
||||||
|
Test implementation of interface ArrayAccess.
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$array = ['a' => 'b', 'c' => 'd', 'e' => ['f' => 'g']];
|
||||||
|
$collection = Collection::init($array);
|
||||||
|
$collection['a'] = 'foo';
|
||||||
|
$collection['h'] = 'bar';
|
||||||
|
unset($collection['c']);
|
||||||
|
if (empty($collection) || isset($collection['t']) || !isset($collection['e']))
|
||||||
|
echo 'Test for handlers.has_dimension failed.', PHP_EOL;
|
||||||
|
if ($collection['e']['f'] != 'g')
|
||||||
|
echo 'Test for handlers.read_dimension failed.', PHP_EOL;
|
||||||
|
if ($collection['a'] != 'foo' || $collection['h'] != 'bar')
|
||||||
|
echo 'Test for handlers.write_dimension failed.', PHP_EOL;
|
||||||
|
if (isset($collection['c']))
|
||||||
|
echo 'Test for handlers.unset_dimension failed.', PHP_EOL;
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
Reference in New Issue