/* per server data */
typedef struct _xmlrpc_server_data {
- zval* method_map;
- zval* introspection_map;
+ zval method_map;
+ zval introspection_map;
XMLRPC_SERVER server_ptr;
} xmlrpc_server_data;
/* data passed to C callback */
typedef struct _xmlrpc_callback_data {
- zval* xmlrpc_method;
- zval* php_function;
- zval* caller_params;
- zval* return_data;
+ zval xmlrpc_method;
+ zval php_function;
+ zval caller_params;
+ zval return_data;
xmlrpc_server_data* server;
char php_executed;
} xmlrpc_callback_data;
/***********************
* forward declarations *
***********************/
-XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue);
+XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval* newvalue);
static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data);
int sset_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type);
-zval* decode_request_worker(char *xml_in, int xml_in_len, char *encoding_in, zval* method_name_out);
+void decode_request_worker(char *xml_in, int xml_in_len, char *encoding_in, zval* method_name_out, zval *retval);
const char* xmlrpc_type_as_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype);
XMLRPC_VALUE_TYPE xmlrpc_str_as_type(const char* str);
XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str);
if (server) {
XMLRPC_ServerDestroy(server->server_ptr);
- zval_dtor(server->method_map);
- FREE_ZVAL(server->method_map);
-
- zval_dtor(server->introspection_map);
- FREE_ZVAL(server->introspection_map);
+ zval_ptr_dtor(&server->method_map);
+ zval_ptr_dtor(&server->introspection_map);
efree(server);
}
/* called when server is being destructed. either when xmlrpc_server_destroy
* is called, or when request ends. */
-static void xmlrpc_server_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void xmlrpc_server_destructor(zend_resource *rsrc TSRMLS_DC)
{
if (rsrc && rsrc->ptr) {
destroy_server_data((xmlrpc_server_data*) rsrc->ptr TSRMLS_CC);
#endif
-static int add_zval(zval* list, const char* id, zval** val)
+static void add_zval(zval* list, const char* id, zval* val)
{
if (list && val) {
if (id) {
int id_len = strlen(id);
if (!(id_len > 1 && id[0] == '0') && is_numeric_string((char *)id, id_len, NULL, NULL, 0) == IS_LONG) {
long index = strtol(id, NULL, 0);
- return zend_hash_index_update(Z_ARRVAL_P(list), index, (void *) val, sizeof(zval **), NULL);
+ zend_hash_index_update(Z_ARRVAL_P(list), index, val);
} else {
- return zend_hash_update(Z_ARRVAL_P(list), (char*) id, strlen(id) + 1, (void *) val, sizeof(zval **), NULL);
+ zend_hash_str_update(Z_ARRVAL_P(list), (char*)id, strlen(id), val);
}
} else {
- return zend_hash_next_index_insert(Z_ARRVAL_P(list), (void *) val, sizeof(zval **), NULL);
+ zend_hash_next_index_insert(Z_ARRVAL_P(list), val);
}
}
- /* what is the correct return on error? */
- return 0;
}
-#define my_zend_hash_get_current_key(ht, my_key, num_index) zend_hash_get_current_key(ht, my_key, num_index, 0)
-
-
/*************************
* input / output options *
*************************/
static void set_output_options(php_output_options* options, zval* output_opts)
{
if (options) {
-
/* defaults */
options->b_php_out = 0;
options->b_auto_version = 1;
options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping | xml_elem_non_ascii_escaping | xml_elem_non_print_escaping;
if (output_opts && Z_TYPE_P(output_opts) == IS_ARRAY) {
- zval** val;
+ zval* val;
/* type of output (xml/php) */
- if (zend_hash_find(Z_ARRVAL_P(output_opts), OUTPUT_TYPE_KEY, OUTPUT_TYPE_KEY_LEN + 1, (void**) &val) == SUCCESS) {
- if (Z_TYPE_PP(val) == IS_STRING) {
- if (!strcmp(Z_STRVAL_PP(val), OUTPUT_TYPE_VALUE_PHP)) {
+ if ((val = zend_hash_str_find(Z_ARRVAL_P(output_opts), OUTPUT_TYPE_KEY, OUTPUT_TYPE_KEY_LEN)) != NULL) {
+ if (Z_TYPE_P(val) == IS_STRING) {
+ if (!strcmp(Z_STRVAL_P(val), OUTPUT_TYPE_VALUE_PHP)) {
options->b_php_out = 1;
- } else if (!strcmp(Z_STRVAL_PP(val), OUTPUT_TYPE_VALUE_XML)) {
+ } else if (!strcmp(Z_STRVAL_P(val), OUTPUT_TYPE_VALUE_XML)) {
options->b_php_out = 0;
}
}
}
/* verbosity of generated xml */
- if (zend_hash_find(Z_ARRVAL_P(output_opts), VERBOSITY_KEY, VERBOSITY_KEY_LEN + 1, (void**) &val) == SUCCESS) {
- if (Z_TYPE_PP(val) == IS_STRING) {
- if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_NO_WHITE_SPACE)) {
+ if ((val = zend_hash_str_find(Z_ARRVAL_P(output_opts), VERBOSITY_KEY, VERBOSITY_KEY_LEN)) != NULL) {
+ if (Z_TYPE_P(val) == IS_STRING) {
+ if (!strcmp(Z_STRVAL_P(val), VERBOSITY_VALUE_NO_WHITE_SPACE)) {
options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_no_white_space;
- } else if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_NEWLINES_ONLY)) {
+ } else if (!strcmp(Z_STRVAL_P(val), VERBOSITY_VALUE_NEWLINES_ONLY)) {
options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_newlines_only;
- } else if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_PRETTY)) {
+ } else if (!strcmp(Z_STRVAL_P(val), VERBOSITY_VALUE_PRETTY)) {
options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_pretty;
}
}
}
/* version of xml to output */
- if (zend_hash_find(Z_ARRVAL_P(output_opts), VERSION_KEY, VERSION_KEY_LEN + 1, (void**) &val) == SUCCESS) {
- if (Z_TYPE_PP(val) == IS_STRING) {
+ if ((val = zend_hash_str_find(Z_ARRVAL_P(output_opts), VERSION_KEY, VERSION_KEY_LEN)) != NULL) {
+ if (Z_TYPE_P(val) == IS_STRING) {
options->b_auto_version = 0;
- if (!strcmp(Z_STRVAL_PP(val), VERSION_VALUE_XMLRPC)) {
+ if (!strcmp(Z_STRVAL_P(val), VERSION_VALUE_XMLRPC)) {
options->xmlrpc_out.version = xmlrpc_version_1_0;
- } else if (!strcmp(Z_STRVAL_PP(val), VERSION_VALUE_SIMPLE)) {
+ } else if (!strcmp(Z_STRVAL_P(val), VERSION_VALUE_SIMPLE)) {
options->xmlrpc_out.version = xmlrpc_version_simple;
- } else if (!strcmp((*val)->value.str.val, VERSION_VALUE_SOAP11)) {
- options->xmlrpc_out.version = xmlrpc_version_soap_1_1;
+ } else if (!strcmp(Z_STRVAL_P(val), VERSION_VALUE_SOAP11)) {
+ options->xmlrpc_out.version = xmlrpc_version_soap_1_1;
} else { /* if(!strcmp((*val)->value.str.val, VERSION_VALUE_AUTO)) { */
- options->b_auto_version = 1;
+ options->b_auto_version = 1;
}
}
- }
- /* encoding code set */
- if (zend_hash_find(Z_ARRVAL_P(output_opts), ENCODING_KEY, ENCODING_KEY_LEN + 1, (void**)&val) == SUCCESS) {
- if (Z_TYPE_PP(val) == IS_STRING) {
- options->xmlrpc_out.xml_elem_opts.encoding = estrdup(Z_STRVAL_PP(val));
+ /* encoding code set */
+ if ((val = zend_hash_str_find(Z_ARRVAL_P(output_opts), ENCODING_KEY, ENCODING_KEY_LEN)) != NULL) {
+ if (Z_TYPE_P(val) == IS_STRING) {
+ options->xmlrpc_out.xml_elem_opts.encoding = estrdup(Z_STRVAL_P(val));
+ }
}
- }
- /* escaping options */
- if (zend_hash_find(Z_ARRVAL_P(output_opts), ESCAPING_KEY, ESCAPING_KEY_LEN + 1, (void**)&val) == SUCCESS) {
- /* multiple values allowed. check if array */
- if (Z_TYPE_PP(val) == IS_ARRAY) {
- zval** iter_val;
+ /* escaping options */
+ if ((val = zend_hash_str_find(Z_ARRVAL_P(output_opts), ESCAPING_KEY, ESCAPING_KEY_LEN)) != NULL) {
+ /* multiple values allowed. check if array */
+ if (Z_TYPE_P(val) == IS_ARRAY) {
+ zval* iter_val;
- zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val));
- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_no_escaping;
+ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_no_escaping;
- while (1) {
- if (zend_hash_get_current_data(Z_ARRVAL_PP(val), (void**)&iter_val) == SUCCESS) {
- if (Z_TYPE_PP(iter_val) == IS_STRING && Z_STRVAL_PP(iter_val)) {
- if (!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_CDATA)) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(val), iter_val) {
+ if (Z_TYPE_P(iter_val) == IS_STRING && Z_STRVAL_P(iter_val)) {
+ if (!strcmp(Z_STRVAL_P(iter_val), ESCAPING_VALUE_CDATA)) {
options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_cdata_escaping;
- } else if (!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_ASCII)) {
+ } else if (!strcmp(Z_STRVAL_P(iter_val), ESCAPING_VALUE_NON_ASCII)) {
options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_ascii_escaping;
- } else if (!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_PRINT)) {
+ } else if (!strcmp(Z_STRVAL_P(iter_val), ESCAPING_VALUE_NON_PRINT)) {
options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_print_escaping;
- } else if (!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_MARKUP)) {
+ } else if (!strcmp(Z_STRVAL_P(iter_val), ESCAPING_VALUE_MARKUP)) {
options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_markup_escaping;
}
}
- } else {
- break;
+ } ZEND_HASH_FOREACH_END();
+ /* else, check for single value */
+ } else if (Z_TYPE_P(val) == IS_STRING) {
+ if (!strcmp(Z_STRVAL_P(val), ESCAPING_VALUE_CDATA)) {
+ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_cdata_escaping;
+ } else if (!strcmp(Z_STRVAL_P(val), ESCAPING_VALUE_NON_ASCII)) {
+ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_ascii_escaping;
+ } else if (!strcmp(Z_STRVAL_P(val), ESCAPING_VALUE_NON_PRINT)) {
+ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_print_escaping;
+ } else if (!strcmp(Z_STRVAL_P(val), ESCAPING_VALUE_MARKUP)) {
+ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping;
}
- zend_hash_move_forward(Z_ARRVAL_PP(val));
- }
- /* else, check for single value */
- } else if (Z_TYPE_PP(val) == IS_STRING) {
- if (!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_CDATA)) {
- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_cdata_escaping;
- } else if (!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_ASCII)) {
- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_ascii_escaping;
- } else if (!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_PRINT)) {
- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_print_escaping;
- } else if (!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_MARKUP)) {
- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping;
}
}
}
{
int bArray = 0, bStruct = 0, bMixed = 0;
unsigned long num_index, last_num = 0;
- char* my_key;
+ zend_string* my_key;
- zend_hash_internal_pointer_reset(ht);
- while (1) {
- int res = my_zend_hash_get_current_key(ht, &my_key, &num_index);
-
- if (res == HASH_KEY_IS_LONG) {
+ ZEND_HASH_FOREACH_KEY(ht, num_index, my_key) {
+ if (my_key == NULL) {
if (bStruct) {
bMixed = 1;
break;
}
bArray = 1;
last_num = num_index;
- } else if (res == HASH_KEY_NON_EXISTENT) {
- break;
- } else if (res == HASH_KEY_IS_STRING) {
+ } else {
if (bArray) {
bMixed = 1;
break;
}
bStruct = 1;
}
- zend_hash_move_forward(ht);
- }
+ } ZEND_HASH_FOREACH_END();
return bMixed ? xmlrpc_vector_mixed : (bStruct ? xmlrpc_vector_struct : xmlrpc_vector_array);
}
XMLRPC_VALUE xReturn = NULL;
if (in_val) {
- zval* val = NULL;
+ zval val;
+ ZVAL_UNDEF(&val);
XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val);
- if (val) {
+ if (!Z_ISUNDEF(val)) {
switch (type) {
case xmlrpc_base64:
- if (Z_TYPE_P(val) == IS_NULL) {
+ if (Z_TYPE(val) == IS_NULL) {
xReturn = XMLRPC_CreateValueEmpty();
XMLRPC_SetValueID(xReturn, key, 0);
} else {
- xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
+ xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL(val), Z_STRLEN(val));
}
break;
case xmlrpc_datetime:
- convert_to_string(val);
- xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val));
+ convert_to_string(&val);
+ xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL(val));
break;
case xmlrpc_boolean:
- convert_to_boolean(val);
- xReturn = XMLRPC_CreateValueBoolean(key, Z_TYPE_P(val) == IS_TRUE);
+ convert_to_boolean(&val);
+ xReturn = XMLRPC_CreateValueBoolean(key, Z_TYPE(val) == IS_TRUE);
break;
case xmlrpc_int:
- convert_to_long(val);
- xReturn = XMLRPC_CreateValueInt(key, Z_LVAL_P(val));
+ convert_to_long(&val);
+ xReturn = XMLRPC_CreateValueInt(key, Z_LVAL(val));
break;
case xmlrpc_double:
- convert_to_double(val);
- xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL_P(val));
+ convert_to_double(&val);
+ xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL(val));
break;
case xmlrpc_string:
- convert_to_string(val);
- xReturn = XMLRPC_CreateValueString(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
+ convert_to_string(&val);
+ xReturn = XMLRPC_CreateValueString(key, Z_STRVAL(val), Z_STRLEN(val));
break;
case xmlrpc_vector:
{
unsigned long num_index;
- zval** pIter;
- char* my_key;
+ zval* pIter;
+ zend_string* my_key;
HashTable *ht = NULL;
- zval *val_arr;
+ zval val_arr;
XMLRPC_VECTOR_TYPE vtype;
- ht = HASH_OF(val);
- if (ht && ht->nApplyCount > 1) {
+ ht = HASH_OF(&val);
+ if (ht && ht->u.v.nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "XML-RPC doesn't support circular references");
return NULL;
}
- MAKE_STD_ZVAL(val_arr);
- MAKE_COPY_ZVAL(&val, val_arr);
- convert_to_array(val_arr);
+ ZVAL_COPY(&val_arr, &val);
+ convert_to_array(&val_arr);
- vtype = determine_vector_type(Z_ARRVAL_P(val_arr));
+ vtype = determine_vector_type(Z_ARRVAL(val_arr));
xReturn = XMLRPC_CreateVector(key, vtype);
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(val_arr));
- while(zend_hash_get_current_data(Z_ARRVAL_P(val_arr), (void**)&pIter) == SUCCESS) {
- int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val_arr), &my_key, &num_index);
-
- switch (res) {
- case HASH_KEY_NON_EXISTENT:
- break;
- case HASH_KEY_IS_STRING:
- case HASH_KEY_IS_LONG:
- ht = HASH_OF(*pIter);
- if (ht) {
- ht->nApplyCount++;
- }
- if (res == HASH_KEY_IS_LONG) {
- char *num_str = NULL;
-
- if (vtype != xmlrpc_vector_array) {
- spprintf(&num_str, 0, "%ld", num_index);
- }
- XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(num_str, *pIter, depth++ TSRMLS_CC));
- if (num_str) {
- efree(num_str);
- }
- } else {
- XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key, *pIter, depth++ TSRMLS_CC));
- }
- if (ht) {
- ht->nApplyCount--;
- }
- break;
+ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(val_arr), num_index, my_key, pIter) {
+ ht = HASH_OF(pIter);
+ if (ht) {
+ ht->u.v.nApplyCount++;
+ }
+ if (my_key == NULL) {
+ char *num_str = NULL;
+
+ if (vtype != xmlrpc_vector_array) {
+ spprintf(&num_str, 0, "%ld", num_index);
+ }
+
+ XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(num_str, pIter, depth++ TSRMLS_CC));
+ if (num_str) {
+ efree(num_str);
+ }
+ } else {
+ XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key->val, pIter, depth++ TSRMLS_CC));
+ }
+ if (ht) {
+ ht->u.v.nApplyCount--;
}
- zend_hash_move_forward(Z_ARRVAL_P(val_arr));
- }
+ break;
+ } ZEND_HASH_FOREACH_END();
zval_ptr_dtor(&val_arr);
}
break;
}
/* recursively convert xmlrpc values into php values */
-static zval* XMLRPC_to_PHP(XMLRPC_VALUE el)
+static void XMLRPC_to_PHP(XMLRPC_VALUE el, zval *elem)
{
- zval* elem = NULL;
const char* pStr;
if (el) {
XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(el);
- MAKE_STD_ZVAL(elem); /* init. very important. spent a frustrating day finding this out. */
-
- switch(type) {
+ switch (type) {
case xmlrpc_empty:
- Z_TYPE_P(elem) = IS_NULL;
+ ZVAL_NULL(elem);
break;
case xmlrpc_string:
pStr = XMLRPC_GetValueString(el);
if (pStr) {
- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
- Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
- Z_TYPE_P(elem) = IS_STRING;
+ ZVAL_STRINGL(elem, pStr, XMLRPC_GetValueStringLen(el));
}
break;
case xmlrpc_int:
- Z_LVAL_P(elem) = XMLRPC_GetValueInt(el);
- Z_TYPE_P(elem) = IS_LONG;
+ ZVAL_LONG(elem, XMLRPC_GetValueInt(el));
break;
case xmlrpc_boolean:
- Z_LVAL_P(elem) = XMLRPC_GetValueBoolean(el);
- Z_TYPE_P(elem) = IS_BOOL;
+ ZVAL_BOOL(elem, XMLRPC_GetValueBoolean(el));
break;
case xmlrpc_double:
- Z_DVAL_P(elem) = XMLRPC_GetValueDouble(el);
- Z_TYPE_P(elem) = IS_DOUBLE;
+ ZVAL_DOUBLE(elem, XMLRPC_GetValueDouble(el));
break;
case xmlrpc_datetime:
- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
- Z_STRVAL_P(elem) = estrndup(XMLRPC_GetValueDateTime_ISO8601(el), Z_STRLEN_P(elem));
- Z_TYPE_P(elem) = IS_STRING;
+ ZVAL_STRINGL(elem, XMLRPC_GetValueDateTime_ISO8601(el), XMLRPC_GetValueStringLen(el));
break;
case xmlrpc_base64:
pStr = XMLRPC_GetValueBase64(el);
if (pStr) {
- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
- Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
- Z_TYPE_P(elem) = IS_STRING;
+ ZVAL_STRINGL(elem, pStr, XMLRPC_GetValueStringLen(el));
}
break;
case xmlrpc_vector:
XMLRPC_VALUE xIter = XMLRPC_VectorRewind(el);
while( xIter ) {
- zval *val = XMLRPC_to_PHP(xIter);
- if (val) {
+ zval val;
+ ZVAL_UNDEF(&val);
+ XMLRPC_to_PHP(xIter, &val);
+ if (!Z_ISUNDEF(val)) {
add_zval(elem, XMLRPC_GetValueID(xIter), &val);
}
xIter = XMLRPC_VectorNext(el);
}
set_zval_xmlrpc_type(elem, type);
}
- return elem;
}
/* {{{ proto string xmlrpc_encode_request(string method, mixed params [, array output_options])
set_output_options(&out, out_opts ? out_opts : 0);
- if (return_value_used) {
+ if (USED_RET()) {
xRequest = XMLRPC_RequestNew();
if (xRequest) {
outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0);
if (outBuf) {
- RETVAL_STRING(outBuf, 1);
+ RETVAL_STRING(outBuf);
free(outBuf);
}
XMLRPC_RequestFree(xRequest, 1);
PHP_FUNCTION(xmlrpc_encode)
{
XMLRPC_VALUE xOut = NULL;
- zval **arg1;
+ zval *arg1;
char *outBuf;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg1) == FAILURE) {
return;
}
- if (return_value_used) {
+ if (USED_RET()) {
/* convert native php type to xmlrpc type */
- xOut = PHP_to_XMLRPC(*arg1 TSRMLS_CC);
+ xOut = PHP_to_XMLRPC(arg1 TSRMLS_CC);
/* generate raw xml from xmlrpc data */
outBuf = XMLRPC_VALUE_ToXML(xOut, 0);
if (xOut) {
if (outBuf) {
- RETVAL_STRING(outBuf, 1);
+ RETVAL_STRING(outBuf);
free(outBuf);
}
/* cleanup */
}
/* }}} */
-zval* decode_request_worker(char *xml_in, int xml_in_len, char *encoding_in, zval* method_name_out) /* {{{ */
+void decode_request_worker(char *xml_in, int xml_in_len, char *encoding_in, zval* method_name_out, zval *retval) /* {{{ */
{
- zval* retval = NULL;
XMLRPC_REQUEST response;
STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}};
const char *method_name;
/* generate XMLRPC_REQUEST from raw xml */
response = XMLRPC_REQUEST_FromXML(xml_in, xml_in_len, &opts);
if (response) {
+ ZVAL_NULL(retval);
/* convert xmlrpc data to native php types */
- retval = XMLRPC_to_PHP(XMLRPC_RequestGetData(response));
+ XMLRPC_to_PHP(XMLRPC_RequestGetData(response), retval);
if (XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) {
if (method_name_out) {
method_name = XMLRPC_RequestGetMethodName(response);
if (method_name) {
- zval_dtor(method_name_out);
- Z_TYPE_P(method_name_out) = IS_STRING;
- Z_STRVAL_P(method_name_out) = estrdup(method_name);
- Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out));
- } else if (retval) {
- zval_ptr_dtor(&retval);
- retval = NULL;
+ zval_ptr_dtor(method_name_out);
+ ZVAL_STRING(method_name_out, method_name);
+ } else {
+ zval_ptr_dtor(retval);
}
}
}
/* dust, sweep, and mop */
XMLRPC_RequestFree(response, 1);
}
- return retval;
}
/* }}} */
PHP_FUNCTION(xmlrpc_decode_request)
{
char *xml, *encoding = NULL;
- zval **method;
+ zval *method;
int xml_len, encoding_len = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|s", &xml, &xml_len, &method, &encoding, &encoding_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|s", &xml, &xml_len, &method, &encoding, &encoding_len) == FAILURE) {
return;
}
+ ZVAL_DEREF(method);
- if (return_value_used) {
- zval* retval = decode_request_worker(xml, xml_len, encoding_len ? encoding : NULL, *method);
- if (retval) {
- *return_value = *retval;
- FREE_ZVAL(retval);
- }
+ if (USED_RET()) {
+ decode_request_worker(xml, xml_len, encoding_len ? encoding : NULL, method, return_value);
}
}
/* }}} */
return;
}
- if (return_value_used) {
- zval* retval = decode_request_worker(arg1, arg1_len, arg2_len ? arg2 : NULL, NULL);
- if (retval) {
- *return_value = *retval;
- FREE_ZVAL(retval);
- }
+ if (USED_RET()) {
+ decode_request_worker(arg1, arg1_len, arg2_len ? arg2 : NULL, NULL, return_value);
}
}
/* }}} */
return;
}
- if (return_value_used) {
- zval *method_map, *introspection_map;
+ if (USED_RET()) {
xmlrpc_server_data *server = emalloc(sizeof(xmlrpc_server_data));
- MAKE_STD_ZVAL(method_map);
- MAKE_STD_ZVAL(introspection_map);
-
- array_init(method_map);
- array_init(introspection_map);
/* allocate server data. free'd in destroy_server_data() */
- server->method_map = method_map;
- server->introspection_map = introspection_map;
+ array_init(&server->method_map);
+ array_init(&server->introspection_map);
server->server_ptr = XMLRPC_ServerCreate();
XMLRPC_ServerRegisterIntrospectionCallback(server->server_ptr, php_xmlrpc_introspection_callback);
/* store for later use */
- ZEND_REGISTER_RESOURCE(return_value,server, le_xmlrpc_server);
+ ZEND_REGISTER_RESOURCE(return_value, server, le_xmlrpc_server);
}
}
/* }}} */
PHP_FUNCTION(xmlrpc_server_destroy)
{
zval *arg1;
- int bSuccess = FAILURE, type;
+ int bSuccess = FAILURE;
xmlrpc_server_data *server;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
return;
}
- server = zend_list_find(Z_LVAL_P(arg1), &type);
-
- if (server && type == le_xmlrpc_server) {
- bSuccess = zend_list_delete(Z_LVAL_P(arg1));
+ ZEND_FETCH_RESOURCE(server, xmlrpc_server_data*, arg1, -1, "xmlrpc server", le_xmlrpc_server);
+ if (server) {
+ bSuccess = zend_list_close(Z_RES_P(arg1));
/* called by hashtable destructor
* destroy_server_data(server);
*/
}
- RETVAL_LONG(bSuccess == SUCCESS);
+ RETURN_BOOL(bSuccess == SUCCESS);
}
/* }}} */
static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server, XMLRPC_REQUEST xRequest, void* data) /* {{{ */
{
xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
- zval** php_function;
- zval* xmlrpc_params;
- zval* callback_params[3];
+ zval* php_function;
+ zval xmlrpc_params;
+ zval callback_params[3];
TSRMLS_FETCH();
- zval_dtor(pData->xmlrpc_method);
- zval_dtor(pData->return_data);
+ zval_ptr_dtor(&pData->xmlrpc_method);
+ zval_ptr_dtor(&pData->return_data);
/* convert xmlrpc to native php types */
- ZVAL_STRING(pData->xmlrpc_method, XMLRPC_RequestGetMethodName(xRequest), 1);
- xmlrpc_params = XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest));
+ ZVAL_STRING(&pData->xmlrpc_method, XMLRPC_RequestGetMethodName(xRequest));
+ XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest), &xmlrpc_params);
/* check if the called method has been previous registered */
- if(zend_hash_find(Z_ARRVAL_P(pData->server->method_map),
- Z_STRVAL_P(pData->xmlrpc_method),
- Z_STRLEN_P(pData->xmlrpc_method) + 1,
- (void**)&php_function) == SUCCESS) {
-
- pData->php_function = *php_function;
+ if ((php_function = zend_hash_find(Z_ARRVAL(pData->server->method_map), Z_STR(pData->xmlrpc_method))) != NULL) {
+ ZVAL_COPY_VALUE(&pData->php_function, php_function);
}
/* setup data hoojum */
- callback_params[0] = pData->xmlrpc_method;
- callback_params[1] = xmlrpc_params;
- callback_params[2] = pData->caller_params;
+ ZVAL_COPY_VALUE(&callback_params[0], &pData->xmlrpc_method);
+ ZVAL_COPY_VALUE(&callback_params[1], &xmlrpc_params);
+ ZVAL_COPY_VALUE(&callback_params[2], &pData->caller_params);
/* Use same C function for all methods */
/* php func prototype: function user_func($method_name, $xmlrpc_params, $user_params) */
- call_user_function(CG(function_table), NULL, pData->php_function, pData->return_data, 3, callback_params TSRMLS_CC);
+ call_user_function(CG(function_table), NULL, &pData->php_function, &pData->return_data, 3, callback_params TSRMLS_CC);
pData->php_executed = 1;
zval_ptr_dtor(&xmlrpc_params);
+ zval_ptr_dtor(&pData->xmlrpc_method);
- return PHP_to_XMLRPC(pData->return_data TSRMLS_CC);
+ return PHP_to_XMLRPC(&pData->return_data TSRMLS_CC);
}
/* }}} */
*/
static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data) /* {{{ */
{
- zval retval, **php_function;
- zval *callback_params[1];
- char *php_function_name;
+ zval retval, *php_function;
+ zval callback_params[1];
+ zend_string *php_function_name;
xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
TSRMLS_FETCH();
/* setup data hoojum */
- callback_params[0] = pData->caller_params;
-
- /* loop through and call all registered callbacks */
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pData->server->introspection_map));
- while (1) {
- if (zend_hash_get_current_data(Z_ARRVAL_P(pData->server->introspection_map), (void**)&php_function) == SUCCESS) {
- if (zend_is_callable(*php_function, 0, &php_function_name TSRMLS_CC)) {
- /* php func prototype: function string user_func($user_params) */
- if (call_user_function(CG(function_table), NULL, *php_function, &retval, 1, callback_params TSRMLS_CC) == SUCCESS) {
- XMLRPC_VALUE xData;
- STRUCT_XMLRPC_ERROR err = {0};
-
- /* return value should be a string */
- convert_to_string(&retval);
-
- xData = XMLRPC_IntrospectionCreateDescription(Z_STRVAL(retval), &err);
-
- if (xData) {
- if (!XMLRPC_ServerAddIntrospectionData(server, xData)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s(), improper element structure", php_function_name);
- }
- XMLRPC_CleanupValue(xData);
- } else {
- /* could not create description */
- if (err.xml_elem_error.parser_code) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to add introspection data returned from %s()",
- err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error, php_function_name);
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s()", php_function_name);
- }
+ ZVAL_COPY_VALUE(&callback_params[0], &pData->caller_params);
+
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL(pData->server->introspection_map), php_function) {
+ if (zend_is_callable(php_function, 0, &php_function_name TSRMLS_CC)) {
+ /* php func prototype: function string user_func($user_params) */
+ if (call_user_function(CG(function_table), NULL, php_function, &retval, 1, callback_params TSRMLS_CC) == SUCCESS) {
+ XMLRPC_VALUE xData;
+ STRUCT_XMLRPC_ERROR err = {0};
+
+ /* return value should be a string */
+ convert_to_string(&retval);
+
+ xData = XMLRPC_IntrospectionCreateDescription(Z_STRVAL(retval), &err);
+
+ if (xData) {
+ if (!XMLRPC_ServerAddIntrospectionData(server, xData)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s(), improper element structure", php_function_name->val);
}
- zval_dtor(&retval);
+ XMLRPC_CleanupValue(xData);
} else {
- /* user func failed */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling user introspection callback: %s()", php_function_name);
+ /* could not create description */
+ if (err.xml_elem_error.parser_code) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to add introspection data returned from %s()",
+ err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error, php_function_name->val);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s()", php_function_name->val);
+ }
}
+ zval_ptr_dtor(&retval);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid callback '%s' passed", php_function_name);
+ /* user func failed */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling user introspection callback: %s()", php_function_name->val);
}
- efree(php_function_name);
} else {
- break;
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid callback '%s' passed", php_function_name->val);
}
- zend_hash_move_forward(Z_ARRVAL_P(pData->server->introspection_map));
- }
+ STR_RELEASE(php_function_name);
+ } ZEND_HASH_FOREACH_END();
/* so we don't call the same callbacks ever again */
- zend_hash_clean(Z_ARRVAL_P(pData->server->introspection_map));
+ zend_hash_clean(Z_ARRVAL(pData->server->introspection_map));
}
/* }}} */
{
char *method_key;
int method_key_len;
- zval *handle, *method_name_save, **method_name;
- int type;
+ zval *handle, *method_name;
xmlrpc_server_data* server;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ", &handle, &method_key, &method_key_len, &method_name) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz", &handle, &method_key, &method_key_len, &method_name) == FAILURE) {
return;
}
- server = zend_list_find(Z_LVAL_P(handle), &type);
-
- if (type == le_xmlrpc_server) {
- /* register with C engine. every method just calls our standard callback,
- * and it then dispatches to php as necessary
- */
- if (XMLRPC_ServerRegisterMethod(server->server_ptr, method_key, php_xmlrpc_callback)) {
- /* save for later use */
- ALLOC_ZVAL(method_name_save);
- MAKE_COPY_ZVAL(method_name, method_name_save);
+ ZEND_FETCH_RESOURCE(server, xmlrpc_server_data*, handle, -1, "xmlrpc server", le_xmlrpc_server);
- /* register our php method */
- add_zval(server->method_map, method_key, &method_name_save);
+ /* register with C engine. every method just calls our standard callback,
+ * and it then dispatches to php as necessary
+ */
+ if (XMLRPC_ServerRegisterMethod(server->server_ptr, method_key, php_xmlrpc_callback)) {
+ /* save for later use */
- RETURN_BOOL(1);
+ if (Z_REFCOUNTED_P(method_name)) {
+ Z_ADDREF_P(method_name);
}
+ /* register our php method */
+ add_zval(&server->method_map, method_key, method_name);
+
+ RETURN_TRUE;
}
- RETURN_BOOL(0);
}
/* }}} */
Register a PHP function to generate documentation */
PHP_FUNCTION(xmlrpc_server_register_introspection_callback)
{
- zval **method_name, *handle, *method_name_save;
- int type;
+ zval *method_name, *handle;
xmlrpc_server_data* server;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &handle, &method_name) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &handle, &method_name) == FAILURE) {
return;
}
- server = zend_list_find(Z_LVAL_P(handle), &type);
+ ZEND_FETCH_RESOURCE(server, xmlrpc_server_data*, handle, -1, "xmlrpc server", le_xmlrpc_server);
- if (type == le_xmlrpc_server) {
- /* save for later use */
- ALLOC_ZVAL(method_name_save);
- MAKE_COPY_ZVAL(method_name, method_name_save);
-
- /* register our php method */
- add_zval(server->introspection_map, NULL, &method_name_save);
-
- RETURN_BOOL(1);
+ if (Z_REFCOUNTED_P(method_name)) {
+ Z_ADDREF_P(method_name);
}
- RETURN_BOOL(0);
+ /* register our php method */
+ add_zval(&server->introspection_map, NULL, method_name);
+
+ RETURN_TRUE;
}
/* }}} */
Parses XML requests and call methods */
PHP_FUNCTION(xmlrpc_server_call_method)
{
- xmlrpc_callback_data data = {0};
XMLRPC_REQUEST xRequest;
+ xmlrpc_callback_data data;
STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS input_opts;
xmlrpc_server_data* server;
- zval **caller_params, *handle, *output_opts = NULL;
+ zval *caller_params, *handle, *output_opts = NULL;
char *rawxml;
- int rawxml_len, type;
+ int rawxml_len;
php_output_options out;
- int argc =ZEND_NUM_ARGS();
+ int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|a", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|a", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) {
return;
}
/* user output options */
set_output_options(&out, output_opts);
}
- server = zend_list_find(Z_LVAL_P(handle), &type);
+ ZEND_FETCH_RESOURCE(server, xmlrpc_server_data*, handle, -1, "xmlrpc server", le_xmlrpc_server);
- if (type == le_xmlrpc_server) {
- /* HACK: use output encoding for now */
- input_opts.xml_elem_opts.encoding = utf8_get_encoding_id_from_string(out.xmlrpc_out.xml_elem_opts.encoding);
+ /* HACK: use output encoding for now */
+ input_opts.xml_elem_opts.encoding = utf8_get_encoding_id_from_string(out.xmlrpc_out.xml_elem_opts.encoding);
- /* generate an XMLRPC_REQUEST from the raw xml input */
- xRequest = XMLRPC_REQUEST_FromXML(rawxml, rawxml_len, &input_opts);
+ /* generate an XMLRPC_REQUEST from the raw xml input */
+ xRequest = XMLRPC_REQUEST_FromXML(rawxml, rawxml_len, &input_opts);
- if (xRequest) {
- const char* methodname = XMLRPC_RequestGetMethodName(xRequest);
- XMLRPC_VALUE xAnswer = NULL;
- MAKE_STD_ZVAL(data.xmlrpc_method); /* init. very important. spent a frustrating day finding this out. */
- MAKE_STD_ZVAL(data.return_data);
- Z_TYPE_P(data.return_data) = IS_NULL; /* in case value is never init'd, we don't dtor to think it is a string or something */
- Z_TYPE_P(data.xmlrpc_method) = IS_NULL;
-
- /* setup some data to pass to the callback function */
- data.caller_params = *caller_params;
- data.php_executed = 0;
- data.server = server;
-
- /* We could just call the php method directly ourselves at this point, but we do this
- * with a C callback in case the xmlrpc library ever implements some cool usage stats,
- * or somesuch.
- */
- xAnswer = XMLRPC_ServerCallMethod(server->server_ptr, xRequest, &data);
- if (xAnswer && out.b_php_out) {
- zval_dtor(data.return_data);
- FREE_ZVAL(data.return_data);
- data.return_data = XMLRPC_to_PHP(xAnswer);
- } else if (data.php_executed && !out.b_php_out && !xAnswer) {
- xAnswer = PHP_to_XMLRPC(data.return_data TSRMLS_CC);
- }
+ if (xRequest) {
+ const char* methodname = XMLRPC_RequestGetMethodName(xRequest);
+ XMLRPC_VALUE xAnswer = NULL;
+ ZVAL_NULL(&data.xmlrpc_method); /* init. very important. spent a frustrating day finding this out. */
+ ZVAL_NULL(&data.return_data);
+ ZVAL_NULL(&data.return_data); /* in case value is never init'd, we don't dtor to think it is a string or something */
+ ZVAL_NULL(&data.xmlrpc_method);
- /* should we return data as xml? */
- if (!out.b_php_out) {
- XMLRPC_REQUEST xResponse = XMLRPC_RequestNew();
- if (xResponse) {
- char *outBuf = 0;
- int buf_len = 0;
-
- /* automagically determine output serialization type from request type */
- if (out.b_auto_version) {
- XMLRPC_REQUEST_OUTPUT_OPTIONS opts = XMLRPC_RequestGetOutputOptions(xRequest);
- if (opts) {
- out.xmlrpc_out.version = opts->version;
- }
- }
- /* set some required request hoojum */
- XMLRPC_RequestSetOutputOptions(xResponse, &out.xmlrpc_out);
- XMLRPC_RequestSetRequestType(xResponse, xmlrpc_request_response);
- XMLRPC_RequestSetData(xResponse, xAnswer);
- XMLRPC_RequestSetMethodName(xResponse, methodname);
-
- /* generate xml */
- outBuf = XMLRPC_REQUEST_ToXML(xResponse, &buf_len);
- if (outBuf) {
- RETVAL_STRINGL(outBuf, buf_len, 1);
- free(outBuf);
+ /* setup some data to pass to the callback function */
+ ZVAL_COPY_VALUE(&data.caller_params, caller_params);
+ data.php_executed = 0;
+ data.server = server;
+
+ /* We could just call the php method directly ourselves at this point, but we do this
+ * with a C callback in case the xmlrpc library ever implements some cool usage stats,
+ * or somesuch.
+ */
+ xAnswer = XMLRPC_ServerCallMethod(server->server_ptr, xRequest, &data);
+ if (xAnswer && out.b_php_out) {
+ XMLRPC_to_PHP(xAnswer, &data.return_data);
+ } else if (data.php_executed && !out.b_php_out && !xAnswer) {
+ xAnswer = PHP_to_XMLRPC(&data.return_data TSRMLS_CC);
+ }
+
+ /* should we return data as xml? */
+ if (!out.b_php_out) {
+ XMLRPC_REQUEST xResponse = XMLRPC_RequestNew();
+ if (xResponse) {
+ char *outBuf = 0;
+ int buf_len = 0;
+
+ /* automagically determine output serialization type from request type */
+ if (out.b_auto_version) {
+ XMLRPC_REQUEST_OUTPUT_OPTIONS opts = XMLRPC_RequestGetOutputOptions(xRequest);
+ if (opts) {
+ out.xmlrpc_out.version = opts->version;
}
- /* cleanup after ourselves. what a sty! */
- XMLRPC_RequestFree(xResponse, 0);
}
- } else { /* or as native php types? */
- *return_value = *data.return_data;
- zval_copy_ctor(return_value);
+ /* set some required request hoojum */
+ XMLRPC_RequestSetOutputOptions(xResponse, &out.xmlrpc_out);
+ XMLRPC_RequestSetRequestType(xResponse, xmlrpc_request_response);
+ XMLRPC_RequestSetData(xResponse, xAnswer);
+ XMLRPC_RequestSetMethodName(xResponse, methodname);
+
+ /* generate xml */
+ outBuf = XMLRPC_REQUEST_ToXML(xResponse, &buf_len);
+ if (outBuf) {
+ RETVAL_STRINGL(outBuf, buf_len);
+ free(outBuf);
+ }
+ /* cleanup after ourselves. what a sty! */
+ XMLRPC_RequestFree(xResponse, 0);
}
+ } else { /* or as native php types? */
+ ZVAL_COPY(return_value, &data.return_data);
+ }
- /* cleanup after ourselves. what a sty! */
- zval_ptr_dtor(&data.xmlrpc_method);
-
- zval_dtor(data.return_data);
- FREE_ZVAL(data.return_data);
-
- if (xAnswer) {
- XMLRPC_CleanupValue(xAnswer);
- }
+ /* cleanup after ourselves. what a sty! */
+ zval_ptr_dtor(&data.xmlrpc_method);
+ zval_ptr_dtor(&data.return_data);
- XMLRPC_RequestFree(xRequest, 1);
+ if (xAnswer) {
+ XMLRPC_CleanupValue(xAnswer);
}
+
+ XMLRPC_RequestFree(xRequest, 1);
}
}
/* }}} */
PHP_FUNCTION(xmlrpc_server_add_introspection_data)
{
zval *handle, *desc;
- int type;
xmlrpc_server_data* server;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &handle, &desc) == FAILURE) {
return;
}
- server = zend_list_find(Z_LVAL_P(handle), &type);
+ ZEND_FETCH_RESOURCE(server, xmlrpc_server_data*, handle, -1, "xmlrpc server", le_xmlrpc_server);
- if (type == le_xmlrpc_server) {
- XMLRPC_VALUE xDesc = PHP_to_XMLRPC(desc TSRMLS_CC);
- if (xDesc) {
- int retval = XMLRPC_ServerAddIntrospectionData(server->server_ptr, xDesc);
- XMLRPC_CleanupValue(xDesc);
- RETURN_LONG(retval);
- }
+ XMLRPC_VALUE xDesc = PHP_to_XMLRPC(desc TSRMLS_CC);
+ if (xDesc) {
+ int retval = XMLRPC_ServerAddIntrospectionData(server->server_ptr, xDesc);
+ XMLRPC_CleanupValue(xDesc);
+ RETURN_LONG(retval);
}
RETURN_LONG(0);
}
Decodes XML into a list of method descriptions */
PHP_FUNCTION(xmlrpc_parse_method_descriptions)
{
- zval *retval;
char *arg1;
int arg1_len;
return;
}
- if (return_value_used) {
+ if (USED_RET()) {
STRUCT_XMLRPC_ERROR err = {0};
XMLRPC_VALUE xVal = XMLRPC_IntrospectionCreateDescription(arg1, &err);
if (xVal) {
- retval = XMLRPC_to_PHP(xVal);
-
- if (retval) {
- RETVAL_ZVAL(retval, 1, 1);
- }
+ XMLRPC_to_PHP(xVal, return_value);
/* dust, sweep, and mop */
XMLRPC_CleanupValue(xVal);
} else {
if (Z_TYPE_P(value) == IS_STRING) {
if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) {
const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none);
- zval* type;
+ zval type;
- MAKE_STD_ZVAL(type);
-
- Z_TYPE_P(type) = IS_STRING;
- Z_STRVAL_P(type) = estrdup(typestr);
- Z_STRLEN_P(type) = strlen(typestr);
+ ZVAL_STRING(&type, typestr);
if (newtype == xmlrpc_datetime) {
- XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val);
+ XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, Z_STRVAL_P(value));
if (v) {
time_t timestamp = (time_t) php_parse_date((char *)XMLRPC_GetValueDateTime_ISO8601(v), NULL);
if (timestamp != -1) {
- zval* ztimestamp;
-
- MAKE_STD_ZVAL(ztimestamp);
+ zval ztimestamp;
- ztimestamp->type = IS_LONG;
- ztimestamp->value.lval = timestamp;
+ ZVAL_LONG(&ztimestamp, timestamp);
convert_to_object(value);
- if (SUCCESS == zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) {
- bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL);
+ if (zend_hash_str_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR) - 1, &type)) {
+ bSuccess = zend_hash_str_update(Z_OBJPROP_P(value), OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR) - 1, &ztimestamp) != NULL;
}
} else {
zval_ptr_dtor(&type);
}
} else {
convert_to_object(value);
- bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+ bSuccess = zend_hash_str_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR) - 1, &type) != NULL;
}
}
}
/* }}} */
/* return xmlrpc type of a php value */
-XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue) /* {{{ */
+XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval* newvalue) /* {{{ */
{
XMLRPC_VALUE_TYPE type = xmlrpc_none;
TSRMLS_FETCH();
#ifndef BOOL_AS_LONG
/* Right thing to do, but it breaks some legacy code. */
- case IS_BOOL:
+ case IS_TRUE:
+ case IS_FALSE:
type = xmlrpc_boolean;
break;
#else
break;
case IS_OBJECT:
{
- zval** attr;
+ zval* attr;
type = xmlrpc_vector;
- if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) {
- if (Z_TYPE_PP(attr) == IS_STRING) {
- type = xmlrpc_str_as_type(Z_STRVAL_PP(attr));
+ if ((attr = zend_hash_str_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR) - 1)) != NULL) {
+ if (Z_TYPE_P(attr) == IS_STRING) {
+ type = xmlrpc_str_as_type(Z_STRVAL_P(attr));
}
}
break;
/* if requested, return an unmolested (magic removed) copy of the value */
if (newvalue) {
- zval** val;
+ zval* val;
if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) {
- if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR), (void**) &val) == SUCCESS) {
- *newvalue = *val;
+ if ((val = zend_hash_str_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR) - 1)) != NULL) {
+ ZVAL_COPY_VALUE(newvalue, val);
}
} else {
- *newvalue = value;
+ ZVAL_COPY_VALUE(newvalue, value);
}
}
}
Sets xmlrpc type, base64 or datetime, for a PHP string value */
PHP_FUNCTION(xmlrpc_set_type)
{
- zval **arg;
+ zval *arg;
char *type;
int type_len;
XMLRPC_VALUE_TYPE vtype;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &arg, &type, &type_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &arg, &type, &type_len) == FAILURE) {
return;
}
+ ZVAL_DEREF(arg);
+
vtype = xmlrpc_str_as_type(type);
if (vtype != xmlrpc_none) {
- if (set_zval_xmlrpc_type(*arg, vtype) == SUCCESS) {
+ if (set_zval_xmlrpc_type(arg, vtype) == SUCCESS) {
RETURN_TRUE;
}
} else {
Gets xmlrpc type for a PHP value. Especially useful for base64 and datetime strings */
PHP_FUNCTION(xmlrpc_get_type)
{
- zval **arg;
+ zval *arg;
XMLRPC_VALUE_TYPE type;
XMLRPC_VECTOR_TYPE vtype = xmlrpc_vector_none;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
return;
}
- type = get_zval_xmlrpc_type(*arg, 0);
+ type = get_zval_xmlrpc_type(arg, 0);
if (type == xmlrpc_vector) {
- vtype = determine_vector_type((Z_TYPE_PP(arg) == IS_OBJECT) ? Z_OBJPROP_PP(arg) : Z_ARRVAL_PP(arg));
+ vtype = determine_vector_type((Z_TYPE_P(arg) == IS_OBJECT) ? Z_OBJPROP_P(arg) : Z_ARRVAL_P(arg));
}
- RETURN_STRING((char*) xmlrpc_type_as_str(type, vtype), 1);
+ RETURN_STRING((char*) xmlrpc_type_as_str(type, vtype));
}
/* }}} */
Determines if an array value represents an XMLRPC fault. */
PHP_FUNCTION(xmlrpc_is_fault)
{
- zval *arg, **val;
+ zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arg) == FAILURE) {
return;
* array, which is rather expensive, especially if it was
* a big array. Thus, we resort to this not so clever hackery.
*/
- if (zend_hash_find(Z_ARRVAL_P(arg), FAULT_CODE, FAULT_CODE_LEN + 1, (void**) &val) == SUCCESS &&
- zend_hash_find(Z_ARRVAL_P(arg), FAULT_STRING, FAULT_STRING_LEN + 1, (void**) &val) == SUCCESS) {
+ if (zend_hash_str_exists(Z_ARRVAL_P(arg), FAULT_CODE, FAULT_CODE_LEN) &&
+ zend_hash_str_exists(Z_ARRVAL_P(arg), FAULT_STRING, FAULT_STRING_LEN)) {
RETURN_TRUE;
}