Skip to content
Newer
Older
100755 567 lines (490 sloc) 17 KB
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
4223aa4 @sebastianbergmann MFH: Bump year.
sebastianbergmann authored Jan 1, 2007
5 | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) |
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Marcus Boerger <helly@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #include "zend.h"
22 #include "zend_API.h"
23 #include "zend_interfaces.h"
82193ad - Bugfix #26229 (getIterator() segfaults when it returns arrays or sc…
Marcus Boerger authored Jan 25, 2005
24 #include "zend_exceptions.h"
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
25
1cc4a69 @smalyshev preserve ZEND_API in definition
smalyshev authored Mar 28, 2004
26 ZEND_API zend_class_entry *zend_ce_traversable;
27 ZEND_API zend_class_entry *zend_ce_aggregate;
28 ZEND_API zend_class_entry *zend_ce_iterator;
29 ZEND_API zend_class_entry *zend_ce_arrayaccess;
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
30 ZEND_API zend_class_entry *zend_ce_serializable;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
31
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
32 /* {{{ zend_call_method
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
33 Only returns the returned zval if retval_ptr != NULL */
34 ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
35 {
36 int result;
37 zend_fcall_info fci;
38 zval z_fname;
39 zval *retval;
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
40 HashTable *function_table;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
41
42 zval **params[2];
43
44 params[0] = &arg1;
45 params[1] = &arg2;
46
47 fci.size = sizeof(fci);
48 /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
49 fci.object_pp = object_pp;
50 fci.function_name = &z_fname;
51 fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
52 fci.param_count = param_count;
53 fci.params = params;
54 fci.no_separation = 1;
55 fci.symbol_table = NULL;
56
57 if (!fn_proxy && !obj_ce) {
58 /* no interest in caching and no information already present that is
59 * needed later inside zend_call_function. */
60 ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
48d9adc - MFH Allow uncached global functions
Marcus Boerger authored Oct 3, 2005
61 fci.function_table = !object_pp ? EG(function_table) : NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
62 result = zend_call_function(&fci, NULL TSRMLS_CC);
63 } else {
64 zend_fcall_info_cache fcic;
65
66 fcic.initialized = 1;
67 if (!obj_ce) {
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
68 obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
69 }
70 if (obj_ce) {
71 function_table = &obj_ce->function_table;
72 } else {
73 function_table = EG(function_table);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
74 }
75 if (!fn_proxy || !*fn_proxy) {
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
76 if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
77 /* error at c-level */
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
78 zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
79 }
80 if (fn_proxy) {
81 *fn_proxy = fcic.function_handler;
82 }
83 } else {
84 fcic.function_handler = *fn_proxy;
85 }
86 fcic.calling_scope = obj_ce;
87 fcic.object_pp = object_pp;
88 result = zend_call_function(&fci, &fcic TSRMLS_CC);
89 }
90 if (result == FAILURE) {
91 /* error at c-level */
92 if (!obj_ce) {
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
93 obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
94 }
f7ba723 @tony2001 MFH: fix #38624 (Strange warning when incrementing an object property…
tony2001 authored Aug 28, 2006
95 if (!EG(exception)) {
96 zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
97 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
98 }
99 if (!retval_ptr_ptr) {
100 if (retval) {
39df192 Correct destruction
Marcus Boerger authored Nov 17, 2003
101 zval_ptr_dtor(&retval);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
102 }
103 return NULL;
104 }
105 return *retval_ptr_ptr;
106 }
107 /* }}} */
108
109 /* iterator interface, c-level functions used by engine */
110
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
111 /* {{{ zend_user_it_new_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
112 ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
113 {
114 zval *retval;
115
116 return zend_call_method_with_0_params(&object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
5824641 IteratorAggregate::getIterator() cannot return anythingy else than ob…
Marcus Boerger authored Nov 13, 2003
117
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
118 }
119 /* }}} */
120
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
121 /* {{{ zend_user_it_dtor */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
122 ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC)
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
123 {
124 zend_user_iterator *iter = (zend_user_iterator*)_iter;
125
126 if (iter->value) {
127 zval_ptr_dtor(&iter->value);
128 iter->value = NULL;
129 }
130 }
131 /* }}} */
132
133 /* {{{ zend_user_it_dtor */
134 static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
135 {
136 zend_user_iterator *iter = (zend_user_iterator*)_iter;
137 zval *object = (zval*)iter->it.data;
138
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
139 zend_user_it_invalidate_current(_iter TSRMLS_CC);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
140 zval_ptr_dtor(&object);
141 efree(iter);
142 }
143 /* }}} */
144
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
145 /* {{{ zend_user_it_valid */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
146 ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
147 {
f9d1309 Prevent some SEGV's when Exceptions are thorown inside iterators.
Marcus Boerger authored Nov 4, 2003
148 if (_iter) {
149 zend_user_iterator *iter = (zend_user_iterator*)_iter;
150 zval *object = (zval*)iter->it.data;
151 zval *more;
152 int result;
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
153
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
154 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
f9d1309 Prevent some SEGV's when Exceptions are thorown inside iterators.
Marcus Boerger authored Nov 4, 2003
155 if (more) {
156 result = i_zend_is_true(more);
b29834a Use correct macro/function
Marcus Boerger authored Nov 18, 2003
157 zval_ptr_dtor(&more);
f9d1309 Prevent some SEGV's when Exceptions are thorown inside iterators.
Marcus Boerger authored Nov 4, 2003
158 return result ? SUCCESS : FAILURE;
159 }
160 }
161 return FAILURE;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
162 }
163 /* }}} */
164
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
165 /* {{{ zend_user_it_get_current_data */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
166 ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
167 {
168 zend_user_iterator *iter = (zend_user_iterator*)_iter;
169 zval *object = (zval*)iter->it.data;
170
171 if (!iter->value) {
172 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
173 }
174 *data = &iter->value;
175 }
176 /* }}} */
177
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
178 /* {{{ zend_user_it_get_current_key_default */
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
179 #if 0
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
180 static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
181 {
da6d68d Little iterator improvement: ability to store index in iterator
Marcus Boerger authored Nov 10, 2003
182 *int_key = _iter->index;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
183 return HASH_KEY_IS_LONG;
184 }
185 #endif
186 /* }}} */
187
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
188 /* {{{ zend_user_it_get_current_key */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
189 ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
190 {
191 zend_user_iterator *iter = (zend_user_iterator*)_iter;
192 zval *object = (zval*)iter->it.data;
193 zval *retval;
194
195 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
196
c5abb9b Capture potential problem by error message
Marcus Boerger authored Apr 25, 2004
197 if (!retval) {
198 *int_key = 0;
897090c - Dont't warn in case an exception is pending - in this case it'd sup…
Marcus Boerger authored Jul 19, 2005
199 if (!EG(exception))
200 {
201 zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
202 }
c5abb9b Capture potential problem by error message
Marcus Boerger authored Apr 25, 2004
203 return HASH_KEY_IS_LONG;
204 }
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
205 switch (Z_TYPE_P(retval)) {
206 default:
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
207 zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
208 case IS_NULL:
209 *int_key = 0;
210 zval_ptr_dtor(&retval);
211 return HASH_KEY_IS_LONG;
212
213 case IS_STRING:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
214 *str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
215 *str_key_len = Z_STRLEN_P(retval)+1;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
216 zval_ptr_dtor(&retval);
217 return HASH_KEY_IS_STRING;
218
219 case IS_DOUBLE:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
220 *int_key = (long)Z_DVAL_P(retval);
221 zval_ptr_dtor(&retval);
222 return HASH_KEY_IS_LONG;
223
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
224 case IS_RESOURCE:
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
225 case IS_BOOL:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
226 case IS_LONG:
227 *int_key = (long)Z_LVAL_P(retval);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
228 zval_ptr_dtor(&retval);
229 return HASH_KEY_IS_LONG;
230 }
231 }
232 /* }}} */
233
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
234 /* {{{ zend_user_it_move_forward */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
235 ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
236 {
237 zend_user_iterator *iter = (zend_user_iterator*)_iter;
238 zval *object = (zval*)iter->it.data;
239
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
240 zend_user_it_invalidate_current(_iter TSRMLS_CC);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
241 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
242 }
243 /* }}} */
244
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
245 /* {{{ zend_user_it_rewind */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
246 ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
247 {
248 zend_user_iterator *iter = (zend_user_iterator*)_iter;
249 zval *object = (zval*)iter->it.data;
250
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
251 zend_user_it_invalidate_current(_iter TSRMLS_CC);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
252 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
253 }
254 /* }}} */
255
256 zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
257 zend_user_it_dtor,
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
258 zend_user_it_valid,
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
259 zend_user_it_get_current_data,
260 zend_user_it_get_current_key,
261 zend_user_it_move_forward,
e1cd098 - no unneccessary retval initialization
Marcus Boerger authored Apr 27, 2004
262 zend_user_it_rewind,
263 zend_user_it_invalidate_current
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
264 };
265
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
266 /* {{{ zend_user_it_get_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
267 static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
268 {
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
269 zend_user_iterator *iterator;
270
271 if (by_ref) {
272 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
273 }
274
275 iterator = emalloc(sizeof(zend_user_iterator));
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
276
277 object->refcount++;
278 iterator->it.data = (void*)object;
279 iterator->it.funcs = ce->iterator_funcs.funcs;
280 iterator->ce = Z_OBJCE_P(object);
281 iterator->value = NULL;
282 return (zend_object_iterator*)iterator;
283 }
284 /* }}} */
285
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
286 /* {{{ zend_user_it_get_new_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
287 ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
288 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
289 zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC);
c978cc2 Use correct order
Marcus Boerger authored Nov 18, 2003
290 zend_object_iterator *new_iterator;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
291
5206e9c - Allow getIterator() to fail
Marcus Boerger authored Jan 24, 2005
292 zend_class_entry *ce_it = iterator && Z_TYPE_P(iterator) == IS_OBJECT ? Z_OBJCE_P(iterator) : NULL;
5824641 IteratorAggregate::getIterator() cannot return anythingy else than ob…
Marcus Boerger authored Nov 13, 2003
293
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
294 if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
295 if (!EG(exception)) {
6c89fd2 - MFH Coverity fix 49
Marcus Boerger authored Apr 10, 2006
296 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name : Z_OBJCE_P(object)->name);
5206e9c - Allow getIterator() to fail
Marcus Boerger authored Jan 24, 2005
297 }
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
298 if (iterator) {
5206e9c - Allow getIterator() to fail
Marcus Boerger authored Jan 24, 2005
299 zval_ptr_dtor(&iterator);
300 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
301 return NULL;
302 }
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
303
304 new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
c978cc2 Use correct order
Marcus Boerger authored Nov 18, 2003
305 zval_ptr_dtor(&iterator);
306 return new_iterator;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
307 }
308 /* }}} */
309
310 /* {{{ zend_implement_traversable */
311 static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
312 {
313 /* check that class_type is traversable at c-level or implements at least one of 'aggregate' and 'Iterator' */
01af2c3 Fix warnign
Marcus Boerger authored Sep 27, 2004
314 zend_uint i;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
315
64c7645 #where has my bracket been gone?
Marcus Boerger authored Jan 17, 2004
316 if (class_type->get_iterator || (class_type->parent && class_type->parent->get_iterator)) {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
317 return SUCCESS;
50ee116 Clearify the different method/class flags (as discussed with Andi).
Marcus Boerger authored Mar 9, 2004
318 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
319 for (i = 0; i < class_type->num_interfaces; i++) {
320 if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
321 return SUCCESS;
322 }
323 }
324 zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
325 class_type->name,
326 zend_ce_traversable->name,
327 zend_ce_iterator->name,
328 zend_ce_aggregate->name);
329 return FAILURE;
330 }
331 /* }}} */
332
333 /* {{{ zend_implement_aggregate */
334 static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
335 {
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
336 int i, t = -1;
337
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
338 if (class_type->get_iterator) {
339 if (class_type->type == ZEND_INTERNAL_CLASS) {
340 /* inheritance ensures the class has necessary userland methods */
341 return SUCCESS;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
342 } else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
343 /* c-level get_iterator cannot be changed (exception being only Traversable is implmented) */
344 if (class_type->num_interfaces) {
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
345 for (i = 0; i < class_type->num_interfaces; i++) {
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
346 if (class_type->interfaces[i] == zend_ce_iterator) {
347 return FAILURE;
348 }
349 if (class_type->interfaces[i] == zend_ce_traversable) {
350 t = i;
351 }
352 }
353 }
354 if (t == -1) {
355 return FAILURE;
356 }
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
357 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
358 }
359 class_type->iterator_funcs.zf_new_iterator = NULL;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
360 class_type->get_iterator = zend_user_it_get_new_iterator;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
361 return SUCCESS;
362 }
363 /* }}} */
364
365 /* {{{ zend_implement_iterator */
366 static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
367 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
368 if (class_type->get_iterator && class_type->get_iterator != zend_user_it_get_iterator) {
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
369 if (class_type->type == ZEND_INTERNAL_CLASS) {
370 /* inheritance ensures the class has the necessary userland methods */
371 return SUCCESS;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
372 } else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
373 /* c-level get_iterator cannot be changed */
374 return FAILURE;
375 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
376 }
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
377 class_type->get_iterator = zend_user_it_get_iterator;
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
378 class_type->iterator_funcs.zf_valid = NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
379 class_type->iterator_funcs.zf_current = NULL;
380 class_type->iterator_funcs.zf_key = NULL;
381 class_type->iterator_funcs.zf_next = NULL;
382 class_type->iterator_funcs.zf_rewind = NULL;
383 if (!class_type->iterator_funcs.funcs) {
384 class_type->iterator_funcs.funcs = &zend_interface_iterator_funcs_iterator;
385 }
386 return SUCCESS;
387 }
388 /* }}} */
389
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
390 /* {{{ zend_implement_arrayaccess */
391 static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
392 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
393 #if 0
394 /* get ht from ce */
395 if (ht->read_dimension != zend_std_read_dimension
396 || ht->write_dimension != zend_std_write_dimension
397 || ht->has_dimension != zend_std_has_dimension
398 || ht->unset_dimension != zend_std_unset_dimension) {
399 return FAILURE;
400 }
401 #endif
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
402 return SUCCESS;
403 }
404 /* }}}*/
405
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
406 /* {{{ zend_user_serialize */
407 int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
408 {
409 zend_class_entry * ce = Z_OBJCE_P(object);
410 zval *retval;
411 int result;
412
413 zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
414
415
416 if (!retval || EG(exception)) {
417 result = FAILURE;
418 } else {
419 switch(Z_TYPE_P(retval)) {
420 case IS_NULL:
421 /* we could also make this '*buf_len = 0' but this allows to skip variables */
d77945e - Just return FAILURE & allow NULL without emmidiate error
Marcus Boerger authored Apr 5, 2005
422 zval_ptr_dtor(&retval);
423 return FAILURE;
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
424 case IS_STRING:
425 *buffer = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
426 *buf_len = Z_STRLEN_P(retval);
427 result = SUCCESS;
428 break;
429 default: /* failure */
430 result = FAILURE;
431 break;
432 }
433 zval_ptr_dtor(&retval);
434 }
435
436 if (result == FAILURE) {
80d7ac0 @tony2001 there is no %v in 5.2
tony2001 authored May 18, 2006
437 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
438 }
439 return result;
440 }
441 /* }}} */
442
443 /* {{{ zend_user_unserialize */
444 int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
445 {
446 zval * zdata;
447
448 object_init_ex(*object, ce);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
449
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
450 MAKE_STD_ZVAL(zdata);
451 ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
452
453 zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
454
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
455 zval_ptr_dtor(&zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
456
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
457 if (EG(exception)) {
458 return FAILURE;
459 } else {
460 return SUCCESS;
461 }
462 }
463 /* }}} */
464
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
465 /* {{{ zend_implement_serializable */
466 static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
467 {
468 if ((class_type->serialize && class_type->serialize != zend_user_serialize)
469 || (class_type->unserialize && class_type->unserialize != zend_user_unserialize)
470 ) {
471 return FAILURE;
472 }
473 class_type->serialize = zend_user_serialize;
474 class_type->unserialize = zend_user_unserialize;
475 return SUCCESS;
476 }
477 /* }}}*/
478
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
479 /* {{{ function tables */
480 zend_function_entry zend_funcs_aggregate[] = {
481 ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
482 {NULL, NULL, NULL}
483 };
484
485 zend_function_entry zend_funcs_iterator[] = {
486 ZEND_ABSTRACT_ME(iterator, current, NULL)
487 ZEND_ABSTRACT_ME(iterator, next, NULL)
488 ZEND_ABSTRACT_ME(iterator, key, NULL)
b6b7c9e Rename hasMore() to valid() as discussed. (Part I)
Marcus Boerger authored Mar 8, 2004
489 ZEND_ABSTRACT_ME(iterator, valid, NULL)
da6d68d Little iterator improvement: ability to store index in iterator
Marcus Boerger authored Nov 10, 2003
490 ZEND_ABSTRACT_ME(iterator, rewind, NULL)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
491 {NULL, NULL, NULL}
492 };
493
494 zend_function_entry *zend_funcs_traversable = NULL;
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
495
496 static
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
497 ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset, 0, 0, 1)
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
498 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
499 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
500
501 static
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
502 ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_get, 0, 0, 1) /* actually this should be return by ref but atm cannot be */
503 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
504 ZEND_END_ARG_INFO()
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
505
506 static
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
507 ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_value, 0, 0, 2)
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
508 ZEND_ARG_INFO(0, offset)
509 ZEND_ARG_INFO(0, value)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
510 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
511
512 zend_function_entry zend_funcs_arrayaccess[] = {
513 ZEND_ABSTRACT_ME(arrayaccess, offsetExists, arginfo_arrayaccess_offset)
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
514 ZEND_ABSTRACT_ME(arrayaccess, offsetGet, arginfo_arrayaccess_offset_get)
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
515 ZEND_ABSTRACT_ME(arrayaccess, offsetSet, arginfo_arrayaccess_offset_value)
516 ZEND_ABSTRACT_ME(arrayaccess, offsetUnset, arginfo_arrayaccess_offset)
517 {NULL, NULL, NULL}
518 };
519
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
520 static
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
521 ZEND_BEGIN_ARG_INFO(arginfo_serializable_serialize, 0)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
522 ZEND_ARG_INFO(0, serialized)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
523 ZEND_END_ARG_INFO()
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
524
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
525 zend_function_entry zend_funcs_serializable[] = {
526 ZEND_ABSTRACT_ME(serializable, serialize, NULL)
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
527 ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
528 {NULL, NULL, NULL}
529 };
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
530 /* }}} */
531
532 #define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
533 {\
534 zend_class_entry ce;\
535 INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
536 zend_ce_ ## class_name = zend_register_internal_interface(&ce TSRMLS_CC);\
537 zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
538 }
539
540 #define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
541 zend_class_implements(zend_ce_ ## class_name TSRMLS_CC, 1, zend_ce_ ## interface_name)
542
543 /* {{{ zend_register_interfaces */
544 ZEND_API void zend_register_interfaces(TSRMLS_D)
545 {
546 REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
547
548 REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
549 REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
550
551 REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
552 REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
553
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
554 REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
555
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
556 REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
557 }
558 /* }}} */
559
560 /*
561 * Local variables:
562 * tab-width: 4
563 * c-basic-offset: 4
564 * indent-tabs-mode: t
565 * End:
566 */
Something went wrong with that request. Please try again.