Fix error: redefinition of typedef 'php_http_message_t' during RHEL build
[m6w6/ext-http] / php_http_params.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 static php_http_params_token_t def_param_sep = {",", 1}, *def_param_sep_ptr[] = {&def_param_sep, NULL};
16 static php_http_params_token_t def_arg_sep = {";", 1}, *def_arg_sep_ptr[] = {&def_arg_sep, NULL};
17 static php_http_params_token_t def_val_sep = {"=", 1}, *def_val_sep_ptr[] = {&def_val_sep, NULL};
18 static php_http_params_opts_t def_opts = {
19 .param = def_param_sep_ptr,
20 .arg = def_arg_sep_ptr,
21 .val = def_val_sep_ptr
22 };
23
24 PHP_HTTP_API php_http_params_opts_t *php_http_params_opts_default_get(php_http_params_opts_t *opts)
25 {
26 if (!opts) {
27 opts = emalloc(sizeof(*opts));
28 }
29
30 memcpy(opts, &def_opts, sizeof(def_opts));
31
32 return opts;
33 }
34
35 typedef struct php_http_params_state {
36 php_http_params_token_t input;
37 php_http_params_token_t param;
38 php_http_params_token_t arg;
39 php_http_params_token_t val;
40 struct {
41 zval **param;
42 zval **args;
43 zval **val;
44 } current;
45 } php_http_params_state_t;
46
47 static inline void sanitize_string(char *str, size_t len, zval *zv TSRMLS_DC)
48 {
49 /* trim whitespace */
50 php_trim(str, len, NULL, 0, zv, 3 TSRMLS_CC);
51
52 /* dequote */
53 if (Z_STRVAL_P(zv)[0] == '"' && Z_STRVAL_P(zv)[Z_STRLEN_P(zv) - 1] == '"') {
54 size_t deq_len = Z_STRLEN_P(zv) - 2;
55 char *deq = estrndup(Z_STRVAL_P(zv) + 1, deq_len);
56
57 zval_dtor(zv);
58 ZVAL_STRINGL(zv, deq, deq_len, 0);
59 }
60
61 /* strip slashes */
62 php_stripslashes(Z_STRVAL_P(zv), &Z_STRLEN_P(zv) TSRMLS_CC);
63 }
64
65 static void push_param(HashTable *params, php_http_params_state_t *state, const php_http_params_opts_t *opts TSRMLS_DC)
66 {
67 if (state->val.str) {
68 if (0 < (state->val.len = state->input.str - state->val.str)) {
69 sanitize_string(state->val.str, state->val.len, *(state->current.val) TSRMLS_CC);
70 }
71 } else if (state->arg.str) {
72 if (0 < (state->arg.len = state->input.str - state->arg.str)) {
73 zval *val, key;
74
75 INIT_PZVAL(&key);
76 sanitize_string(state->arg.str, state->arg.len, &key TSRMLS_CC);
77 if (Z_STRLEN(key)) {
78 MAKE_STD_ZVAL(val);
79 ZVAL_TRUE(val);
80 zend_symtable_update(Z_ARRVAL_PP(state->current.args), Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &val, sizeof(zval *), (void *) &state->current.val);
81 }
82 zval_dtor(&key);
83 }
84 } else if (state->param.str) {
85 if (0 < (state->param.len = state->input.str - state->param.str)) {
86 zval *prm, *arg, *val, key;
87
88 INIT_PZVAL(&key);
89 sanitize_string(state->param.str, state->param.len, &key TSRMLS_CC);
90 if (Z_STRLEN(key)) {
91 MAKE_STD_ZVAL(prm);
92 array_init(prm);
93 MAKE_STD_ZVAL(val);
94 ZVAL_TRUE(val);
95 zend_hash_update(Z_ARRVAL_P(prm), "value", sizeof("value"), (void *) &val, sizeof(zval *), (void *) &state->current.val);
96
97 MAKE_STD_ZVAL(arg);
98 array_init(arg);
99 zend_hash_update(Z_ARRVAL_P(prm), "arguments", sizeof("arguments"), (void *) &arg, sizeof(zval *), (void *) &state->current.args);
100
101 zend_symtable_update(params, Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &prm, sizeof(zval *), (void *) &state->current.param);
102 }
103 zval_dtor(&key);
104 }
105 }
106 }
107
108 static inline zend_bool check_str(const char *chk_str, size_t chk_len, const char *sep_str, size_t sep_len) {
109 return 0 < sep_len && chk_len >= sep_len && !memcmp(chk_str, sep_str, sep_len);
110 }
111
112 static size_t check_sep(php_http_params_state_t *state, php_http_params_token_t **separators)
113 {
114 php_http_params_token_t **sep = separators;
115
116 if (sep) while (*sep) {
117 if (check_str(state->input.str, state->input.len, (*sep)->str, (*sep)->len)) {
118 return (*sep)->len;
119 }
120 ++sep;
121 }
122 return 0;
123 }
124
125 PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t *opts TSRMLS_DC)
126 {
127 php_http_params_state_t state = {
128 .input.str = opts->input.str,
129 .input.len = opts->input.len,
130 .param.str = NULL,
131 .param.len = 0,
132 .arg.str = NULL,
133 .arg.len = 0,
134 .val.str = NULL,
135 .val.len = 0
136 };
137
138 if (!params) {
139 ALLOC_HASHTABLE(params);
140 ZEND_INIT_SYMTABLE(params);
141 }
142
143 while (state.input.len) {
144 if (!state.param.str) {
145 /* initialize */
146 state.param.str = state.input.str;
147 } else {
148 size_t sep_len;
149 /* are we at a param separator? */
150 if (0 < (sep_len = check_sep(&state, opts->param))) {
151 push_param(params, &state, opts TSRMLS_CC);
152
153 /* start off with a new param */
154 state.param.str = state.input.str + sep_len;
155 state.param.len = 0;
156 state.arg.str = NULL;
157 state.arg.len = 0;
158 state.val.str = NULL;
159 state.val.len = 0;
160 } else
161 /* are we at an arg separator? */
162 if (0 < (sep_len = check_sep(&state, opts->arg))) {
163 push_param(params, &state, opts TSRMLS_CC);
164
165 /* continue with a new arg */
166 state.arg.str = state.input.str + sep_len;
167 state.arg.len = 0;
168 state.val.str = NULL;
169 state.val.len = 0;
170 } else
171 /* are we at a val separator? */
172 if (0 < (sep_len = check_sep(&state, opts->val))) {
173 /* only handle separator if we're not already reading in a val */
174 if (!state.val.str) {
175 push_param(params, &state, opts TSRMLS_CC);
176
177 state.val.str = state.input.str + sep_len;
178 state.val.len = 0;
179 }
180 }
181 }
182
183 ++state.input.str;
184 --state.input.len;
185 }
186 /* finalize */
187 push_param(params, &state, opts TSRMLS_CC);
188
189 return params;
190 }
191
192 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpParams, method, 0, req_args)
193 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpParams, method, 0)
194 #define PHP_HTTP_PARAMS_ME(method, visibility) PHP_ME(HttpParams, method, PHP_HTTP_ARGS(HttpParams, method), visibility)
195 #define PHP_HTTP_PARAMS_GME(method, visibility) PHP_ME(HttpParams, method, PHP_HTTP_ARGS(HttpParams, __getter), visibility)
196
197 PHP_HTTP_BEGIN_ARGS(__construct, 0)
198 PHP_HTTP_ARG_VAL(params, 0)
199 PHP_HTTP_ARG_VAL(param_sep, 0)
200 PHP_HTTP_ARG_VAL(arg_sep, 0)
201 PHP_HTTP_ARG_VAL(val_sep, 0)
202 PHP_HTTP_END_ARGS;
203
204 PHP_HTTP_EMPTY_ARGS(toArray);
205 PHP_HTTP_EMPTY_ARGS(toString);
206
207 PHP_HTTP_BEGIN_ARGS(offsetExists, 1)
208 PHP_HTTP_ARG_VAL(name, 0)
209 PHP_HTTP_END_ARGS;
210
211 PHP_HTTP_BEGIN_ARGS(offsetUnset, 1)
212 PHP_HTTP_ARG_VAL(name, 0)
213 PHP_HTTP_END_ARGS;
214
215 PHP_HTTP_BEGIN_ARGS(offsetGet, 1)
216 PHP_HTTP_ARG_VAL(name, 0)
217 PHP_HTTP_END_ARGS;
218
219 PHP_HTTP_BEGIN_ARGS(offsetSet, 2)
220 PHP_HTTP_ARG_VAL(name, 0)
221 PHP_HTTP_ARG_VAL(value, 0)
222 PHP_HTTP_END_ARGS;
223
224 zend_class_entry *php_http_params_class_entry;
225 zend_function_entry php_http_params_method_entry[] = {
226 PHP_HTTP_PARAMS_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
227
228 PHP_HTTP_PARAMS_ME(toArray, ZEND_ACC_PUBLIC)
229 PHP_HTTP_PARAMS_ME(toString, ZEND_ACC_PUBLIC)
230 ZEND_MALIAS(HttpParams, __toString, toString, PHP_HTTP_ARGS(HttpParams, toString), ZEND_ACC_PUBLIC)
231
232 PHP_HTTP_PARAMS_ME(offsetExists, ZEND_ACC_PUBLIC)
233 PHP_HTTP_PARAMS_ME(offsetUnset, ZEND_ACC_PUBLIC)
234 PHP_HTTP_PARAMS_ME(offsetSet, ZEND_ACC_PUBLIC)
235 PHP_HTTP_PARAMS_ME(offsetGet, ZEND_ACC_PUBLIC)
236
237 EMPTY_FUNCTION_ENTRY
238 };
239
240 PHP_MINIT_FUNCTION(http_params)
241 {
242 PHP_HTTP_REGISTER_CLASS(http, Params, http_params, php_http_object_class_entry, 0);
243
244 zend_class_implements(php_http_params_class_entry TSRMLS_CC, 1, zend_ce_arrayaccess);
245
246 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_PARAM_SEP"), ZEND_STRL(",") TSRMLS_CC);
247 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_ARG_SEP"), ZEND_STRL(";") TSRMLS_CC);
248 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_VAL_SEP"), ZEND_STRL("=") TSRMLS_CC);
249 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("COOKIE_PARAM_SEP"), ZEND_STRL("") TSRMLS_CC);
250
251 zend_declare_property_null(php_http_params_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC TSRMLS_CC);
252 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("param_sep"), ZEND_STRL(","), ZEND_ACC_PUBLIC TSRMLS_CC);
253 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("arg_sep"), ZEND_STRL(";"), ZEND_ACC_PUBLIC TSRMLS_CC);
254 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("val_sep"), ZEND_STRL("="), ZEND_ACC_PUBLIC TSRMLS_CC);
255
256 return SUCCESS;
257 }
258
259 static php_http_params_token_t **parse_sep(zval *zv TSRMLS_DC)
260 {
261 zval **sep;
262 HashPosition pos;
263 php_http_params_token_t **ret, **tmp;
264
265 if (!zv) {
266 return NULL;
267 }
268
269 zv = php_http_ztyp(IS_ARRAY, zv);
270 ret = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(zv)) + 1, sizeof(*ret));
271
272 tmp = ret;
273 FOREACH_VAL(pos, zv, sep) {
274 zval *zt = php_http_ztyp(IS_STRING, *sep);
275
276 if (Z_STRLEN_P(zt)) {
277 *tmp = emalloc(sizeof(**tmp));
278 (*tmp)->str = estrndup(Z_STRVAL_P(zt), (*tmp)->len = Z_STRLEN_P(zt));
279 ++tmp;
280 }
281 zval_ptr_dtor(&zt);
282 }
283 zval_ptr_dtor(&zv);
284
285 *tmp = NULL;
286 return ret;
287 }
288
289 static void free_sep(php_http_params_token_t **separator) {
290 php_http_params_token_t **sep = separator;
291 if (sep) {
292 while (*sep) {
293 STR_FREE((*sep)->str);
294 efree(*sep);
295 ++sep;
296 }
297 efree(separator);
298 }
299 }
300
301 PHP_METHOD(HttpParams, __construct)
302 {
303 with_error_handling(EH_THROW, php_http_exception_class_entry) {
304 zval *zcopy, *zparams = NULL, *param_sep = NULL, *arg_sep = NULL, *val_sep = NULL;
305
306 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z/z/z/", &zparams, &param_sep, &arg_sep, &val_sep)) {
307 switch (ZEND_NUM_ARGS()) {
308 case 4:
309 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC);
310 /* no break */
311 case 3:
312 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep TSRMLS_CC);
313 /* no break */
314 case 2:
315 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC);
316 /* no break */
317 }
318
319 if (zparams) {
320 switch (Z_TYPE_P(zparams)) {
321 case IS_OBJECT:
322 case IS_ARRAY:
323 zcopy = php_http_zsep(1, IS_ARRAY, zparams);
324 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zcopy TSRMLS_CC);
325 zval_ptr_dtor(&zcopy);
326 break;
327 default:
328 zcopy = php_http_ztyp(IS_STRING, zparams);
329 if (Z_STRLEN_P(zcopy)) {
330 php_http_params_opts_t opts = {
331 .input.str = Z_STRVAL_P(zcopy),
332 .input.len = Z_STRLEN_P(zcopy),
333 .param = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC) TSRMLS_CC),
334 .arg = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC) TSRMLS_CC),
335 .val = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC) TSRMLS_CC)
336 };
337
338 MAKE_STD_ZVAL(zparams);
339 array_init(zparams);
340 php_http_params_parse(Z_ARRVAL_P(zparams), &opts TSRMLS_CC);
341 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
342 zval_ptr_dtor(&zparams);
343
344 free_sep(opts.param);
345 free_sep(opts.arg);
346 free_sep(opts.val);
347 }
348 zval_ptr_dtor(&zcopy);
349 break;
350 }
351 } else {
352 MAKE_STD_ZVAL(zparams);
353 array_init(zparams);
354 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
355 zval_ptr_dtor(&zparams);
356 }
357 }
358 } end_error_handling();
359 }
360
361 PHP_METHOD(HttpParams, toArray)
362 {
363 if (SUCCESS != zend_parse_parameters_none()) {
364 RETURN_FALSE;
365 }
366 RETURN_PROP(php_http_params_class_entry, "params");
367 }
368
369 PHP_METHOD(HttpParams, toString)
370 {
371 zval *zparams, *zpsep, *zasep, *zvsep;
372 zval **zparam, **zvalue, **zargs, **zarg;
373 HashPosition pos1, pos2;
374 php_http_array_hashkey_t key1 = php_http_array_hashkey_init(0), key2 = php_http_array_hashkey_init(0);
375 php_http_buffer_t buf;
376
377 zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
378 zpsep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC));
379 zasep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC));
380 zvsep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC));
381 php_http_buffer_init(&buf);
382
383 FOREACH_KEYVAL(pos1, zparams, key1, zparam) {
384 /* new param ? */
385 if (PHP_HTTP_BUFFER_LEN(&buf)) {
386 php_http_buffer_append(&buf, Z_STRVAL_P(zpsep), Z_STRLEN_P(zpsep));
387 }
388
389 /* add name */
390 if (key1.type == HASH_KEY_IS_STRING) {
391 php_http_buffer_append(&buf, key1.str, key1.len - 1);
392 } else {
393 php_http_buffer_appendf(&buf, "%lu", key1.num);
394 }
395
396 if (Z_TYPE_PP(zparam) == IS_ARRAY) {
397 /* got a value? */
398 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(zparam), ZEND_STRS("value"), (void *) &zvalue)) {
399 if (Z_TYPE_PP(zvalue) != IS_BOOL) {
400 zval *tmp = php_http_ztyp(IS_STRING, *zvalue);
401
402 php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
403 php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
404 zval_ptr_dtor(&tmp);
405 } else if (!Z_BVAL_PP(zvalue)) {
406 php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
407 php_http_buffer_appends(&buf, "0");
408 }
409 }
410 /* add arguments */
411 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(zparam), ZEND_STRS("arguments"), (void *) &zargs)) {
412 if (Z_TYPE_PP(zargs) == IS_ARRAY) {
413 FOREACH_KEYVAL(pos2, *zargs, key2, zarg) {
414 /* new arg? */
415 if (PHP_HTTP_BUFFER_LEN(&buf)) {
416 php_http_buffer_append(&buf, Z_STRVAL_P(zasep), Z_STRLEN_P(zasep));
417 }
418
419 /* add name */
420 if (key2.type == HASH_KEY_IS_STRING) {
421 php_http_buffer_append(&buf, key2.str, key2.len - 1);
422 } else {
423 php_http_buffer_appendf(&buf, "%lu", key2.num);
424 }
425 /* add value */
426 if (Z_TYPE_PP(zarg) != IS_BOOL) {
427 zval *tmp = php_http_ztyp(IS_STRING, *zarg);
428 int escaped_len;
429
430 Z_STRVAL_P(tmp) = php_addslashes(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &escaped_len, 1 TSRMLS_CC);
431 php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
432 if (escaped_len != Z_STRLEN_P(tmp)) {
433 php_http_buffer_appends(&buf, "\"");
434 php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) = escaped_len);
435 php_http_buffer_appends(&buf, "\"");
436 } else {
437 php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
438 }
439 zval_ptr_dtor(&tmp);
440 } else if (!Z_BVAL_PP(zarg)) {
441 php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
442 php_http_buffer_appends(&buf, "0");
443 }
444 }
445 }
446 }
447 }
448 }
449
450 zval_ptr_dtor(&zparams);
451 zval_ptr_dtor(&zpsep);
452 zval_ptr_dtor(&zasep);
453 zval_ptr_dtor(&zvsep);
454
455 php_http_buffer_fix(&buf);
456 php_http_buffer_shrink(&buf);
457 RETVAL_PHP_HTTP_BUFFER_VAL(&buf);
458 }
459
460 PHP_METHOD(HttpParams, offsetExists)
461 {
462 char *name_str;
463 int name_len;
464
465 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
466 zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
467
468 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
469 RETVAL_BOOL(Z_TYPE_PP(zparam) != IS_NULL);
470 } else {
471 RETVAL_FALSE;
472 }
473 zval_ptr_dtor(&zparams);
474 }
475 }
476
477 PHP_METHOD(HttpParams, offsetGet)
478 {
479 char *name_str;
480 int name_len;
481
482 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
483 zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
484
485 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
486 RETVAL_ZVAL(*zparam, 1, 0);
487 }
488
489 zval_ptr_dtor(&zparams);
490 }
491 }
492
493
494 PHP_METHOD(HttpParams, offsetUnset)
495 {
496 char *name_str;
497 int name_len;
498
499 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
500 zval *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
501
502 zend_symtable_del(Z_ARRVAL_P(zparams), name_str, name_len + 1);
503 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
504
505 zval_ptr_dtor(&zparams);
506 }
507 }
508
509 PHP_METHOD(HttpParams, offsetSet)
510 {
511 zval *nvalue;
512 char *name_str;
513 int name_len;
514
515 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name_str, &name_len, &nvalue)) {
516 zval **zparam, *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
517
518 if (name_len) {
519 if (Z_TYPE_P(nvalue) == IS_ARRAY) {
520 zval *new_zparam;
521
522 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
523 new_zparam = php_http_zsep(1, IS_ARRAY, *zparam);
524 array_join(Z_ARRVAL_P(nvalue), Z_ARRVAL_P(new_zparam), 0, 0);
525 } else {
526 new_zparam = nvalue;
527 Z_ADDREF_P(new_zparam);
528 }
529 add_assoc_zval_ex(zparams, name_str, name_len + 1, new_zparam);
530 } else {
531 zval *tmp;
532
533 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
534 tmp = php_http_zsep(1, IS_ARRAY, *zparam);
535 } else {
536 MAKE_STD_ZVAL(tmp);
537 array_init(tmp);
538 }
539
540 Z_ADDREF_P(nvalue);
541 add_assoc_zval_ex(tmp, ZEND_STRS("value"), nvalue);
542 add_assoc_zval_ex(zparams, name_str, name_len + 1, tmp);
543 }
544 } else {
545 zval *tmp = php_http_ztyp(IS_STRING, nvalue), *arr;
546
547 MAKE_STD_ZVAL(arr);
548 array_init(arr);
549 add_assoc_bool_ex(arr, ZEND_STRS("value"), 1);
550 add_assoc_zval_ex(zparams, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1, arr);
551 zval_ptr_dtor(&tmp);
552 }
553
554 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
555 zval_ptr_dtor(&zparams);
556 }
557 }
558
559 /*
560 * Local variables:
561 * tab-width: 4
562 * c-basic-offset: 4
563 * End:
564 * vim600: noet sw=4 ts=4 fdm=marker
565 * vim<600: noet sw=4 ts=4
566 */
567