code cleanup
[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 = {{NULL,0}, {NULL,0}, {NULL,0}, {NULL,0}, {NULL,NULL,NULL}};
128
129 state.input.str = opts->input.str;
130 state.input.len = opts->input.len;
131
132 if (!params) {
133 ALLOC_HASHTABLE(params);
134 ZEND_INIT_SYMTABLE(params);
135 }
136
137 while (state.input.len) {
138 if (!state.param.str) {
139 /* initialize */
140 state.param.str = state.input.str;
141 } else {
142 size_t sep_len;
143 /* are we at a param separator? */
144 if (0 < (sep_len = check_sep(&state, opts->param))) {
145 push_param(params, &state, opts TSRMLS_CC);
146
147 /* start off with a new param */
148 state.param.str = state.input.str + sep_len;
149 state.param.len = 0;
150 state.arg.str = NULL;
151 state.arg.len = 0;
152 state.val.str = NULL;
153 state.val.len = 0;
154 } else
155 /* are we at an arg separator? */
156 if (0 < (sep_len = check_sep(&state, opts->arg))) {
157 push_param(params, &state, opts TSRMLS_CC);
158
159 /* continue with a new arg */
160 state.arg.str = state.input.str + sep_len;
161 state.arg.len = 0;
162 state.val.str = NULL;
163 state.val.len = 0;
164 } else
165 /* are we at a val separator? */
166 if (0 < (sep_len = check_sep(&state, opts->val))) {
167 /* only handle separator if we're not already reading in a val */
168 if (!state.val.str) {
169 push_param(params, &state, opts TSRMLS_CC);
170
171 state.val.str = state.input.str + sep_len;
172 state.val.len = 0;
173 }
174 }
175 }
176
177 ++state.input.str;
178 --state.input.len;
179 }
180 /* finalize */
181 push_param(params, &state, opts TSRMLS_CC);
182
183 return params;
184 }
185
186 PHP_HTTP_API php_http_buffer_t *php_http_params_to_string(php_http_buffer_t *buf, HashTable *params, const char *pss, size_t psl, const char *ass, size_t asl, const char *vss, size_t vsl TSRMLS_DC)
187 {
188 zval **zparam;
189 HashPosition pos1, pos2;
190 php_http_array_hashkey_t key1 = php_http_array_hashkey_init(0), key2 = php_http_array_hashkey_init(0);
191
192 if (!buf) {
193 buf = php_http_buffer_init(NULL);
194 }
195
196 FOREACH_HASH_KEYVAL(pos1, params, key1, zparam) {
197 /* new param ? */
198 if (PHP_HTTP_BUFFER_LEN(buf)) {
199 php_http_buffer_append(buf, pss, psl);
200 }
201
202 /* add name */
203 if (key1.type == HASH_KEY_IS_STRING) {
204 php_http_buffer_append(buf, key1.str, key1.len - 1);
205 } else {
206 php_http_buffer_appendf(buf, "%lu", key1.num);
207 }
208
209 if (Z_TYPE_PP(zparam) != IS_ARRAY) {
210 zval *tmp = php_http_ztyp(IS_STRING, *zparam);
211
212 php_http_buffer_append(buf, vss, vsl);
213 php_http_buffer_append(buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
214 zval_ptr_dtor(&tmp);
215 } else {
216 zval **zvalue, **zargs, **zarg;
217
218 /* got a value? */
219 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(zparam), ZEND_STRS("value"), (void *) &zvalue)) {
220 if (Z_TYPE_PP(zvalue) != IS_BOOL) {
221 zval *tmp = php_http_ztyp(IS_STRING, *zvalue);
222
223 php_http_buffer_append(buf, vss, vsl);
224 php_http_buffer_append(buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
225 zval_ptr_dtor(&tmp);
226 } else if (!Z_BVAL_PP(zvalue)) {
227 php_http_buffer_append(buf, vss, vsl);
228 php_http_buffer_appends(buf, "0");
229 }
230 }
231 /* add arguments */
232 if (SUCCESS != zend_hash_find(Z_ARRVAL_PP(zparam), ZEND_STRS("arguments"), (void *) &zargs)) {
233 zargs = zparam;
234 }
235
236 if (Z_TYPE_PP(zargs) == IS_ARRAY) {
237 FOREACH_KEYVAL(pos2, *zargs, key2, zarg) {
238 /* skip "value" if zargs == zparam */
239 if (zargs == zparam && key2.type == HASH_KEY_IS_STRING && !strcmp(key2.str, "value")) {
240 continue;
241 }
242
243 /* new arg? */
244 if (PHP_HTTP_BUFFER_LEN(buf)) {
245 php_http_buffer_append(buf, ass, asl);
246 }
247
248 /* add name */
249 if (key2.type == HASH_KEY_IS_STRING) {
250 php_http_buffer_append(buf, key2.str, key2.len - 1);
251 } else {
252 php_http_buffer_appendf(buf, "%lu", key2.num);
253 }
254 /* add value */
255 if (Z_TYPE_PP(zarg) != IS_BOOL) {
256 zval *tmp = php_http_ztyp(IS_STRING, *zarg);
257 int escaped_len;
258
259 Z_STRVAL_P(tmp) = php_addslashes(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &escaped_len, 1 TSRMLS_CC);
260 php_http_buffer_append(buf, vss, vsl);
261 if (escaped_len != Z_STRLEN_P(tmp)) {
262 php_http_buffer_appends(buf, "\"");
263 php_http_buffer_append(buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) = escaped_len);
264 php_http_buffer_appends(buf, "\"");
265 } else {
266 php_http_buffer_append(buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
267 }
268 zval_ptr_dtor(&tmp);
269 } else if (!Z_BVAL_PP(zarg)) {
270 php_http_buffer_append(buf, vss, vsl);
271 php_http_buffer_appends(buf, "0");
272 }
273 }
274 }
275 }
276 }
277
278 php_http_buffer_shrink(buf);
279 php_http_buffer_fix(buf);
280
281 return buf;
282 }
283
284 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpParams, method, 0, req_args)
285 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpParams, method, 0)
286 #define PHP_HTTP_PARAMS_ME(method, visibility) PHP_ME(HttpParams, method, PHP_HTTP_ARGS(HttpParams, method), visibility)
287 #define PHP_HTTP_PARAMS_GME(method, visibility) PHP_ME(HttpParams, method, PHP_HTTP_ARGS(HttpParams, __getter), visibility)
288
289 PHP_HTTP_BEGIN_ARGS(__construct, 0)
290 PHP_HTTP_ARG_VAL(params, 0)
291 PHP_HTTP_ARG_VAL(param_sep, 0)
292 PHP_HTTP_ARG_VAL(arg_sep, 0)
293 PHP_HTTP_ARG_VAL(val_sep, 0)
294 PHP_HTTP_END_ARGS;
295
296 PHP_HTTP_EMPTY_ARGS(toArray);
297 PHP_HTTP_EMPTY_ARGS(toString);
298
299 PHP_HTTP_BEGIN_ARGS(offsetExists, 1)
300 PHP_HTTP_ARG_VAL(name, 0)
301 PHP_HTTP_END_ARGS;
302
303 PHP_HTTP_BEGIN_ARGS(offsetUnset, 1)
304 PHP_HTTP_ARG_VAL(name, 0)
305 PHP_HTTP_END_ARGS;
306
307 PHP_HTTP_BEGIN_ARGS(offsetGet, 1)
308 PHP_HTTP_ARG_VAL(name, 0)
309 PHP_HTTP_END_ARGS;
310
311 PHP_HTTP_BEGIN_ARGS(offsetSet, 2)
312 PHP_HTTP_ARG_VAL(name, 0)
313 PHP_HTTP_ARG_VAL(value, 0)
314 PHP_HTTP_END_ARGS;
315
316 static zend_class_entry *php_http_params_class_entry;
317
318 zend_class_entry *php_http_params_get_class_entry(void)
319 {
320 return php_http_params_class_entry;
321 }
322
323 static zend_function_entry php_http_params_method_entry[] = {
324 PHP_HTTP_PARAMS_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
325
326 PHP_HTTP_PARAMS_ME(toArray, ZEND_ACC_PUBLIC)
327 PHP_HTTP_PARAMS_ME(toString, ZEND_ACC_PUBLIC)
328 ZEND_MALIAS(HttpParams, __toString, toString, PHP_HTTP_ARGS(HttpParams, toString), ZEND_ACC_PUBLIC)
329
330 PHP_HTTP_PARAMS_ME(offsetExists, ZEND_ACC_PUBLIC)
331 PHP_HTTP_PARAMS_ME(offsetUnset, ZEND_ACC_PUBLIC)
332 PHP_HTTP_PARAMS_ME(offsetSet, ZEND_ACC_PUBLIC)
333 PHP_HTTP_PARAMS_ME(offsetGet, ZEND_ACC_PUBLIC)
334
335 EMPTY_FUNCTION_ENTRY
336 };
337
338 PHP_MINIT_FUNCTION(http_params)
339 {
340 PHP_HTTP_REGISTER_CLASS(http, Params, http_params, php_http_object_get_class_entry(), 0);
341
342 zend_class_implements(php_http_params_class_entry TSRMLS_CC, 1, zend_ce_arrayaccess);
343
344 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_PARAM_SEP"), ZEND_STRL(",") TSRMLS_CC);
345 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_ARG_SEP"), ZEND_STRL(";") TSRMLS_CC);
346 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_VAL_SEP"), ZEND_STRL("=") TSRMLS_CC);
347 zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("COOKIE_PARAM_SEP"), ZEND_STRL("") TSRMLS_CC);
348
349 zend_declare_property_null(php_http_params_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC TSRMLS_CC);
350 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("param_sep"), ZEND_STRL(","), ZEND_ACC_PUBLIC TSRMLS_CC);
351 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("arg_sep"), ZEND_STRL(";"), ZEND_ACC_PUBLIC TSRMLS_CC);
352 zend_declare_property_stringl(php_http_params_class_entry, ZEND_STRL("val_sep"), ZEND_STRL("="), ZEND_ACC_PUBLIC TSRMLS_CC);
353
354 return SUCCESS;
355 }
356
357 static php_http_params_token_t **parse_sep(zval *zv TSRMLS_DC)
358 {
359 zval **sep;
360 HashPosition pos;
361 php_http_params_token_t **ret, **tmp;
362
363 if (!zv) {
364 return NULL;
365 }
366
367 zv = php_http_ztyp(IS_ARRAY, zv);
368 ret = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(zv)) + 1, sizeof(*ret));
369
370 tmp = ret;
371 FOREACH_VAL(pos, zv, sep) {
372 zval *zt = php_http_ztyp(IS_STRING, *sep);
373
374 if (Z_STRLEN_P(zt)) {
375 *tmp = emalloc(sizeof(**tmp));
376 (*tmp)->str = estrndup(Z_STRVAL_P(zt), (*tmp)->len = Z_STRLEN_P(zt));
377 ++tmp;
378 }
379 zval_ptr_dtor(&zt);
380 }
381 zval_ptr_dtor(&zv);
382
383 *tmp = NULL;
384 return ret;
385 }
386
387 static void free_sep(php_http_params_token_t **separator) {
388 php_http_params_token_t **sep = separator;
389 if (sep) {
390 while (*sep) {
391 STR_FREE((*sep)->str);
392 efree(*sep);
393 ++sep;
394 }
395 efree(separator);
396 }
397 }
398
399 PHP_METHOD(HttpParams, __construct)
400 {
401 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
402 zval *zcopy, *zparams = NULL, *param_sep = NULL, *arg_sep = NULL, *val_sep = NULL;
403
404 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z/z/z/", &zparams, &param_sep, &arg_sep, &val_sep)) {
405 switch (ZEND_NUM_ARGS()) {
406 case 4:
407 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC);
408 /* no break */
409 case 3:
410 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep TSRMLS_CC);
411 /* no break */
412 case 2:
413 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC);
414 /* no break */
415 }
416
417 if (zparams) {
418 switch (Z_TYPE_P(zparams)) {
419 case IS_OBJECT:
420 case IS_ARRAY:
421 zcopy = php_http_zsep(1, IS_ARRAY, zparams);
422 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zcopy TSRMLS_CC);
423 zval_ptr_dtor(&zcopy);
424 break;
425 default:
426 zcopy = php_http_ztyp(IS_STRING, zparams);
427 if (Z_STRLEN_P(zcopy)) {
428 php_http_params_opts_t opts = {
429 .input = {
430 .str = Z_STRVAL_P(zcopy),
431 .len = Z_STRLEN_P(zcopy)
432 },
433 .param = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC) TSRMLS_CC),
434 .arg = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC) TSRMLS_CC),
435 .val = parse_sep(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC) TSRMLS_CC)
436 };
437
438 MAKE_STD_ZVAL(zparams);
439 array_init(zparams);
440 php_http_params_parse(Z_ARRVAL_P(zparams), &opts TSRMLS_CC);
441 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
442 zval_ptr_dtor(&zparams);
443
444 free_sep(opts.param);
445 free_sep(opts.arg);
446 free_sep(opts.val);
447 }
448 zval_ptr_dtor(&zcopy);
449 break;
450 }
451 } else {
452 MAKE_STD_ZVAL(zparams);
453 array_init(zparams);
454 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
455 zval_ptr_dtor(&zparams);
456 }
457 }
458 } end_error_handling();
459 }
460
461 PHP_METHOD(HttpParams, toArray)
462 {
463 if (SUCCESS != zend_parse_parameters_none()) {
464 RETURN_FALSE;
465 }
466 RETURN_PROP(php_http_params_class_entry, "params");
467 }
468
469 PHP_METHOD(HttpParams, toString)
470 {
471 zval *zparams, *zpsep, *zasep, *zvsep;
472 php_http_buffer_t buf;
473
474 zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
475 zpsep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC));
476 zasep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC));
477 zvsep = php_http_ztyp(IS_STRING, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC));
478
479 php_http_buffer_init(&buf);
480 php_http_params_to_string(&buf, Z_ARRVAL_P(zparams), Z_STRVAL_P(zpsep), Z_STRLEN_P(zpsep), Z_STRVAL_P(zasep), Z_STRLEN_P(zasep), Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep) TSRMLS_CC);
481
482 zval_ptr_dtor(&zparams);
483 zval_ptr_dtor(&zpsep);
484 zval_ptr_dtor(&zasep);
485 zval_ptr_dtor(&zvsep);
486
487 RETVAL_PHP_HTTP_BUFFER_VAL(&buf);
488 }
489
490 PHP_METHOD(HttpParams, offsetExists)
491 {
492 char *name_str;
493 int name_len;
494
495 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
496 zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
497
498 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
499 RETVAL_BOOL(Z_TYPE_PP(zparam) != IS_NULL);
500 } else {
501 RETVAL_FALSE;
502 }
503 zval_ptr_dtor(&zparams);
504 }
505 }
506
507 PHP_METHOD(HttpParams, offsetGet)
508 {
509 char *name_str;
510 int name_len;
511
512 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
513 zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
514
515 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
516 RETVAL_ZVAL(*zparam, 1, 0);
517 }
518
519 zval_ptr_dtor(&zparams);
520 }
521 }
522
523
524 PHP_METHOD(HttpParams, offsetUnset)
525 {
526 char *name_str;
527 int name_len;
528
529 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
530 zval *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
531
532 zend_symtable_del(Z_ARRVAL_P(zparams), name_str, name_len + 1);
533 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
534
535 zval_ptr_dtor(&zparams);
536 }
537 }
538
539 PHP_METHOD(HttpParams, offsetSet)
540 {
541 zval *nvalue;
542 char *name_str;
543 int name_len;
544
545 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name_str, &name_len, &nvalue)) {
546 zval **zparam, *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC));
547
548 if (name_len) {
549 if (Z_TYPE_P(nvalue) == IS_ARRAY) {
550 zval *new_zparam;
551
552 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
553 new_zparam = php_http_zsep(1, IS_ARRAY, *zparam);
554 array_join(Z_ARRVAL_P(nvalue), Z_ARRVAL_P(new_zparam), 0, 0);
555 } else {
556 new_zparam = nvalue;
557 Z_ADDREF_P(new_zparam);
558 }
559 add_assoc_zval_ex(zparams, name_str, name_len + 1, new_zparam);
560 } else {
561 zval *tmp;
562
563 if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) {
564 tmp = php_http_zsep(1, IS_ARRAY, *zparam);
565 } else {
566 MAKE_STD_ZVAL(tmp);
567 array_init(tmp);
568 }
569
570 Z_ADDREF_P(nvalue);
571 add_assoc_zval_ex(tmp, ZEND_STRS("value"), nvalue);
572 add_assoc_zval_ex(zparams, name_str, name_len + 1, tmp);
573 }
574 } else {
575 zval *tmp = php_http_ztyp(IS_STRING, nvalue), *arr;
576
577 MAKE_STD_ZVAL(arr);
578 array_init(arr);
579 add_assoc_bool_ex(arr, ZEND_STRS("value"), 1);
580 add_assoc_zval_ex(zparams, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1, arr);
581 zval_ptr_dtor(&tmp);
582 }
583
584 zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC);
585 zval_ptr_dtor(&zparams);
586 }
587 }
588
589 /*
590 * Local variables:
591 * tab-width: 4
592 * c-basic-offset: 4
593 * End:
594 * vim600: noet sw=4 ts=4 fdm=marker
595 * vim<600: noet sw=4 ts=4
596 */
597