@@ -116,211 +116,194 @@ static inline int msgpack_convert_string_to_properties(
116116
117117int msgpack_convert_array (zval * return_value , zval * tpl , zval * * value )
118118{
119- if (Z_TYPE_P (tpl ) == IS_ARRAY )
120- {
121- HashTable * ht , * htval ;
122- int num ;
123- zend_string * key_str ;
124- ulong key_long ;
125- zval * data ;
119+ if (Z_TYPE_P (tpl ) != IS_ARRAY ) {
120+ MSGPACK_WARNING ("[msgpack] (%s) template is not array" , __FUNCTION__ );
121+ zval_ptr_dtor (* value );
122+ return FAILURE ;
123+ }
126124
125+ zend_string * key ;
126+ int key_type ;
127+ ulong key_index ;
128+ zval * data , * arydata ;
129+ HashPosition pos , valpos ;
130+ HashTable * ht , * htval ;
127131
128- ht = HASH_OF (tpl );
129- // TODO: maybe need to release memory?
130- array_init (return_value );
132+ ht = HASH_OF (tpl );
133+ array_init (return_value );
131134
132- num = zend_hash_num_elements (ht );
133- if (num <= 0 )
134- {
135- MSGPACK_WARNING (
136- "[msgpack] (%s) template array length is 0" ,
135+ if (zend_hash_num_elements (ht ) <= 0 ) {
136+ MSGPACK_WARNING ("[msgpack] (%s) template array length is 0" ,
137137 __FUNCTION__ );
138+ zval_ptr_dtor (* value );
139+ return FAILURE ;
140+ }
141+
142+ /* string */
143+ if (ht -> nNumOfElements != ht -> nNextFreeElement ) {
144+ htval = HASH_OF (* value );
145+ if (!htval ) {
146+ MSGPACK_WARNING (
147+ "[msgpack] (%s) input data is not array" ,
148+ __FUNCTION__ );
138149 zval_ptr_dtor (* value );
139150 return FAILURE ;
140151 }
141152
142- /* string */
143- if (ht -> nNumOfElements != ht -> nNextFreeElement )
153+ zend_hash_internal_pointer_reset_ex (ht , & pos );
154+ zend_hash_internal_pointer_reset_ex (htval , & valpos );
155+ for (;; zend_hash_move_forward_ex (ht , & pos ), zend_hash_move_forward_ex (htval , & valpos ))
144156 {
145- htval = HASH_OF (* value );
146- if (!htval )
147- {
148- MSGPACK_WARNING (
149- "[msgpack] (%s) input data is not array" ,
150- __FUNCTION__ );
151- zval_ptr_dtor (* value );
152- return FAILURE ;
157+ key_type = zend_hash_get_current_key_ex (ht , & key , & key_index , & pos );
158+
159+ if (key_type == HASH_KEY_NON_EXISTENT ) {
160+ break ;
153161 }
154162
155- ZEND_HASH_FOREACH_KEY_VAL (ht , key_long , key_str , data ) {
156- if (key_str ) {
157- int (* convert_function )(zval * , zval * , zval * * ) = NULL ;
158- zval * * dataval , * val ;
163+ if ((data = zend_hash_get_current_data_ex (ht , & pos )) == NULL ) {
164+ continue ;
165+ }
159166
160- switch (Z_TYPE_P (data ))
161- {
162- case IS_ARRAY :
163- convert_function = msgpack_convert_array ;
164- break ;
165- case IS_OBJECT :
166- convert_function = msgpack_convert_object ;
167- break ;
168- default :
169- break ;
170- }
167+ if (key_type == HASH_KEY_IS_STRING ) {
168+ int (* convert_function )(zval * , zval * , zval * * ) = NULL ;
169+ zval * dataval , * val ;
171170
172- if (!data ) {
173- MSGPACK_WARNING (
174- "[msgpack] (%s) can't get data" ,
175- __FUNCTION__ );
176- zval_ptr_dtor (* value );
177- return FAILURE ;
178- }
171+ switch (Z_TYPE_P (data )) {
172+ case IS_ARRAY :
173+ convert_function = msgpack_convert_array ;
174+ break ;
175+ case IS_OBJECT :
176+ // case IS_STRING:
177+ convert_function = msgpack_convert_object ;
178+ break ;
179+ default :
180+ break ;
181+ }
179182
180- if (convert_function )
181- {
182- zval * rv ;
183- if (convert_function (rv , data , & val ) != SUCCESS )
184- {
185- zval_ptr_dtor (val );
186- return FAILURE ;
187- }
188- add_assoc_zval_ex (return_value , key_str -> val , key_str -> len , rv );
189- }
190- else
191- {
192- add_assoc_zval_ex (return_value , key_str -> val , key_str -> len , val );
193- }
183+ if ((dataval = zend_hash_get_current_data_ex (htval , & valpos )) == NULL ) {
184+ MSGPACK_WARNING ("[msgpack] (%s) can't get data" , __FUNCTION__ );
185+ zval_ptr_dtor (* value );
186+ return FAILURE ;
187+ }
194188
189+ MSGPACK_CONVERT_COPY_ZVAL (val , dataval );
195190
191+ if (convert_function ) {
192+ zval rv ;
193+ if (convert_function (& rv , data , & val ) != SUCCESS ) {
194+ zval_ptr_dtor (val );
195+ return FAILURE ;
196+ }
197+ add_assoc_zval_ex (return_value , key -> val , key -> len , & rv );
198+ } else {
199+ add_assoc_zval_ex (return_value , key -> val , key -> len , val );
196200 }
201+ }
202+ }
197203
198- } ZEND_HASH_FOREACH_END ( );
204+ zval_ptr_dtor ( * value );
199205
206+ return SUCCESS ;
207+ } else {
208+ /* index */
209+ int (* convert_function )(zval * , zval * , zval * * ) = NULL ;
200210
211+ if (Z_TYPE_P (* value ) != IS_ARRAY ) {
212+ MSGPACK_WARNING ("[msgpack] (%s) unserialized data must be array." , __FUNCTION__ );
201213 zval_ptr_dtor (* value );
202-
203- return SUCCESS ;
214+ return FAILURE ;
204215 }
205- else
206- {
207- /* index */
208- int (* convert_function )(zval * , zval * , zval * * ) = NULL ;
209- int first_loop = 0 ;
210-
211- if (Z_TYPE_P (* value ) != IS_ARRAY )
212- {
213- MSGPACK_WARNING (
214- "[msgpack] (%s) unserialized data must be array." ,
216+
217+ zend_hash_internal_pointer_reset_ex (ht , & pos );
218+ key_type = zend_hash_get_current_key_ex (ht , & key , & key_index , & pos );
219+
220+ if (key_type == HASH_KEY_NON_EXISTENT ) {
221+ MSGPACK_WARNING (
222+ "[msgpack] (%s) first element in template array is empty" ,
215223 __FUNCTION__ );
216- zval_ptr_dtor (* value );
217- return FAILURE ;
218- }
224+ zval_ptr_dtor (* value );
225+ return FAILURE ;
226+ }
219227
220- ZEND_HASH_FOREACH_KEY_VAL (ht , key_long , key_str , data ) {
221- if (first_loop ) {
222- if (!key_long && !key_str ) {
223- MSGPACK_WARNING (
224- "[msgpack] (%s) first element in template array is empty" ,
225- __FUNCTION__ );
226- zval_ptr_dtor (* value );
227- return FAILURE ;
228- }
228+ if ((data = zend_hash_get_current_data_ex (ht , & pos )) == NULL ) {
229+ MSGPACK_WARNING ("[msgpack] (%s) invalid template: empty array?" , __FUNCTION__ );
230+ zval_ptr_dtor (* value );
231+ return FAILURE ;
232+ }
229233
230- if (!data ) {
231- MSGPACK_WARNING (
232- "[msgpack] (%s) invalid template: empty array?" ,
233- __FUNCTION__ );
234- zval_ptr_dtor (* value );
235- return FAILURE ;
236- }
234+ switch (Z_TYPE_P (data ))
235+ {
236+ case IS_ARRAY :
237+ convert_function = msgpack_convert_array ;
238+ break ;
239+ case IS_OBJECT :
240+ case IS_STRING :
241+ convert_function = msgpack_convert_object ;
242+ break ;
243+ default :
244+ break ;
245+ }
237246
238- switch (Z_TYPE_P (data )) {
239- case IS_ARRAY :
240- convert_function = msgpack_convert_array ;
241- break ;
242- case IS_OBJECT :
243- case IS_STRING :
244- convert_function = msgpack_convert_object ;
245- break ;
246- default :
247- break ;
248- }
247+ htval = HASH_OF (* value );
248+ if (zend_hash_num_elements (htval ) <= 0 ) {
249+ MSGPACK_WARNING ("[msgpack] (%s) array length is 0 in unserialized data" , __FUNCTION__ );
250+ zval_ptr_dtor (* value );
251+ return FAILURE ;
252+ }
249253
250- htval = HASH_OF (* value );
251- num = zend_hash_num_elements (htval );
252- if (num <= 0 ) {
253- MSGPACK_WARNING (
254- "[msgpack] (%s) array length is 0 in unserialized data" ,
255- __FUNCTION__ );
256- zval_ptr_dtor (* value );
257- return FAILURE ;
258- }
254+ zend_hash_internal_pointer_reset_ex (htval , & valpos );
255+ for (;; zend_hash_move_forward_ex (htval , & valpos )) {
256+ key_type = zend_hash_get_current_key_ex (htval , & key , & key_index , & valpos );
259257
258+ if (key_type == HASH_KEY_NON_EXISTENT ) {
259+ break ;
260+ }
260261
261- first_loop = 1 ;
262- } else {
263- if (!data ) {
264- MSGPACK_WARNING (
265- "[msgpack] (%s) can't get next data in indexed array" ,
266- __FUNCTION__ );
267- continue ;
268- } else if (key_long ) {
269- zval * aryval , * rv ;
270- if (convert_function )
271- {
272- if (convert_function (rv , data , & aryval ) != SUCCESS )
273- {
274- zval_ptr_dtor (aryval );
262+ if ((arydata = zend_hash_get_current_data_ex (htval , & valpos )) == NULL ) {
263+ MSGPACK_WARNING ( "[msgpack] (%s) can't get next data in indexed array" , __FUNCTION__ );
264+ continue ;
265+ }
266+
267+ switch (key_type ) {
268+ case HASH_KEY_IS_LONG : {
269+ zval rv ;
270+ if (convert_function ) {
271+ if (convert_function (& rv , data , & arydata ) != SUCCESS ) {
275272 MSGPACK_WARNING (
276- "[msgpack] (%s) "
277- "convert failure in HASH_KEY_IS_LONG "
278- "in indexed array" ,
279- __FUNCTION__ );
273+ "[msgpack] (%s) "
274+ "convert failure in HASH_KEY_IS_LONG "
275+ "in indexed array" ,
276+ __FUNCTION__ );
280277 zval_ptr_dtor (* value );
281278 return FAILURE ;
282279 }
283- add_next_index_zval (return_value , rv );
284- }
285- else
286- {
287- add_next_index_zval (return_value , aryval );
280+ add_next_index_zval (return_value , & rv );
281+ } else {
282+ add_next_index_zval (return_value , arydata );
288283 }
289284 break ;
290- } else if (key_str ) {
291- MSGPACK_WARNING (
292- "[msgpack] (%s) key is string" ,
293- __FUNCTION__ );
294- zval_ptr_dtor (* value );
295- return FAILURE ;
296- } else {
297- MSGPACK_WARNING (
298- "[msgpack] (%s) key is not string nor array" ,
299- __FUNCTION__ );
300- zval_ptr_dtor (* value );
301- return FAILURE ;
302285 }
303- }
304- } ZEND_HASH_FOREACH_END ();
305-
306- zval_ptr_dtor (* value );
307- return SUCCESS ;
286+ case HASH_KEY_IS_STRING :
287+ MSGPACK_WARNING ("[msgpack] (%s) key is string" , __FUNCTION__ );
288+ zval_ptr_dtor (* value );
289+ return FAILURE ;
290+ default :
291+ MSGPACK_WARNING ("[msgpack] (%s) key is not string nor array" , __FUNCTION__ );
292+ zval_ptr_dtor (* value );
293+ return FAILURE ;
294+ }
308295 }
309- }
310- else
311- {
312- // shouldn't reach
313- MSGPACK_WARNING (
314- "[msgpack] (%s) template is not array" ,
315- __FUNCTION__ );
316- zval_ptr_dtor (* value );
317- return FAILURE ;
296+
297+ //zval_ptr_dtor(*value);
298+ return SUCCESS ;
318299 }
319300
320301 // shouldn't reach
321302 zval_ptr_dtor (* value );
322303 return FAILURE ;
304+
323305}
306+
324307int msgpack_convert_object (zval * return_value , zval * tpl , zval * * value ) {
325308 zend_class_entry * ce ;
326309
@@ -472,13 +455,13 @@ int msgpack_convert_object(zval *return_value, zval *tpl, zval **value) {
472455
473456 if (convert_function ) {
474457 zval nv ;
475- // if (convert_function(&nv, str_key , &data ) != SUCCESS) {
476- // // zval_ptr_dtor(& aryval);
477- // MSGPACK_WARNING("[msgpack] (%s) "
478- // "convert failure in convert_object",
479- // __FUNCTION__);
480- // return FAILURE;
481- // }
458+ if (convert_function (& nv , data , & aryval ) != SUCCESS ) {
459+ zval_ptr_dtor (aryval );
460+ MSGPACK_WARNING ("[msgpack] (%s) "
461+ "convert failure in convert_object" ,
462+ __FUNCTION__ );
463+ return FAILURE ;
464+ }
482465
483466 //zend_update_property(ce, return_value, str_key->val, str_key->len, &nv);
484467 } else {
0 commit comments