Skip to content

Commit fd19e23

Browse files
committed
Finish converting msgpack_convert_array
1 parent 3866934 commit fd19e23

File tree

1 file changed

+152
-169
lines changed

1 file changed

+152
-169
lines changed

msgpack_convert.c

Lines changed: 152 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -116,211 +116,194 @@ static inline int msgpack_convert_string_to_properties(
116116

117117
int 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+
324307
int 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

Comments
 (0)