1 #include "../../common.h"
2
3 #include "../../ds/ds_vector.h"
4 #include "../objects/php_vector.h"
5 #include "php_vector_iterator.h"
6
php_ds_vector_iterator_dtor(zend_object_iterator * iter)7 static void php_ds_vector_iterator_dtor(zend_object_iterator *iter)
8 {
9 php_ds_vector_iterator_t *iterator = (php_ds_vector_iterator_t *) iter;
10
11 OBJ_RELEASE(iterator->object);
12 }
13
php_ds_vector_iterator_valid(zend_object_iterator * iter)14 static int php_ds_vector_iterator_valid(zend_object_iterator *iter)
15 {
16 php_ds_vector_iterator_t *iterator = (php_ds_vector_iterator_t *) iter;
17
18 return iterator->position < iterator->vector->size ? SUCCESS : FAILURE;
19 }
20
php_ds_vector_iterator_get_current_data(zend_object_iterator * iter)21 static zval *php_ds_vector_iterator_get_current_data(zend_object_iterator *iter)
22 {
23 php_ds_vector_iterator_t *iterator = (php_ds_vector_iterator_t *) iter;
24
25 return &iterator->vector->buffer[iterator->position];
26 }
27
php_ds_vector_iterator_get_current_key(zend_object_iterator * iter,zval * key)28 static void php_ds_vector_iterator_get_current_key(zend_object_iterator *iter, zval *key)
29 {
30 ZVAL_LONG(key, ((php_ds_vector_iterator_t *) iter)->position);
31 }
32
php_ds_vector_iterator_move_forward(zend_object_iterator * iter)33 static void php_ds_vector_iterator_move_forward(zend_object_iterator *iter)
34 {
35 ((php_ds_vector_iterator_t *) iter)->position++;
36 }
37
php_ds_vector_iterator_rewind(zend_object_iterator * iter)38 static void php_ds_vector_iterator_rewind(zend_object_iterator *iter)
39 {
40 ((php_ds_vector_iterator_t *) iter)->position = 0;
41 }
42
43 static zend_object_iterator_funcs php_ds_vector_iterator_funcs = {
44 php_ds_vector_iterator_dtor,
45 php_ds_vector_iterator_valid,
46 php_ds_vector_iterator_get_current_data,
47 php_ds_vector_iterator_get_current_key,
48 php_ds_vector_iterator_move_forward,
49 php_ds_vector_iterator_rewind
50 };
51
php_ds_vector_create_iterator(zval * obj,int by_ref)52 static zend_object_iterator *php_ds_vector_create_iterator(zval *obj, int by_ref)
53 {
54 php_ds_vector_iterator_t *iterator;
55
56 if (by_ref) {
57 ITERATION_BY_REF_NOT_SUPPORTED();
58 return NULL;
59 }
60
61 iterator = ecalloc(1, sizeof(php_ds_vector_iterator_t));
62
63 zend_iterator_init((zend_object_iterator*) iterator);
64
65 iterator->intern.funcs = &php_ds_vector_iterator_funcs;
66 iterator->vector = Z_DS_VECTOR_P(obj);
67 iterator->object = Z_OBJ_P(obj);
68 iterator->position = 0;
69
70 // Add a reference to the object so that it doesn't get collected when
71 // the iterated object is implict, eg. foreach ($obj->getInstance() as $value){ ... }
72 #if PHP_VERSION_ID >= 70300
73 GC_ADDREF(iterator->object);
74 #else
75 ++GC_REFCOUNT(iterator->object);
76 #endif
77
78 return (zend_object_iterator *) iterator;
79 }
80
php_ds_vector_get_iterator(zend_class_entry * ce,zval * obj,int by_ref)81 zend_object_iterator *php_ds_vector_get_iterator(zend_class_entry *ce, zval *obj, int by_ref)
82 {
83 return php_ds_vector_create_iterator(obj, by_ref);
84 }
85