Patch from Sascha that abstracts session serializers. WDDX extension

now implements the encode/decode functions and registers them with
the session module.
This commit is contained in:
Andrei Zmievski 2001-05-01 17:01:51 +00:00
parent ab9a7a5f5f
commit ea56318495
4 changed files with 164 additions and 131 deletions

View file

@ -143,17 +143,20 @@ typedef struct ps_serializer_struct {
int (*decode)(PS_SERIALIZER_DECODE_ARGS);
} ps_serializer;
#define PS_SERIALIZER_ENCODE_NAME(x) ps_srlzr_encode_##x
#define PS_SERIALIZER_DECODE_NAME(x) ps_srlzr_decode_##x
#define PS_SERIALIZER_ENCODE_FUNC(x) \
int ps_srlzr_encode_##x(PS_SERIALIZER_ENCODE_ARGS)
int PS_SERIALIZER_ENCODE_NAME(x)(PS_SERIALIZER_ENCODE_ARGS)
#define PS_SERIALIZER_DECODE_FUNC(x) \
int ps_srlzr_decode_##x(PS_SERIALIZER_DECODE_ARGS)
int PS_SERIALIZER_DECODE_NAME(x)(PS_SERIALIZER_DECODE_ARGS)
#define PS_SERIALIZER_FUNCS(x) \
PS_SERIALIZER_ENCODE_FUNC(x); \
PS_SERIALIZER_DECODE_FUNC(x)
#define PS_SERIALIZER_ENTRY(x) \
{ #x,ps_srlzr_encode_##x, ps_srlzr_decode_##x }
{ #x, PS_SERIALIZER_ENCODE_NAME(x), PS_SERIALIZER_DECODE_NAME(x) }
#ifdef TRANS_SID
void session_adapt_uris(const char *, size_t, char **, size_t *);
@ -163,12 +166,49 @@ void session_adapt_url(const char *, size_t, char **, size_t *);
#define session_adapt_url(a,b,c,d)
#endif
void php_set_session_var(char *name, size_t namelen, zval *state_val PSLS_DC);
int php_get_session_var(char *name, size_t namelen, zval ***state_var PLS_DC PSLS_DC ELS_DC);
int php_session_register_serializer(const char *name,
int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
int (*decode)(PS_SERIALIZER_DECODE_ARGS));
#define PS_ADD_VARL(name,namelen) \
zend_hash_update(&PS(vars), name, namelen + 1, 0, 0, NULL)
#define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))
#define PS_DEL_VARL(name,namelen) \
zend_hash_del(&PS(vars), name, namelen + 1);
#define PS_DEL_VAR(name) PS_DEL_VARL(name, strlen(name))
#define PS_ENCODE_VARS \
char *key; \
ulong key_length; \
ulong num_key; \
zval **struc; \
ELS_FETCH(); \
PLS_FETCH()
#define PS_ENCODE_LOOP(code) \
for (zend_hash_internal_pointer_reset(&PS(vars)); \
zend_hash_get_current_key_ex(&PS(vars), &key, &key_length, &num_key, 0, NULL) == HASH_KEY_IS_STRING; \
zend_hash_move_forward(&PS(vars))) { \
key_length--; \
if (php_get_session_var(key, key_length, &struc PLS_CC PSLS_CC ELS_CC) == SUCCESS) { \
code; \
} \
}
#ifdef ZTS
extern int ps_globals_id;
#else
extern php_ps_globals ps_globals;
#endif
void php_session_auto_start(void *data);
void php_session_shutdown(void *data);
#if HAVE_WDDX
#define WDDX_SERIALIZER
#include "ext/wddx/php_wddx_api.h"
#endif
#endif

View file

@ -40,12 +40,6 @@
#include "ext/standard/php_rand.h" /* for RAND_MAX */
#include "ext/standard/info.h"
#ifdef ZTS
int ps_globals_id;
#else
static php_ps_globals ps_globals;
#endif
#include "modules.c"
#include "ext/standard/php_smart_str.h"
@ -71,6 +65,12 @@ function_entry session_functions[] = {
{0}
};
#ifdef ZTS
int ps_globals_id;
#else
php_ps_globals ps_globals;
#endif
static ps_module *_php_find_ps_module(char *name PSLS_DC);
static const ps_serializer *_php_find_ps_serializer(char *name PSLS_DC);
@ -123,20 +123,36 @@ PHP_INI_END()
PS_SERIALIZER_FUNCS(php);
PS_SERIALIZER_FUNCS(php_binary);
#ifdef WDDX_SERIALIZER
PS_SERIALIZER_FUNCS(wddx);
#endif
#define MAX_SERIALIZERS 10
const static ps_serializer ps_serializers[] = {
#ifdef WDDX_SERIALIZER
PS_SERIALIZER_ENTRY(wddx),
#endif
static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = {
PS_SERIALIZER_ENTRY(php),
PS_SERIALIZER_ENTRY(php_binary),
{0}
PS_SERIALIZER_ENTRY(php_binary)
};
int php_session_register_serializer(const char *name,
int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
int (*decode)(PS_SERIALIZER_DECODE_ARGS))
{
int ret = -1;
int i;
for (i = 0; i < MAX_SERIALIZERS; i++) {
if (ps_serializers[i].name == NULL) {
ps_serializers[i].name = name;
ps_serializers[i].encode = encode;
ps_serializers[i].decode = decode;
ps_serializers[i + 1].name = NULL;
ret = 0;
break;
}
}
return ret;
}
PHP_MINIT_FUNCTION(session);
PHP_RINIT_FUNCTION(session);
PHP_MSHUTDOWN_FUNCTION(session);
@ -182,36 +198,7 @@ typedef struct {
#define MAX_STR 512
#define PS_ADD_VARL(name,namelen) \
zend_hash_update(&PS(vars), name, namelen + 1, 0, 0, NULL)
#define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))
#define PS_DEL_VARL(name,namelen) \
zend_hash_del(&PS(vars), name, namelen + 1);
#define PS_DEL_VAR(name) PS_DEL_VARL(name, strlen(name))
#define ENCODE_VARS \
char *key; \
ulong key_length; \
ulong num_key; \
zval **struc; \
ELS_FETCH(); \
PLS_FETCH()
#define ENCODE_LOOP(code) \
for (zend_hash_internal_pointer_reset(&PS(vars)); \
zend_hash_get_current_key_ex(&PS(vars), &key, &key_length, &num_key, 0, NULL) == HASH_KEY_IS_STRING; \
zend_hash_move_forward(&PS(vars))) { \
key_length--; \
if (php_get_session_var(key, key_length, &struc PLS_CC PSLS_CC ELS_CC) == SUCCESS) { \
code; \
} \
}
static void php_set_session_var(char *name, size_t namelen,
zval *state_val PSLS_DC)
void php_set_session_var(char *name, size_t namelen, zval *state_val PSLS_DC)
{
zval *state_val_copy;
PLS_FETCH();
@ -244,7 +231,7 @@ static void php_set_session_var(char *name, size_t namelen,
}
}
static int php_get_session_var(char *name, size_t namelen, zval ***state_var PLS_DC PSLS_DC ELS_DC)
int php_get_session_var(char *name, size_t namelen, zval ***state_var PLS_DC PSLS_DC ELS_DC)
{
HashTable *ht = &EG(symbol_table);
@ -263,7 +250,7 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary)
zval *buf;
char strbuf[MAX_STR + 1];
php_serialize_data_t var_hash;
ENCODE_VARS;
PS_ENCODE_VARS;
buf = ecalloc(sizeof(*buf), 1);
Z_TYPE_P(buf) = IS_STRING;
@ -271,7 +258,7 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary)
PHP_VAR_SERIALIZE_INIT(var_hash);
ENCODE_LOOP(
PS_ENCODE_LOOP(
if (key_length > PS_BIN_MAX) continue;
strbuf[0] = key_length;
memcpy(strbuf + 1, key, key_length);
@ -338,7 +325,7 @@ PS_SERIALIZER_ENCODE_FUNC(php)
zval *buf;
char strbuf[MAX_STR + 1];
php_serialize_data_t var_hash;
ENCODE_VARS;
PS_ENCODE_VARS;
buf = ecalloc(sizeof(*buf), 1);
Z_TYPE_P(buf) = IS_STRING;
@ -346,7 +333,7 @@ PS_SERIALIZER_ENCODE_FUNC(php)
PHP_VAR_SERIALIZE_INIT(var_hash);
ENCODE_LOOP(
PS_ENCODE_LOOP(
if (key_length + 1 > MAX_STR) continue;
memcpy(strbuf, key, key_length);
strbuf[key_length] = PS_DELIMITER;
@ -410,77 +397,6 @@ PS_SERIALIZER_DECODE_FUNC(php)
return SUCCESS;
}
#ifdef WDDX_SERIALIZER
PS_SERIALIZER_ENCODE_FUNC(wddx)
{
wddx_packet *packet;
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);
ENCODE_LOOP(
php_wddx_serialize_var(packet, *struc, key, key_length);
);
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(wddx)
{
zval *retval;
zval **ent;
char *key;
ulong 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:
sprintf(tmp, "%ld", idx);
key = tmp;
/* fallthru */
case HASH_KEY_IS_STRING:
php_set_session_var(key, key_length-1, *ent PSLS_CC);
PS_ADD_VAR(key);
}
}
}
zval_ptr_dtor(&retval);
return ret;
}
#endif
static void php_session_track_init(void)
{
zval **old_vars = NULL;

View file

@ -53,8 +53,8 @@
typedef smart_str wddx_packet;
wddx_packet *php_wddx_constructor(void);
#define php_wddx_destructor(packet) smart_str_free(packet)
wddx_packet* php_wddx_constructor(void);
void php_wddx_destructor(wddx_packet *packet);
void php_wddx_packet_start(wddx_packet *packet, char *comment, int comment_len);
void php_wddx_packet_end(wddx_packet *packet);

View file

@ -203,10 +203,81 @@ static void release_wddx_packet_rsrc(zend_rsrc_list_entry *rsrc)
efree(str);
}
#include "ext/session/php_session.h"
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);
);
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(wddx)
{
zval *retval;
zval **ent;
char *key;
ulong 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:
sprintf(tmp, "%ld", idx);
key = tmp;
/* fallthru */
case HASH_KEY_IS_STRING:
php_set_session_var(key, key_length-1, *ent PSLS_CC);
PS_ADD_VAR(key);
}
}
}
zval_ptr_dtor(&retval);
return ret;
}
PHP_MINIT_FUNCTION(wddx)
{
le_wddx = zend_register_list_destructors_ex(release_wddx_packet_rsrc, NULL, "wddx", module_number);
php_session_register_serializer("wddx",
PS_SERIALIZER_ENCODE_NAME(wddx),
PS_SERIALIZER_DECODE_NAME(wddx));
return SUCCESS;
}
@ -956,6 +1027,12 @@ wddx_packet *php_wddx_constructor(void)
return packet;
}
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)