📄 xmlrpc-epi-php.c
字号:
} } /* 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; zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val)); 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)) { options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_cdata_escaping; } else if(!strcmp(Z_STRVAL_PP(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)) { options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_print_escaping; } else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_MARKUP)) { options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_markup_escaping; } } } else { break; } 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; } } } } }}/******************* encode / decode *******************//* php arrays have no distinction between array and struct types. * they even allow mixed. Thus, we determine the type by iterating * through the entire array and figuring out each element. * room for some optimation here if we stop after a specific # of elements. */static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht){ int bArray = 0, bStruct = 0, bMixed = 0; unsigned long num_index; char* 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) { if(bStruct) { bMixed = 1; break; } bArray = 1; } else if(res == HASH_KEY_NON_EXISTANT) { break; } else if(res == HASH_KEY_IS_STRING) { if(bArray) { bMixed = 1; break; } bStruct = 1; } zend_hash_move_forward(ht); } return bMixed ? xmlrpc_vector_mixed : (bStruct ? xmlrpc_vector_struct : xmlrpc_vector_array);}/* recursively convert php values into xmlrpc values */static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int depth TSRMLS_DC){ XMLRPC_VALUE xReturn = NULL; if(in_val) { zval* val = NULL; XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val); if(val) { switch(type) { case xmlrpc_base64: if(Z_TYPE_P(val) == IS_NULL) { xReturn = XMLRPC_CreateValueEmpty(); XMLRPC_SetValueID(xReturn, key, 0); } else { xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); } break; case xmlrpc_datetime: convert_to_string(val); xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val)); break; case xmlrpc_boolean: convert_to_boolean(val); xReturn = XMLRPC_CreateValueBoolean(key, Z_LVAL_P(val)); break; case xmlrpc_int: convert_to_long(val); xReturn = XMLRPC_CreateValueInt(key, Z_LVAL_P(val)); break; case xmlrpc_double: convert_to_double(val); xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL_P(val)); break; case xmlrpc_string: convert_to_string(val); xReturn = XMLRPC_CreateValueString(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); break; case xmlrpc_vector: { unsigned long num_index; zval** pIter; char* my_key; HashTable *ht = NULL; ht = HASH_OF(val); if (ht && ht->nApplyCount > 1) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "XML-RPC doesn't support circular references"); return NULL; } convert_to_array(val); xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(val))); zend_hash_internal_pointer_reset(Z_ARRVAL_P(val)); while(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) { int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val), &my_key, &num_index); switch (res) { case HASH_KEY_NON_EXISTANT: 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) { XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(0, *pIter, depth++ TSRMLS_CC)); } else { XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key, *pIter, depth++ TSRMLS_CC)); } if (ht) { ht->nApplyCount--; } break; } zend_hash_move_forward(Z_ARRVAL_P(val)); } } break; default: break; } } } return xReturn;}static XMLRPC_VALUE PHP_to_XMLRPC(zval* root_val TSRMLS_DC){ return PHP_to_XMLRPC_worker(NULL, root_val, 0 TSRMLS_CC);}/* recursively convert xmlrpc values into php values */static zval* XMLRPC_to_PHP(XMLRPC_VALUE el){ 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) { case xmlrpc_empty: Z_TYPE_P(elem) = IS_NULL; 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; } break; case xmlrpc_int: Z_LVAL_P(elem) = XMLRPC_GetValueInt(el); Z_TYPE_P(elem) = IS_LONG; break; case xmlrpc_boolean: Z_LVAL_P(elem) = XMLRPC_GetValueBoolean(el); Z_TYPE_P(elem) = IS_BOOL; break; case xmlrpc_double: Z_DVAL_P(elem) = XMLRPC_GetValueDouble(el); Z_TYPE_P(elem) = IS_DOUBLE; 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; 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; } break; case xmlrpc_vector: if(array_init(elem) == SUCCESS) { XMLRPC_VALUE xIter = XMLRPC_VectorRewind(el); while( xIter ) { zval* val = XMLRPC_to_PHP(xIter); if(val) { add_zval(elem, XMLRPC_GetValueID(xIter), &val); } xIter = XMLRPC_VectorNext(el); } } break; default: break; } set_zval_xmlrpc_type(elem, type); } return elem;}/* {{{ proto string xmlrpc_encode_request(string method, mixed params) Generates XML for a method request */PHP_FUNCTION(xmlrpc_encode_request){ XMLRPC_REQUEST xRequest = NULL; zval* method, *vals, *out_opts; char* outBuf; php_output_options out; if( !(ARG_COUNT(ht) == 2 || ARG_COUNT(ht) == 3) || getParameters(ht, ARG_COUNT(ht), &method, &vals, &out_opts) == FAILURE) { WRONG_PARAM_COUNT; /* prints/logs a warning and returns */ } set_output_options(&out, (ARG_COUNT(ht) == 3) ? out_opts : 0); if(return_value_used) { xRequest = XMLRPC_RequestNew(); if(xRequest) { XMLRPC_RequestSetOutputOptions(xRequest, &out.xmlrpc_out); if(Z_TYPE_P(method) == IS_NULL) { XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_response); } else { XMLRPC_RequestSetMethodName(xRequest, Z_STRVAL_P(method)); XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_call); } if(Z_TYPE_P(vals) != IS_NULL) { XMLRPC_RequestSetData(xRequest, PHP_to_XMLRPC(vals TSRMLS_CC)); } outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0); if(outBuf) { RETVAL_STRING(outBuf, 1); free(outBuf); } XMLRPC_RequestFree(xRequest, 1); } } if (out.xmlrpc_out.xml_elem_opts.encoding != ENCODING_DEFAULT) { efree(out.xmlrpc_out.xml_elem_opts.encoding); }}/* }}} *//* {{{ proto string xmlrpc_encode(mixed value) Generates XML for a PHP value */PHP_FUNCTION(xmlrpc_encode){ XMLRPC_VALUE xOut = NULL; zval* arg1; char* outBuf; if( !(ARG_COUNT(ht) == 1) || getParameters(ht, ARG_COUNT(ht), &arg1) == FAILURE) { WRONG_PARAM_COUNT; /* prints/logs a warning and returns */ } if( return_value_used ) { /* convert native php type to xmlrpc type */ 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); free(outBuf); } /* cleanup */ XMLRPC_CleanupValue(xOut); } }}/* }}} */zval* decode_request_worker (zval* xml_in, zval* encoding_in, zval* method_name_out){ zval* retval = NULL; XMLRPC_REQUEST response; STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}}; opts.xml_elem_opts.encoding = encoding_in ? utf8_get_encoding_id_from_string(Z_STRVAL_P(encoding_in)) : ENCODING_DEFAULT; /* generate XMLRPC_REQUEST from raw xml */ response = XMLRPC_REQUEST_FromXML(Z_STRVAL_P(xml_in), Z_STRLEN_P(xml_in), &opts); if(response) { /* convert xmlrpc data to native php types */ retval = XMLRPC_to_PHP(XMLRPC_RequestGetData(response)); if(XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) { if(method_name_out) { convert_to_string(method_name_out); Z_TYPE_P(method_name_out) = IS_STRING; Z_STRVAL_P(method_name_out) = estrdup(XMLRPC_RequestGetMethodName(response)); Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out)); } } /* dust, sweep, and mop */ XMLRPC_RequestFree(response, 1); } return retval;}/* {{{ proto array xmlrpc_decode_request(string xml, string& method [, string encoding]) Decodes XML into native PHP types */PHP_FUNCTION(xmlrpc_decode_request){ zval* xml, *method, *encoding = NULL; if( !(ARG_COUNT(ht) == 2 || ARG_COUNT(ht) == 3) || getParameters(ht, ARG_COUNT(ht), &xml, &method, &encoding) == FAILURE) { WRONG_PARAM_COUNT; /* prints/logs a warning and returns */ }#if ZEND_MODULE_API_NO < 20010901 if (!ParameterPassedByReference(ht,2)) { zend_error(E_WARNING,"second argument to xmlrpc_decode_request() passed by value, expecting reference"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -