📄 wddx.c
字号:
!strcmp(name, EL_ARRAY) || !strcmp(name, EL_STRUCT) || !strcmp(name, EL_RECORDSET) || !strcmp(name, EL_BINARY) || !strcmp(name, EL_DATETIME)) { wddx_stack_top(stack, (void**)&ent1); if (!strcmp(name, EL_BINARY)) { int new_len=0; unsigned char *new_str; new_str = php_base64_decode(Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data), &new_len); STR_FREE(Z_STRVAL_P(ent1->data)); Z_STRVAL_P(ent1->data) = new_str; Z_STRLEN_P(ent1->data) = new_len; } /* Call __wakeup() method on the object. */ if (Z_TYPE_P(ent1->data) == IS_OBJECT) { zval *fname, *retval = NULL; MAKE_STD_ZVAL(fname); ZVAL_STRING(fname, "__wakeup", 1); call_user_function_ex(NULL, &ent1->data, fname, &retval, 0, 0, 0, NULL TSRMLS_CC); zval_dtor(fname); FREE_ZVAL(fname); if (retval) zval_ptr_dtor(&retval); } 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); if (ent1->varname) { if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) && Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data)) { zend_bool incomplete_class = 0; zend_str_tolower(Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data)); if (zend_hash_find(EG(class_table), Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data)+1, (void **) &ce)==FAILURE) { incomplete_class = 1; ce = PHP_IC_ENTRY; } /* Initialize target object */ MAKE_STD_ZVAL(obj); INIT_PZVAL(obj); object_init_ex(obj, ce); /* Merge current hashtable with object's default properties */ zend_hash_merge(Z_OBJPROP_P(obj), Z_ARRVAL_P(ent2->data), (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); if (incomplete_class) { php_store_class_name(obj, Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data) TSRMLS_CC); } /* Clean up old array entry */ zval_ptr_dtor(&ent2->data); /* Set stack entry to point to the newly created object */ ent2->data = obj; /* Clean up class name var entry */ zval_ptr_dtor(&ent1->data); } else { long l; double d; switch (is_numeric_string(ent1->varname, strlen(ent1->varname), &l, &d, 0)) { case IS_DOUBLE: if (d > INT_MAX) { goto bigint; } l = (long) d; case IS_LONG: zend_hash_index_update(target_hash, l, &ent1->data, sizeof(zval *), NULL); break; default:bigint: zend_hash_update(target_hash,ent1->varname, strlen(ent1->varname)+1, &ent1->data, sizeof(zval *), NULL); } } efree(ent1->varname); } else { zend_hash_next_index_insert(target_hash, &ent1->data, sizeof(zval *), NULL); } } 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--; }}/* }}} *//* {{{ php_wddx_process_data */static void php_wddx_process_data(void *user_data, const XML_Char *s, int len){ st_entry *ent; wddx_stack *stack = (wddx_stack *)user_data; char *decoded; int decoded_len; TSRMLS_FETCH(); if (!wddx_stack_is_empty(stack) && !stack->done) { wddx_stack_top(stack, (void**)&ent); switch (Z_TYPE_P(ent)) { case ST_STRING: 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, 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, decoded_len); Z_STRLEN_P(ent->data) += decoded_len; Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0'; } efree(decoded); break; case ST_BINARY: if (Z_STRLEN_P(ent->data) == 0) { Z_STRVAL_P(ent->data) = estrndup(s, len + 1); } else { Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data), Z_STRLEN_P(ent->data) + len + 1); memcpy(Z_STRVAL_P(ent->data) + Z_STRLEN_P(ent->data), s, len); } Z_STRLEN_P(ent->data) += len; Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0'; break; case ST_NUMBER: Z_TYPE_P(ent->data) = IS_STRING; Z_STRLEN_P(ent->data) = len; Z_STRVAL_P(ent->data) = estrndup(s, len); convert_scalar_to_number(ent->data TSRMLS_CC); break; case ST_BOOLEAN: if (!strcmp(s, "true")) Z_LVAL_P(ent->data) = 1; else if (!strcmp(s, "false")) Z_LVAL_P(ent->data) = 0; else { stack->top--; zval_ptr_dtor(&ent->data); if (ent->varname) efree(ent->varname); efree(ent); } break; case ST_DATETIME: { char *tmp; tmp = emalloc(len + 1); memcpy(tmp, s, len); tmp[len] = '\0'; Z_LVAL_P(ent->data) = php_parse_date(tmp, NULL); /* date out of range < 1969 or > 2038 */ if (Z_LVAL_P(ent->data) == -1) { Z_TYPE_P(ent->data) = IS_STRING; Z_STRLEN_P(ent->data) = len; Z_STRVAL_P(ent->data) = estrndup(s, len); } efree(tmp); } default: break; } }}/* }}} *//* {{{ php_wddx_deserialize_ex */int php_wddx_deserialize_ex(char *value, int vallen, zval *return_value){ wddx_stack stack; XML_Parser parser; st_entry *ent; int retval; wddx_stack_init(&stack); parser = XML_ParserCreate("ISO-8859-1"); XML_SetUserData(parser, &stack); XML_SetElementHandler(parser, php_wddx_push_element, php_wddx_pop_element); XML_SetCharacterDataHandler(parser, php_wddx_process_data); XML_Parse(parser, value, vallen, 1); XML_ParserFree(parser); if (stack.top == 1) { wddx_stack_top(&stack, (void**)&ent); *return_value = *(ent->data); zval_copy_ctor(return_value); retval = SUCCESS; } else retval = FAILURE; wddx_stack_destroy(&stack); return retval;}/* }}} *//* {{{ proto string wddx_serialize_value(mixed var [, string comment]) Creates a new packet and serializes the given value */PHP_FUNCTION(wddx_serialize_value){ zval *var; char *comment = NULL; int comment_len = 0; wddx_packet *packet; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &var, &comment, &comment_len) == FAILURE) return; packet = php_wddx_constructor(); if (!packet) { RETURN_FALSE; } php_wddx_packet_start(packet, comment, comment_len); php_wddx_serialize_var(packet, var, NULL, 0 TSRMLS_CC); php_wddx_packet_end(packet); ZVAL_STRINGL(return_value, packet->c, packet->len, 1); smart_str_free(packet); efree(packet);}/* }}} *//* {{{ proto string wddx_serialize_vars(mixed var_name [, mixed ...]) Creates a new packet and serializes given variables into a struct */PHP_FUNCTION(wddx_serialize_vars){ int argc, i; wddx_packet *packet; zval ***args; argc = ZEND_NUM_ARGS(); if (argc < 1) { php_error(E_WARNING, "%s() requires at least 1 argument, 0 given", get_active_function_name(TSRMLS_C)); return; } /* Allocate arguments array and get the arguments, checking for errors. */ args = (zval ***)emalloc(argc * sizeof(zval **)); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } packet = php_wddx_constructor(); if (!packet) { RETURN_FALSE; } php_wddx_packet_start(packet, NULL, 0); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); for (i=0; i<argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY && Z_TYPE_PP(args[i]) != IS_OBJECT) convert_to_string_ex(args[i]); php_wddx_add_var(packet, *args[i]); } php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); php_wddx_packet_end(packet); efree(args); ZVAL_STRINGL(return_value, packet->c, packet->len, 1); smart_str_free(packet); efree(packet);}/* }}} *//* {{{ php_wddx_constructor */wddx_packet *php_wddx_constructor(void){ smart_str *packet; packet = (smart_str *)emalloc(sizeof(smart_str)); packet->c = NULL; return packet;}/* }}} *//* {{{ php_wddx_destructor */void php_wddx_destructor(wddx_packet *packet){ smart_str_free(packet); efree(packet);}/* }}} *//* {{{ proto int wddx_packet_start([string comment]) Starts a WDDX packet with optional comment and returns the packet id */PHP_FUNCTION(wddx_packet_start){ char *comment = NULL; int comment_len = 0; wddx_packet *packet; comment = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &comment, &comment_len) == FAILURE) return; packet = php_wddx_constructor(); if (!packet) { RETURN_FALSE; } php_wddx_packet_start(packet, comment, comment_len); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); ZEND_REGISTER_RESOURCE(return_value, packet, le_wddx);}/* }}} *//* {{{ proto string wddx_packet_end(int packet_id) Ends specified WDDX packet and returns the string containing the packet */PHP_FUNCTION(wddx_packet_end){ zval *packet_id; wddx_packet *packet = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &packet_id) == FAILURE) return; ZEND_FETCH_RESOURCE(packet, wddx_packet *, &packet_id, -1, "WDDX packet ID", le_wddx); php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); php_wddx_packet_end(packet); ZVAL_STRINGL(return_value, packet->c, packet->len, 1); zend_list_delete(Z_LVAL_P(packet_id));}/* }}} *//* {{{ proto int wddx_add_vars(int packet_id, mixed var_names [, mixed ...]) Serializes given variables and adds them to packet given by packet_id */PHP_FUNCTION(wddx_add_vars){ int argc, i; zval ***args; zval **packet_id; wddx_packet *packet = NULL; argc = ZEND_NUM_ARGS(); if (argc < 2) { php_error(E_WARNING, "%s() requires at least 2 arguments, %d given", get_active_function_name(TSRMLS_C), ZEND_NUM_ARGS()); return; } /* Allocate arguments array and get the arguments, checking for errors. */ args = (zval ***)emalloc(argc * sizeof(zval **)); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } packet_id = args[0]; packet = (wddx_packet *)zend_fetch_resource(packet_id TSRMLS_CC, -1, "WDDX packet ID", NULL, 1, le_wddx); if (!packet) { efree(args); RETURN_FALSE; } for (i=1; i<argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY && Z_TYPE_PP(args[i]) != IS_OBJECT) convert_to_string_ex(args[i]); php_wddx_add_var(packet, (*args[i])); } efree(args); RETURN_TRUE;}/* }}} *//* {{{ proto mixed wddx_deserialize(string packet) Deserializes given packet and returns a PHP value */PHP_FUNCTION(wddx_deserialize){ char *packet; int packet_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &packet, &packet_len) == FAILURE) return; if (packet_len == 0) return; php_wddx_deserialize_ex(packet, packet_len, return_value);}/* }}} */#endif /* HAVE_LIBEXPAT *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -