summaryrefslogtreecommitdiff
path: root/ext/wddx
diff options
context:
space:
mode:
authorAndrei Zmievski <andrei@php.net>2001-11-18 01:16:03 +0000
committerAndrei Zmievski <andrei@php.net>2001-11-18 01:16:03 +0000
commita2f95abb6d60798c552267c1f42ca4e59308b357 (patch)
tree6471f37581c4a9294e3494c2306603311f4a5354 /ext/wddx
parent3744720899b2bcad515f113ed419a27ec098d8d9 (diff)
downloadphp-git-a2f95abb6d60798c552267c1f42ca4e59308b357.tar.gz
- Added support for parsing recordsets.
- Fixed a bug that sometimes would corrupt top-level element if it was a scalar one.
Diffstat (limited to 'ext/wddx')
-rw-r--r--ext/wddx/wddx.c142
1 files changed, 117 insertions, 25 deletions
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 5e39ddfd6c..315f21b0f7 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -31,6 +31,7 @@
#include "ext/standard/info.h"
#include "ext/standard/php_smart_str.h"
#include "ext/standard/html.h"
+#include "ext/standard/php_string.h"
#define WDDX_BUF_LEN 256
#define PHP_CLASS_NAME_VAR "php_class_name"
@@ -47,8 +48,10 @@
#define EL_STRUCT "struct"
#define EL_VALUE "value"
#define EL_VAR "var"
-#define EL_VAR_NAME "name"
+#define EL_NAME "name"
#define EL_VERSION "version"
+#define EL_RECORDSET "recordset"
+#define EL_FIELD "field"
#define php_wddx_deserialize(a,b) \
php_wddx_deserialize_ex((a)->value.str.val, (a)->value.str.len, (b))
@@ -72,7 +75,9 @@ typedef struct {
ST_NUMBER,
ST_STRING,
ST_BINARY,
- ST_STRUCT
+ ST_STRUCT,
+ ST_RECORDSET,
+ ST_FIELD
} type;
char *varname;
} st_entry;
@@ -80,6 +85,7 @@ typedef struct {
typedef struct {
int top, max;
char *varname;
+ zend_bool done;
void **elements;
} wddx_stack;
@@ -129,6 +135,7 @@ static int wddx_stack_init(wddx_stack *stack)
} else {
stack->max = STACK_BLOCK_SIZE;
stack->varname = NULL;
+ stack->done = 0;
return SUCCESS;
}
}
@@ -382,7 +389,7 @@ static void php_wddx_serialize_string(wddx_packet *packet, zval *var)
break;
default:
- if (iscntrl((int)*p)) {
+ if (iscntrl((int)*p) && *p != '\n') {
FLUSH_BUF();
sprintf(control_buf, WDDX_CHAR, *p);
php_wddx_add_chunk(packet, control_buf);
@@ -712,12 +719,14 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
} else if (!strcmp(name, EL_CHAR)) {
int i;
- char tmp_buf[2];
- for (i=0; atts[i]; i++) {
- if (!strcmp(atts[i], EL_CHAR_CODE) && atts[i+1]) {
- sprintf(tmp_buf, "%c", (char)strtol(atts[i+1], NULL, 16));
+ for (i = 0; atts[i]; i++) {
+ if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
+ char tmp_buf[2];
+
+ sprintf(tmp_buf, "%c", (char)strtol(atts[i], NULL, 16));
php_wddx_process_data(user_data, tmp_buf, strlen(tmp_buf));
+ break;
}
}
} else if (!strcmp(name, EL_NUMBER)) {
@@ -731,8 +740,8 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
} else if (!strcmp(name, EL_BOOLEAN)) {
int i;
- for (i=0; atts[i]; i++) {
- if (!strcmp(atts[i], EL_VALUE) && atts[i+1]) {
+ for (i = 0; atts[i]; i++) {
+ if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
ent.type = ST_BOOLEAN;
SET_STACK_VARNAME;
@@ -740,7 +749,8 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
INIT_PZVAL(ent.data);
Z_TYPE_P(ent.data) = IS_BOOL;
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
- php_wddx_process_data(user_data, atts[i+1], strlen(atts[i+1]));
+ php_wddx_process_data(user_data, atts[i], strlen(atts[i]));
+ break;
}
}
} else if (!strcmp(name, EL_NULL)) {
@@ -771,14 +781,83 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
} else if (!strcmp(name, EL_VAR)) {
int i;
- for (i=0; atts[i]; i++) {
- if (!strcmp(atts[i], EL_VAR_NAME) && atts[i+1]) {
- char *decoded_value;
+ for (i = 0; atts[i]; i++) {
+ if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
+ char *decoded;
+ int decoded_len;
+ decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
+ stack->varname = decoded;
+ break;
+ }
+ }
+ } else if (!strcmp(name, EL_RECORDSET)) {
+ int i;
+
+ ent.type = ST_RECORDSET;
+ SET_STACK_VARNAME;
+ MAKE_STD_ZVAL(ent.data);
+ array_init(ent.data);
+
+ for (i = 0; atts[i]; i++) {
+ if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
+ zval *tmp;
+ char *key;
+ char *p1, *p2, *endp;
+ char *decoded;
+ int decoded_len;
+
+ decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
+ endp = (char *)decoded + decoded_len;
+ p1 = (char *)decoded;
+ while ((p2 = php_memnstr(p1, ",", sizeof(",")-1, endp)) != NULL) {
+ key = estrndup(p1, p2 - p1);
+ MAKE_STD_ZVAL(tmp);
+ array_init(tmp);
+ add_assoc_zval_ex(ent.data, key, p2 - p1 + 1, tmp);
+ p1 = p2 + sizeof(",")-1;
+ efree(key);
+ }
+
+ if (p1 <= endp) {
+ MAKE_STD_ZVAL(tmp);
+ array_init(tmp);
+ add_assoc_zval_ex(ent.data, p1, endp - p1 + 1, tmp);
+ }
+
+ efree(decoded);
+ break;
+ }
+ }
+
+ wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
+ } else if (!strcmp(name, EL_FIELD)) {
+ int i;
+ st_entry ent;
+
+ ent.type = ST_FIELD;
+ ent.varname = NULL;
+ ent.data = NULL;
+
+ for (i = 0; atts[i]; i++) {
+ if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
+ char *decoded;
int decoded_len;
- decoded_value = xml_utf8_decode(atts[i+1],strlen(atts[i+1]),&decoded_len,"ISO-8859-1");
- stack->varname = decoded_value;
+ st_entry *recordset;
+ zval **field;
+
+ decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
+ if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS &&
+ recordset->type == ST_RECORDSET &&
+ zend_hash_find(Z_ARRVAL_P(recordset->data), decoded, decoded_len+1, (void**)&field) == SUCCESS) {
+ ent.data = *field;
+ }
+
+ efree(decoded);
+ break;
}
}
+
+ wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
}
}
/* }}} */
@@ -802,7 +881,7 @@ static void php_wddx_pop_element(void *user_data, const char *name)
if (!strcmp(name, EL_STRING) || !strcmp(name, EL_NUMBER) ||
!strcmp(name, EL_BOOLEAN) || !strcmp(name, EL_NULL) ||
!strcmp(name, EL_ARRAY) || !strcmp(name, EL_STRUCT) ||
- !strcmp(name, EL_BINARY)) {
+ !strcmp(name, EL_RECORDSET) || !strcmp(name, EL_BINARY)) {
wddx_stack_top(stack, (void**)&ent1);
if (!strcmp(name, EL_BINARY)) {
@@ -833,6 +912,14 @@ static void php_wddx_pop_element(void *user_data, const char *name)
if (stack->top > 1) {
stack->top--;
wddx_stack_top(stack, (void**)&ent2);
+
+ /* if non-existent field */
+ if (ent2->type == ST_FIELD && ent2->data == NULL) {
+ zval_ptr_dtor(&ent1->data);
+ efree(ent1);
+ return;
+ }
+
if (Z_TYPE_P(ent2->data) == IS_ARRAY || Z_TYPE_P(ent2->data) == IS_OBJECT) {
target_hash = HASH_OF(ent2->data);
@@ -871,8 +958,7 @@ static void php_wddx_pop_element(void *user_data, const char *name)
/* Clean up class name var entry */
zval_ptr_dtor(&ent1->data);
- }
- else
+ } else
zend_hash_update(target_hash,
ent1->varname, strlen(ent1->varname)+1,
&ent1->data, sizeof(zval *), NULL);
@@ -884,9 +970,15 @@ static void php_wddx_pop_element(void *user_data, const char *name)
}
}
efree(ent1);
- }
+ } else
+ stack->done = 1;
} else if (!strcmp(name, EL_VAR) && stack->varname) {
efree(stack->varname);
+ } else if (!strcmp(name, EL_FIELD)) {
+ st_entry *ent;
+ wddx_stack_top(stack, (void **)&ent);
+ efree(ent);
+ stack->top--;
}
}
/* }}} */
@@ -897,28 +989,28 @@ static void php_wddx_process_data(void *user_data, const char *s, int len)
{
st_entry *ent;
wddx_stack *stack = (wddx_stack *)user_data;
- char *decoded_value;
+ char *decoded;
int decoded_len;
TSRMLS_FETCH();
- if (!wddx_stack_is_empty(stack)) {
+ if (!wddx_stack_is_empty(stack) && !stack->done) {
wddx_stack_top(stack, (void**)&ent);
switch (Z_TYPE_P(ent)) {
case ST_STRING:
- decoded_value = xml_utf8_decode(s,len,&decoded_len,"ISO-8859-1");
+ decoded = xml_utf8_decode(s, len, &decoded_len, "ISO-8859-1");
if (Z_STRLEN_P(ent->data) == 0) {
- Z_STRVAL_P(ent->data) = estrndup(decoded_value, decoded_len);
+ Z_STRVAL_P(ent->data) = estrndup(decoded, decoded_len);
Z_STRLEN_P(ent->data) = decoded_len;
} else {
Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data),
Z_STRLEN_P(ent->data) + decoded_len + 1);
- strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded_value, decoded_len);
+ strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded, decoded_len);
Z_STRLEN_P(ent->data) += decoded_len;
Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0';
}
- efree(decoded_value);
+ efree(decoded);
break;
case ST_BINARY: