📄 wddx.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Andrei Zmievski <andrei@php.net> | +----------------------------------------------------------------------+ *//* $Id: wddx.c,v 1.96.2.6.2.10 2007/01/09 15:21:08 iliaa Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_wddx.h"#if HAVE_WDDX#include "php_wddx_api.h"#define PHP_XML_INTERNAL#include "ext/xml/php_xml.h"#include "ext/standard/php_incomplete_class.h"#include "ext/standard/base64.h"#include "ext/standard/info.h"#include "ext/standard/php_smart_str.h"#include "ext/standard/html.h"#include "ext/standard/php_string.h"#include "ext/standard/php_parsedate.h"#define WDDX_BUF_LEN 256#define PHP_CLASS_NAME_VAR "php_class_name"#define EL_ARRAY "array"#define EL_BINARY "binary"#define EL_BOOLEAN "boolean"#define EL_CHAR "char"#define EL_CHAR_CODE "code"#define EL_NULL "null"#define EL_NUMBER "number"#define EL_PACKET "wddxPacket"#define EL_STRING "string"#define EL_STRUCT "struct"#define EL_VALUE "value"#define EL_VAR "var"#define EL_NAME "name"#define EL_VERSION "version"#define EL_RECORDSET "recordset"#define EL_FIELD "field"#define EL_DATETIME "dateTime"#define php_wddx_deserialize(a,b) \ php_wddx_deserialize_ex((a)->value.str.val, (a)->value.str.len, (b))#define SET_STACK_VARNAME \ if (stack->varname) { \ ent.varname = estrdup(stack->varname); \ efree(stack->varname); \ stack->varname = NULL; \ } else \ ent.varname = NULL; \ static int le_wddx;typedef struct { zval *data; enum { ST_ARRAY, ST_BOOLEAN, ST_NULL, ST_NUMBER, ST_STRING, ST_BINARY, ST_STRUCT, ST_RECORDSET, ST_FIELD, ST_DATETIME } type; char *varname;} st_entry;typedef struct { int top, max; char *varname; zend_bool done; void **elements;} wddx_stack;static void php_wddx_process_data(void *user_data, const XML_Char *s, int len);/* {{{ wddx_functions[] */function_entry wddx_functions[] = { PHP_FE(wddx_serialize_value, NULL) PHP_FE(wddx_serialize_vars, NULL) PHP_FE(wddx_packet_start, NULL) PHP_FE(wddx_packet_end, NULL) PHP_FE(wddx_add_vars, NULL) PHP_FE(wddx_deserialize, NULL) {NULL, NULL, NULL}};/* }}} */PHP_MINIT_FUNCTION(wddx);PHP_MINFO_FUNCTION(wddx);/* {{{ dynamically loadable module stuff */#ifdef COMPILE_DL_WDDXZEND_GET_MODULE(wddx)#endif /* COMPILE_DL_WDDX *//* }}} *//* {{{ wddx_module_entry */zend_module_entry wddx_module_entry = { STANDARD_MODULE_HEADER, "wddx", wddx_functions, PHP_MINIT(wddx), NULL, NULL, NULL, PHP_MINFO(wddx), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES};/* }}} *//* {{{ wddx_stack_init */ static int wddx_stack_init(wddx_stack *stack){ stack->top = 0; stack->elements = (void **) emalloc(sizeof(void **) * STACK_BLOCK_SIZE); if (!stack->elements) { return FAILURE; } else { stack->max = STACK_BLOCK_SIZE; stack->varname = NULL; stack->done = 0; return SUCCESS; }}/* }}} *//* {{{ wddx_stack_push */static int wddx_stack_push(wddx_stack *stack, void *element, int size){ if (stack->top >= stack->max) { /* we need to allocate more memory */ stack->elements = (void **) erealloc(stack->elements, (sizeof(void **) * (stack->max += STACK_BLOCK_SIZE))); if (!stack->elements) { return FAILURE; } } stack->elements[stack->top] = (void *) emalloc(size); memcpy(stack->elements[stack->top], element, size); return stack->top++;}/* }}} *//* {{{ wddx_stack_top */static int wddx_stack_top(wddx_stack *stack, void **element){ if (stack->top > 0) { *element = stack->elements[stack->top - 1]; return SUCCESS; } else { *element = NULL; return FAILURE; }}/* }}} *//* {{{ wddx_stack_is_empty */static int wddx_stack_is_empty(wddx_stack *stack){ if (stack->top == 0) { return 1; } else { return 0; }}/* }}} *//* {{{ wddx_stack_destroy */static int wddx_stack_destroy(wddx_stack *stack){ register int i; if (stack->elements) { for (i = 0; i < stack->top; i++) { if (((st_entry *)stack->elements[i])->data) { zval_ptr_dtor(&((st_entry *)stack->elements[i])->data); } if (((st_entry *)stack->elements[i])->varname) efree(((st_entry *)stack->elements[i])->varname); efree(stack->elements[i]); } efree(stack->elements); } return SUCCESS;}/* }}} *//* {{{ release_wddx_packet_rsrc */static void release_wddx_packet_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC){ smart_str *str = (smart_str *)rsrc->ptr; smart_str_free(str); efree(str);}/* }}} */#include "ext/session/php_session.h"#if HAVE_PHP_SESSION/* {{{ PS_SERIALIZER_ENCODE_FUNC */PS_SERIALIZER_ENCODE_FUNC(wddx){ wddx_packet *packet; PS_ENCODE_VARS; packet = php_wddx_constructor(); if (!packet) return FAILURE; php_wddx_packet_start(packet, NULL, 0); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); PS_ENCODE_LOOP( php_wddx_serialize_var(packet, *struc, key, key_length TSRMLS_CC); ); php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); php_wddx_packet_end(packet); *newstr = php_wddx_gather(packet); php_wddx_destructor(packet); if (newlen) *newlen = strlen(*newstr); return SUCCESS;}/* }}} *//* {{{ PS_SERIALIZER_DECODE_FUNC */PS_SERIALIZER_DECODE_FUNC(wddx){ zval *retval; zval **ent; char *key; uint key_length; char tmp[128]; ulong idx; int hash_type; int ret; if (vallen == 0) return SUCCESS; MAKE_STD_ZVAL(retval); if ((ret = php_wddx_deserialize_ex((char *)val, vallen, retval)) == SUCCESS) { for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(retval)); zend_hash_get_current_data(Z_ARRVAL_P(retval), (void **) &ent) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(retval))) { hash_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(retval), &key, &key_length, &idx, 0, NULL); switch (hash_type) { case HASH_KEY_IS_LONG: key_length = sprintf(tmp, "%ld", idx) + 1; key = tmp; /* fallthru */ case HASH_KEY_IS_STRING: php_set_session_var(key, key_length-1, *ent, NULL TSRMLS_CC); PS_ADD_VAR(key); } } } zval_ptr_dtor(&retval); return ret;}/* }}} */#endif/* {{{ PHP_MINIT_FUNCTION */PHP_MINIT_FUNCTION(wddx){ le_wddx = zend_register_list_destructors_ex(release_wddx_packet_rsrc, NULL, "wddx", module_number);#if HAVE_PHP_SESSION php_session_register_serializer("wddx", PS_SERIALIZER_ENCODE_NAME(wddx), PS_SERIALIZER_DECODE_NAME(wddx));#endif return SUCCESS;}/* }}} *//* {{{ PHP_MINFO_FUNCTION */PHP_MINFO_FUNCTION(wddx){ php_info_print_table_start();#if HAVE_PHP_SESSION php_info_print_table_header(2, "WDDX Support", "enabled" ); php_info_print_table_row(2, "WDDX Session Serializer", "enabled" );#else php_info_print_table_row(2, "WDDX Support", "enabled" );#endif php_info_print_table_end();}/* }}} *//* {{{ php_wddx_packet_start */void php_wddx_packet_start(wddx_packet *packet, char *comment, int comment_len){ php_wddx_add_chunk_static(packet, WDDX_PACKET_S); if (comment) { php_wddx_add_chunk_static(packet, WDDX_HEADER_S); php_wddx_add_chunk_static(packet, WDDX_COMMENT_S); php_wddx_add_chunk_ex(packet, comment, comment_len); php_wddx_add_chunk_static(packet, WDDX_COMMENT_E); php_wddx_add_chunk_static(packet, WDDX_HEADER_E); } else php_wddx_add_chunk_static(packet, WDDX_HEADER); php_wddx_add_chunk_static(packet, WDDX_DATA_S);}/* }}} *//* {{{ php_wddx_packet_end */void php_wddx_packet_end(wddx_packet *packet){ php_wddx_add_chunk_static(packet, WDDX_DATA_E); php_wddx_add_chunk_static(packet, WDDX_PACKET_E); }/* }}} */#define FLUSH_BUF() \ if (l > 0) { \ php_wddx_add_chunk_ex(packet, buf, l); \ l = 0; \ }/* {{{ php_wddx_serialize_string */static void php_wddx_serialize_string(wddx_packet *packet, zval *var){ char *buf, *p, *vend, control_buf[WDDX_BUF_LEN]; int l; php_wddx_add_chunk_static(packet, WDDX_STRING_S); if (Z_STRLEN_P(var) > 0) { l = 0; vend = Z_STRVAL_P(var) + Z_STRLEN_P(var); buf = (char *)emalloc(Z_STRLEN_P(var) + 1); for(p = Z_STRVAL_P(var); p != vend; p++) { switch (*p) { case '<': FLUSH_BUF(); php_wddx_add_chunk_static(packet, "<"); break; case '&': FLUSH_BUF(); php_wddx_add_chunk_static(packet, "&"); break; case '>': FLUSH_BUF(); php_wddx_add_chunk_static(packet, ">"); break; default: if (iscntrl((int)*(unsigned char *)p) || (int)*(unsigned char *)p >= 127) { FLUSH_BUF(); sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); php_wddx_add_chunk(packet, control_buf); } else buf[l++] = *p; break; } } FLUSH_BUF(); efree(buf); } php_wddx_add_chunk_static(packet, WDDX_STRING_E);}/* }}} *//* {{{ php_wddx_serialize_number */static void php_wddx_serialize_number(wddx_packet *packet, zval *var){ char tmp_buf[WDDX_BUF_LEN]; zval tmp; tmp = *var; zval_copy_ctor(&tmp); convert_to_string(&tmp); snprintf(tmp_buf, sizeof(tmp_buf), WDDX_NUMBER, Z_STRVAL(tmp)); zval_dtor(&tmp); php_wddx_add_chunk(packet, tmp_buf); }/* }}} *//* {{{ php_wddx_serialize_boolean */static void php_wddx_serialize_boolean(wddx_packet *packet, zval *var){ char tmp_buf[WDDX_BUF_LEN]; sprintf(tmp_buf, WDDX_BOOLEAN, Z_LVAL_P(var) ? "true" : "false"); php_wddx_add_chunk(packet, tmp_buf);}/* }}} *//* {{{ php_wddx_serialize_unset */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -