+#define http_zset(t, z) _http_zset((t), (z))
+static inline zval *_http_zset(int type, zval *z)
+{
+ if (Z_TYPE_P(z) != type) {
+ switch (type) {
+ case IS_NULL: convert_to_null(z); break;
+ case IS_BOOL: convert_to_boolean(z); break;
+ case IS_LONG: convert_to_long(z); break;
+ case IS_DOUBLE: convert_to_double(z); break;
+ case IS_STRING: convert_to_string(z); break;
+ case IS_ARRAY: convert_to_array(z); break;
+ case IS_OBJECT: convert_to_object(z); break;
+ }
+ }
+ return z;
+}
+#define http_zsep(t, z) _http_zsep_ex((t), (z), NULL)
+#define http_zsep_ex(t, z, p) _http_zsep_ex((t), (z), (p))
+static inline zval *_http_zsep_ex(int type, zval *z, zval **p) {
+ SEPARATE_ARG_IF_REF(z);
+ if (Z_TYPE_P(z) != type) {
+ switch (type) {
+ case IS_NULL: convert_to_null_ex(&z); break;
+ case IS_BOOL: convert_to_boolean_ex(&z); break;
+ case IS_LONG: convert_to_long_ex(&z); break;
+ case IS_DOUBLE: convert_to_double_ex(&z); break;
+ case IS_STRING: convert_to_string_ex(&z); break;
+ case IS_ARRAY: convert_to_array_ex(&z); break;
+ case IS_OBJECT: convert_to_object_ex(&z); break;
+ }
+ }
+ if (p) {
+ *p = z;
+ }
+ return z;
+}
+
+typedef struct _HashKey {
+ char *str;
+ uint len;
+ ulong num;
+ uint dup:1;
+ uint type:31;
+} HashKey;
+#define initHashKey(dup) {NULL, 0, 0, (dup), 0}
+
+#define FOREACH_VAL(pos, array, val) FOREACH_HASH_VAL(pos, Z_ARRVAL_P(array), val)
+#define FOREACH_HASH_VAL(pos, hash, val) \
+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
+ zend_hash_get_current_data_ex(hash, (void *) &val, &pos) == SUCCESS; \
+ zend_hash_move_forward_ex(hash, &pos))
+
+#define FOREACH_KEY(pos, array, key) FOREACH_HASH_KEY(pos, Z_ARRVAL_P(array), key)
+#define FOREACH_HASH_KEY(pos, hash, _key) \
+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
+ ((_key).type = zend_hash_get_current_key_ex(hash, &(_key).str, &(_key).len, &(_key).num, (zend_bool) (_key).dup, &pos)) != HASH_KEY_NON_EXISTANT; \
+ zend_hash_move_forward_ex(hash, &pos)) \
+
+#define FOREACH_KEYVAL(pos, array, key, val) FOREACH_HASH_KEYVAL(pos, Z_ARRVAL_P(array), key, val)
+#define FOREACH_HASH_KEYVAL(pos, hash, _key, val) \
+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
+ ((_key).type = zend_hash_get_current_key_ex(hash, &(_key).str, &(_key).len, &(_key).num, (zend_bool) (_key).dup, &pos)) != HASH_KEY_NON_EXISTANT && \
+ zend_hash_get_current_data_ex(hash, (void *) &val, &pos) == SUCCESS; \
+ zend_hash_move_forward_ex(hash, &pos))
+
+#define array_copy(src, dst) zend_hash_copy(dst, src, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *))
+#define ARRAY_JOIN_STRONLY 1
+#define ARRAY_JOIN_PRETTIFY 2
+#define array_join(src, dst, append, flags) zend_hash_apply_with_arguments(src HTTP_ZAPI_HASH_TSRMLS_CC, (append)?apply_array_append_func:apply_array_merge_func, 2, dst, (int)flags)
+
+extern int apply_array_append_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
+extern int apply_array_merge_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
+