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