static void to_zval_read_aggregation(const char *structure, zval *zarr, /* initialized array */ const field_descriptor *descriptors, res_context *ctx) { const field_descriptor *descr; assert(Z_TYPE_P(zarr) == IS_ARRAY); assert(Z_ARRVAL_P(zarr) != NULL); for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) { zval *new_zv, tmp; if (descr->to_zval == NULL) { do_to_zval_err(ctx, "No information on how to convert native " "field into value for key '%s'", descr->name); break; } ZVAL_NULL(&tmp); new_zv = zend_symtable_str_update(Z_ARRVAL_P(zarr), descr->name, descr->name_size - 1, &tmp); zend_llist_add_element(&ctx->keys, (void*)&descr->name); descr->to_zval(structure + descr->field_offset, new_zv, ctx); zend_llist_remove_tail(&ctx->keys); } }
/** * Updates an array property */ int zephir_update_property_array(zval *object, const char *property, zend_uint property_length, const zval *index, zval *value) { zval tmp; int separated = 0; if (Z_TYPE_P(object) == IS_OBJECT) { zephir_read_property(&tmp, object, property, property_length, PH_NOISY | PH_READONLY); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp)) { if (Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } /** Convert the value to array if not is an array */ if (Z_TYPE(tmp) != IS_ARRAY) { if (separated) { convert_to_array(&tmp); } else { array_init(&tmp); separated = 1; } Z_DELREF(tmp); } Z_TRY_ADDREF_P(value); if (Z_TYPE_P(index) == IS_STRING) { zend_symtable_str_update(Z_ARRVAL(tmp), Z_STRVAL_P(index), Z_STRLEN_P(index), value); } else if (Z_TYPE_P(index) == IS_LONG) { zend_hash_index_update(Z_ARRVAL(tmp), Z_LVAL_P(index), value); } else if (Z_TYPE_P(index) == IS_NULL) { zend_hash_next_index_insert(Z_ARRVAL(tmp), value); } if (separated) { zephir_update_property_zval(object, property, property_length, &tmp); } } return SUCCESS; }