Skip to content
Newer
Older
100755 591 lines (512 sloc) 18 KB
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
08659c2 @sebastianbergmann MFH: Bump copyright year, 3 of 3.
sebastianbergmann authored Dec 31, 2008
5 | Copyright (c) 1998-2009 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
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
130 /* {{{ zend_user_it_dtor */
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) {
356 return FAILURE;
357 }
358 if (class_type->interfaces[i] == zend_ce_traversable) {
359 t = i;
360 }
361 }
362 }
363 if (t == -1) {
364 return FAILURE;
365 }
851a02e Give some freedon to c iterators but not in userspace.
Marcus Boerger authored Oct 28, 2003
366 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
367 }
368 class_type->iterator_funcs.zf_new_iterator = NULL;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
369 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
370 return SUCCESS;
371 }
372 /* }}} */
373
374 /* {{{ zend_implement_iterator */
375 static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
376 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
377 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
378 if (class_type->type == ZEND_INTERNAL_CLASS) {
379 /* inheritance ensures the class has the necessary userland methods */
380 return SUCCESS;
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
381 } 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
382 /* c-level get_iterator cannot be changed */
383 return FAILURE;
384 }
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
385 }
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
386 class_type->get_iterator = zend_user_it_get_iterator;
6b0f57e Rename hasMore() to valid() as discussed. (Part II)
Marcus Boerger authored Mar 8, 2004
387 class_type->iterator_funcs.zf_valid = NULL;
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
388 class_type->iterator_funcs.zf_current = NULL;
389 class_type->iterator_funcs.zf_key = NULL;
390 class_type->iterator_funcs.zf_next = NULL;
391 class_type->iterator_funcs.zf_rewind = NULL;
392 if (!class_type->iterator_funcs.funcs) {
393 class_type->iterator_funcs.funcs = &zend_interface_iterator_funcs_iterator;
394 }
395 return SUCCESS;
396 }
397 /* }}} */
398
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
399 /* {{{ zend_implement_arrayaccess */
400 static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
401 {
6186617 - Export struct zend_user_iterator
Marcus Boerger authored Jan 26, 2004
402 #if 0
403 /* get ht from ce */
404 if (ht->read_dimension != zend_std_read_dimension
405 || ht->write_dimension != zend_std_write_dimension
406 || ht->has_dimension != zend_std_has_dimension
407 || ht->unset_dimension != zend_std_unset_dimension) {
408 return FAILURE;
409 }
410 #endif
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
411 return SUCCESS;
412 }
413 /* }}}*/
414
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
415 /* {{{ zend_user_serialize */
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
416 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
417 {
418 zend_class_entry * ce = Z_OBJCE_P(object);
419 zval *retval;
420 int result;
421
422 zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
423
424
425 if (!retval || EG(exception)) {
426 result = FAILURE;
427 } else {
428 switch(Z_TYPE_P(retval)) {
429 case IS_NULL:
430 /* 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
431 zval_ptr_dtor(&retval);
432 return FAILURE;
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
433 case IS_STRING:
d90ebc6 Fixed comilation warnings
Dmitry Stogov authored Jan 24, 2008
434 *buffer = (unsigned char*)estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
435 *buf_len = Z_STRLEN_P(retval);
436 result = SUCCESS;
437 break;
438 default: /* failure */
439 result = FAILURE;
440 break;
441 }
442 zval_ptr_dtor(&retval);
443 }
444
445 if (result == FAILURE) {
80d7ac0 @tony2001 there is no %v in 5.2
tony2001 authored May 18, 2006
446 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
447 }
448 return result;
449 }
450 /* }}} */
451
452 /* {{{ zend_user_unserialize */
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
453 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
454 {
455 zval * zdata;
456
457 object_init_ex(*object, ce);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
458
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
459 MAKE_STD_ZVAL(zdata);
460 ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
461
462 zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
463
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
464 zval_ptr_dtor(&zdata);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
465
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
466 if (EG(exception)) {
467 return FAILURE;
468 } else {
469 return SUCCESS;
470 }
471 }
472 /* }}} */
473
f48d22a @colder MFH: Fix #46646 (Implement zend functions to restrict serialization o…
colder authored Dec 22, 2008
474 ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
475 {
476 zend_class_entry *ce = Z_OBJCE_P(object);
477 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name);
478 return FAILURE;
479 }
480 /* }}} */
481
482 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) /* {{{ */
483 {
484 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name);
485 return FAILURE;
486 }
487 /* }}} */
488
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
489 /* {{{ zend_implement_serializable */
490 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
491 {
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
492 if (class_type->parent
493 && (class_type->parent->serialize || class_type->parent->unserialize)
494 && !instanceof_function_ex(class_type->parent, zend_ce_serializable, 1 TSRMLS_CC)) {
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
495 return FAILURE;
496 }
cc9a8ee @colder MFH:
colder authored Aug 24, 2008
497 if (!class_type->serialize) {
498 class_type->serialize = zend_user_serialize;
499 }
500 if (!class_type->unserialize) {
501 class_type->unserialize = zend_user_unserialize;
502 }
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
503 return SUCCESS;
504 }
505 /* }}}*/
506
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
507 /* {{{ function tables */
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
508 const zend_function_entry zend_funcs_aggregate[] = {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
509 ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
510 {NULL, NULL, NULL}
511 };
512
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
513 const zend_function_entry zend_funcs_iterator[] = {
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
514 ZEND_ABSTRACT_ME(iterator, current, NULL)
515 ZEND_ABSTRACT_ME(iterator, next, NULL)
516 ZEND_ABSTRACT_ME(iterator, key, NULL)
b6b7c9e Rename hasMore() to valid() as discussed. (Part I)
Marcus Boerger authored Mar 8, 2004
517 ZEND_ABSTRACT_ME(iterator, valid, NULL)
da6d68d Little iterator improvement: ability to store index in iterator
Marcus Boerger authored Nov 10, 2003
518 ZEND_ABSTRACT_ME(iterator, rewind, NULL)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
519 {NULL, NULL, NULL}
520 };
521
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
522 const zend_function_entry *zend_funcs_traversable = NULL;
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
523
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
524 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
525 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
526 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
527
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
528 ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_get, 0, 0, 1) /* actually this should be return by ref but atm cannot be */
529 ZEND_ARG_INFO(0, offset)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
530 ZEND_END_ARG_INFO()
c6e3947 - More exact signatures (even though complete correct not possible atm)
Marcus Boerger authored Mar 13, 2005
531
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
532 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
533 ZEND_ARG_INFO(0, offset)
534 ZEND_ARG_INFO(0, value)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
535 ZEND_END_ARG_INFO()
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
536
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
537 const zend_function_entry zend_funcs_arrayaccess[] = {
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
538 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
539 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
540 ZEND_ABSTRACT_ME(arrayaccess, offsetSet, arginfo_arrayaccess_offset_value)
541 ZEND_ABSTRACT_ME(arrayaccess, offsetUnset, arginfo_arrayaccess_offset)
542 {NULL, NULL, NULL}
543 };
544
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
545 ZEND_BEGIN_ARG_INFO(arginfo_serializable_serialize, 0)
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
546 ZEND_ARG_INFO(0, serialized)
23eaae2 @tony2001 MFH
tony2001 authored May 30, 2007
547 ZEND_END_ARG_INFO()
757da1e - New Interface Serializeable
Marcus Boerger authored Mar 7, 2005
548
6c810b0 Improved memory usage by movig constants to read only memory. (Dmitry…
Dmitry Stogov authored Sep 27, 2007
549 const zend_function_entry zend_funcs_serializable[] = {
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
550 ZEND_ABSTRACT_ME(serializable, serialize, NULL)
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
551 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
552 {NULL, NULL, NULL}
553 };
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
554 /* }}} */
555
556 #define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
557 {\
558 zend_class_entry ce;\
559 INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
560 zend_ce_ ## class_name = zend_register_internal_interface(&ce TSRMLS_CC);\
561 zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
562 }
563
564 #define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
565 zend_class_implements(zend_ce_ ## class_name TSRMLS_CC, 1, zend_ce_ ## interface_name)
566
567 /* {{{ zend_register_interfaces */
568 ZEND_API void zend_register_interfaces(TSRMLS_D)
569 {
570 REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
571
572 REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
573 REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
574
575 REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
576 REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
577
4dba05d Add new interface ArrayAccess to use objects as Arrays
Marcus Boerger authored Nov 24, 2003
578 REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
637a404 - MFH as discussed
Marcus Boerger authored May 9, 2006
579
e9dbeab @andigutmans - Fix typos
andigutmans authored Mar 19, 2005
580 REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
8abb3bd Impement userspace iterator interfaces and tests. See tests for details
Marcus Boerger authored Oct 22, 2003
581 }
582 /* }}} */
583
584 /*
585 * Local variables:
586 * tab-width: 4
587 * c-basic-offset: 4
588 * indent-tabs-mode: t
589 * End:
590 */
Something went wrong with that request. Please try again.