Skip to content
Newer
Older
100755 601 lines (522 sloc) 18.4 KB
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
e4ca0ed @felipensp - Year++
felipensp authored Jan 1, 2012
5 | Copyright (c) 1998-2012 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 */
7d4fd3f Fixed bug #46409 (__invoke method called outside of object context wh…
Dmitry Stogov authored Nov 27, 2008
49 fci.object_ptr = object_pp ? *object_pp : NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
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;
4a4d739 Fixed bug #47699 (autoload and late static binding)
Dmitry Stogov authored Mar 25, 2009
87 if (object_pp) {
88 fcic.called_scope = Z_OBJCE_PP(object_pp);
89 } else if (obj_ce &&
90 !(EG(called_scope) &&
91 instanceof_function(EG(called_scope), obj_ce TSRMLS_CC))) {
92 fcic.called_scope = obj_ce;
93 } else {
94 fcic.called_scope = EG(called_scope);
95 }
7d4fd3f Fixed bug #46409 (__invoke method called outside of object context wh…
Dmitry Stogov authored Nov 27, 2008
96 fcic.object_ptr = object_pp ? *object_pp : NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
97 result = zend_call_function(&fci, &fcic TSRMLS_CC);
98 }
99 if (result == FAILURE) {
100 /* error at c-level */
101 if (!obj_ce) {
0b3ed59 - Support statuc methods/functions
Marcus Boerger authored Mar 1, 2005
102 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
103 }
f7ba723 @tony2001 MFH: fix #38624 (Strange warning when incrementing an object property…
tony2001 authored Aug 28, 2006
104 if (!EG(exception)) {
105 zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
106 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
107 }
108 if (!retval_ptr_ptr) {
109 if (retval) {
39df192 Correct destruction
Marcus Boerger authored Nov 17, 2003
110 zval_ptr_dtor(&retval);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
111 }
112 return NULL;
113 }
114 return *retval_ptr_ptr;
115 }
116 /* }}} */
117
118 /* iterator interface, c-level functions used by engine */
119
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
120 /* {{{ zend_user_it_new_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
121 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
122 {
123 zval *retval;
124
125 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
126
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
127 }
128 /* }}} */
129
bbf8a50 @laruence Fix typo
laruence authored May 3, 2012
130 /* {{{ zend_user_it_invalidate_current */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
131 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
132 {
133 zend_user_iterator *iter = (zend_user_iterator*)_iter;
134
135 if (iter->value) {
136 zval_ptr_dtor(&iter->value);
137 iter->value = NULL;
138 }
139 }
140 /* }}} */
141
142 /* {{{ zend_user_it_dtor */
143 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
144 {
145 zend_user_iterator *iter = (zend_user_iterator*)_iter;
146 zval *object = (zval*)iter->it.data;
147
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
148 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
149 zval_ptr_dtor(&object);
150 efree(iter);
151 }
152 /* }}} */
153
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
154 /* {{{ zend_user_it_valid */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
155 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
156 {
f9d1309 Prevent some SEGV's when Exceptions are thorown inside iterators.
Marcus Boerger authored Nov 4, 2003
157 if (_iter) {
158 zend_user_iterator *iter = (zend_user_iterator*)_iter;
159 zval *object = (zval*)iter->it.data;
160 zval *more;
161 int result;
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
162
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
163 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
164 if (more) {
165 result = i_zend_is_true(more);
b29834a Use correct macro/function
Marcus Boerger authored Nov 18, 2003
166 zval_ptr_dtor(&more);
f9d1309 Prevent some SEGV's when Exceptions are thorown inside iterators.
Marcus Boerger authored Nov 4, 2003
167 return result ? SUCCESS : FAILURE;
168 }
169 }
170 return FAILURE;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
171 }
172 /* }}} */
173
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
174 /* {{{ zend_user_it_get_current_data */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
175 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
176 {
177 zend_user_iterator *iter = (zend_user_iterator*)_iter;
178 zval *object = (zval*)iter->it.data;
179
180 if (!iter->value) {
181 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
182 }
183 *data = &iter->value;
184 }
185 /* }}} */
186
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
187 /* {{{ zend_user_it_get_current_key_default */
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
188 #if 0
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
189 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
190 {
da6d68d Little iterator improvement: ability to store index in iterator
Marcus Boerger authored Nov 10, 2003
191 *int_key = _iter->index;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
192 return HASH_KEY_IS_LONG;
193 }
194 #endif
195 /* }}} */
196
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
197 /* {{{ zend_user_it_get_current_key */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
198 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
199 {
200 zend_user_iterator *iter = (zend_user_iterator*)_iter;
201 zval *object = (zval*)iter->it.data;
202 zval *retval;
203
204 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
205
c5abb9b Capture potential problem by error message
Marcus Boerger authored Apr 25, 2004
206 if (!retval) {
207 *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
208 if (!EG(exception))
209 {
210 zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
211 }
c5abb9b Capture potential problem by error message
Marcus Boerger authored Apr 25, 2004
212 return HASH_KEY_IS_LONG;
213 }
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
214 switch (Z_TYPE_P(retval)) {
215 default:
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
216 zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
217 case IS_NULL:
218 *int_key = 0;
219 zval_ptr_dtor(&retval);
220 return HASH_KEY_IS_LONG;
221
222 case IS_STRING:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
223 *str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
224 *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
225 zval_ptr_dtor(&retval);
226 return HASH_KEY_IS_STRING;
227
228 case IS_DOUBLE:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
229 *int_key = (long)Z_DVAL_P(retval);
230 zval_ptr_dtor(&retval);
231 return HASH_KEY_IS_LONG;
232
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
233 case IS_RESOURCE:
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
234 case IS_BOOL:
7a5240e - MFH missing bits and pieces of the partial sync with head
Marcus Boerger authored May 11, 2006
235 case IS_LONG:
236 *int_key = (long)Z_LVAL_P(retval);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
237 zval_ptr_dtor(&retval);
238 return HASH_KEY_IS_LONG;
239 }
240 }
241 /* }}} */
242
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
243 /* {{{ zend_user_it_move_forward */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
244 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
245 {
246 zend_user_iterator *iter = (zend_user_iterator*)_iter;
247 zval *object = (zval*)iter->it.data;
248
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
249 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
250 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
251 }
252 /* }}} */
253
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
254 /* {{{ zend_user_it_rewind */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
255 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
256 {
257 zend_user_iterator *iter = (zend_user_iterator*)_iter;
258 zval *object = (zval*)iter->it.data;
259
11ce65a - Fix warnings
Marcus Boerger authored Apr 27, 2004
260 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
261 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
262 }
263 /* }}} */
264
265 zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
266 zend_user_it_dtor,
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
267 zend_user_it_valid,
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
268 zend_user_it_get_current_data,
269 zend_user_it_get_current_key,
270 zend_user_it_move_forward,
e1cd098 - no unneccessary retval initialization
Marcus Boerger authored Apr 27, 2004
271 zend_user_it_rewind,
272 zend_user_it_invalidate_current
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
273 };
274
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
275 /* {{{ zend_user_it_get_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
276 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
277 {
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
278 zend_user_iterator *iterator;
279
280 if (by_ref) {
281 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
282 }
283
284 iterator = emalloc(sizeof(zend_user_iterator));
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
285
4b4d634 MFH: Added macros for managing zval refcounts and is_ref statuses
Yiduo (David) Wang authored Oct 7, 2007
286 Z_ADDREF_P(object);
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
287 iterator->it.data = (void*)object;
288 iterator->it.funcs = ce->iterator_funcs.funcs;
289 iterator->ce = Z_OBJCE_P(object);
290 iterator->value = NULL;
291 return (zend_object_iterator*)iterator;
292 }
293 /* }}} */
294
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
295 /* {{{ zend_user_it_get_new_iterator */
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
296 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
297 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
298 zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC);
c978cc2 Use correct order
Marcus Boerger authored Nov 18, 2003
299 zend_object_iterator *new_iterator;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
300
5206e9c - Allow getIterator() to fail
Marcus Boerger authored Jan 24, 2005
301 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
302
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
303 if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
304 if (!EG(exception)) {
6c89fd2 - MFH Coverity fix 49
Marcus Boerger authored Apr 10, 2006
305 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
306 }
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
307 if (iterator) {
5206e9c - Allow getIterator() to fail
Marcus Boerger authored Jan 24, 2005
308 zval_ptr_dtor(&iterator);
309 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
310 return NULL;
311 }
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
312
313 new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
c978cc2 Use correct order
Marcus Boerger authored Nov 18, 2003
314 zval_ptr_dtor(&iterator);
315 return new_iterator;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
316 }
317 /* }}} */
318
319 /* {{{ zend_implement_traversable */
320 static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
321 {
322 /* 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
323 zend_uint i;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
324
64c7645 #where has my bracket been gone?
Marcus Boerger authored Jan 17, 2004
325 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
326 return SUCCESS;
50ee116 Clearify the different method/class flags (as discussed with Andi).
Marcus Boerger authored Mar 9, 2004
327 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
328 for (i = 0; i < class_type->num_interfaces; i++) {
329 if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
330 return SUCCESS;
331 }
332 }
333 zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
334 class_type->name,
335 zend_ce_traversable->name,
336 zend_ce_iterator->name,
337 zend_ce_aggregate->name);
338 return FAILURE;
339 }
340 /* }}} */
341
342 /* {{{ zend_implement_aggregate */
343 static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
344 {
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
345 int i, t = -1;
346
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
347 if (class_type->get_iterator) {
348 if (class_type->type == ZEND_INTERNAL_CLASS) {
349 /* inheritance ensures the class has necessary userland methods */
350 return SUCCESS;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
351 } 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
352 /* c-level get_iterator cannot be changed (exception being only Traversable is implmented) */
353 if (class_type->num_interfaces) {
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
354 for (i = 0; i < class_type->num_interfaces; i++) {
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
355 if (class_type->interfaces[i] == zend_ce_iterator) {
191b52d @colder Remove trailing dots
colder authored Feb 2, 2010
356 zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
cca05f1 @colder Fix #48667 (Implementing Iterator and IteratorAggregate is now restri…
colder authored Feb 1, 2010
357 class_type->name,
358 interface->name,
359 zend_ce_iterator->name);
72c1baa - Allow to convert Traversable into Aggregate
Marcus Boerger authored Feb 23, 2005
360 return FAILURE;
361 }
362 if (class_type->interfaces[i] == zend_ce_traversable) {
363 t = i;
364 }
365 }
366 }
367 if (t == -1) {
368 return FAILURE;
369 }
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
370 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
371 }
372 class_type->iterator_funcs.zf_new_iterator = NULL;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
373 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
374 return SUCCESS;
375 }
376 /* }}} */
377
378 /* {{{ zend_implement_iterator */
379 static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
380 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
381 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
382 if (class_type->type == ZEND_INTERNAL_CLASS) {
383 /* inheritance ensures the class has the necessary userland methods */
384 return SUCCESS;
cca05f1 @colder Fix #48667 (Implementing Iterator and IteratorAggregate is now restri…
colder authored Feb 1, 2010
385 } else {
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
386 /* c-level get_iterator cannot be changed */
cca05f1 @colder Fix #48667 (Implementing Iterator and IteratorAggregate is now restri…
colder authored Feb 1, 2010
387 if (class_type->get_iterator == zend_user_it_get_new_iterator) {
191b52d @colder Remove trailing dots
colder authored Feb 2, 2010
388 zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
cca05f1 @colder Fix #48667 (Implementing Iterator and IteratorAggregate is now restri…
colder authored Feb 1, 2010
389 class_type->name,
390 interface->name,
391 zend_ce_aggregate->name);
392 }
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
393 return FAILURE;
394 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
395 }
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
396 class_type->get_iterator = zend_user_it_get_iterator;
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
397 class_type->iterator_funcs.zf_valid = NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
398 class_type->iterator_funcs.zf_current = NULL;
399 class_type->iterator_funcs.zf_key = NULL;
400 class_type->iterator_funcs.zf_next = NULL;
401 class_type->iterator_funcs.zf_rewind = NULL;
402 if (!class_type->iterator_funcs.funcs) {
403 class_type->iterator_funcs.funcs = &zend_interface_iterator_funcs_iterator;
404 }
405 return SUCCESS;
406 }
407 /* }}} */
408
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
409 /* {{{ zend_implement_arrayaccess */
410 static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
411 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
412 #if 0
413 /* get ht from ce */
414 if (ht->read_dimension != zend_std_read_dimension
415 || ht->write_dimension != zend_std_write_dimension
416 || ht->has_dimension != zend_std_has_dimension
417 || ht->unset_dimension != zend_std_unset_dimension) {
418 return FAILURE;
419 }
420 #endif
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
421 return SUCCESS;
422 }
423 /* }}}*/
424
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
425 /* {{{ zend_user_serialize */
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
426 ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
427 {
428 zend_class_entry * ce = Z_OBJCE_P(object);
429 zval *retval;
430 int result;
431
432 zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
433
434
435 if (!retval || EG(exception)) {
436 result = FAILURE;
437 } else {
438 switch(Z_TYPE_P(retval)) {
439 case IS_NULL:
440 /* 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
441 zval_ptr_dtor(&retval);
442 return FAILURE;
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
443 case IS_STRING:
d90ebc6 Fixed comilation warnings
Dmitry Stogov authored Jan 24, 2008
444 *buffer = (unsigned char*)estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
445 *buf_len = Z_STRLEN_P(retval);
446 result = SUCCESS;
447 break;
448 default: /* failure */
449 result = FAILURE;
450 break;
451 }
452 zval_ptr_dtor(&retval);
453 }
454
455 if (result == FAILURE) {
80d7ac0 @tony2001 there is no %v in 5.2
tony2001 authored May 18, 2006
456 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
457 }
458 return result;
459 }
460 /* }}} */
461
462 /* {{{ zend_user_unserialize */
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
463 ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
464 {
465 zval * zdata;
466
467 object_init_ex(*object, ce);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
468
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
469 MAKE_STD_ZVAL(zdata);
470 ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
471
472 zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
473
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
474 zval_ptr_dtor(&zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
475
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
476 if (EG(exception)) {
477 return FAILURE;
478 } else {
479 return SUCCESS;
480 }
481 }
482 /* }}} */
483
f48d22a @colder MFH: Fix #46646 (Implement zend functions to restrict serialization o…
colder authored Dec 22, 2008
484 ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
485 {
486 zend_class_entry *ce = Z_OBJCE_P(object);
487 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name);
488 return FAILURE;
489 }
490 /* }}} */
491
492 ZEND_API int zend_class_unserialize_deny(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
493 {
494 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name);
495 return FAILURE;
496 }
497 /* }}} */
498
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
499 /* {{{ zend_implement_serializable */
500 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
501 {
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
502 if (class_type->parent
503 && (class_type->parent->serialize || class_type->parent->unserialize)
504 && !instanceof_function_ex(class_type->parent, zend_ce_serializable, 1 TSRMLS_CC)) {
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
505 return FAILURE;
506 }
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
507 if (!class_type->serialize) {
508 class_type->serialize = zend_user_serialize;
509 }
510 if (!class_type->unserialize) {
511 class_type->unserialize = zend_user_unserialize;
512 }
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
513 return SUCCESS;
514 }
515 /* }}}*/
516
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
517 /* {{{ function tables */
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
518 const zend_function_entry zend_funcs_aggregate[] = {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
519 ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
520 {NULL, NULL, NULL}
521 };
522
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
523 const zend_function_entry zend_funcs_iterator[] = {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
524 ZEND_ABSTRACT_ME(iterator, current, NULL)
525 ZEND_ABSTRACT_ME(iterator, next, NULL)
526 ZEND_ABSTRACT_ME(iterator, key, NULL)
b6b7c9e Rename hasMore() to valid() as discussed. (Part I)
Marcus Boerger authored Mar 8, 2004
527 ZEND_ABSTRACT_ME(iterator, valid, NULL)
da6d68d Little iterator improvement: ability to store index in iterator
Marcus Boerger authored Nov 10, 2003
528 ZEND_ABSTRACT_ME(iterator, rewind, NULL)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
529 {NULL, NULL, NULL}
530 };
531
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
532 const zend_function_entry *zend_funcs_traversable = NULL;
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
533
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
534 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
535 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
536 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
537
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
538 ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_get, 0, 0, 1) /* actually this should be return by ref but atm cannot be */
539 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
540 ZEND_END_ARG_INFO()
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
541
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
542 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
543 ZEND_ARG_INFO(0, offset)
544 ZEND_ARG_INFO(0, value)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
545 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
546
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
547 const zend_function_entry zend_funcs_arrayaccess[] = {
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
548 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
549 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
550 ZEND_ABSTRACT_ME(arrayaccess, offsetSet, arginfo_arrayaccess_offset_value)
551 ZEND_ABSTRACT_ME(arrayaccess, offsetUnset, arginfo_arrayaccess_offset)
552 {NULL, NULL, NULL}
553 };
554
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
555 ZEND_BEGIN_ARG_INFO(arginfo_serializable_serialize, 0)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
556 ZEND_ARG_INFO(0, serialized)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
557 ZEND_END_ARG_INFO()
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
558
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
559 const zend_function_entry zend_funcs_serializable[] = {
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
560 ZEND_ABSTRACT_ME(serializable, serialize, NULL)
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
561 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
562 {NULL, NULL, NULL}
563 };
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
564 /* }}} */
565
566 #define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
567 {\
568 zend_class_entry ce;\
569 INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
570 zend_ce_ ## class_name = zend_register_internal_interface(&ce TSRMLS_CC);\
571 zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
572 }
573
574 #define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
575 zend_class_implements(zend_ce_ ## class_name TSRMLS_CC, 1, zend_ce_ ## interface_name)
576
577 /* {{{ zend_register_interfaces */
578 ZEND_API void zend_register_interfaces(TSRMLS_D)
579 {
580 REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
581
582 REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
583 REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
584
585 REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
586 REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
587
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
588 REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
589
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
590 REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
591 }
592 /* }}} */
593
594 /*
595 * Local variables:
596 * tab-width: 4
597 * c-basic-offset: 4
598 * indent-tabs-mode: t
599 * End:
600 */
Something went wrong with that request. Please try again.