X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=trunk%2Fphp%2Fxmlrpc%2Flibxmlrpc%2Fxml_to_dandarpc.c;fp=trunk%2Fphp%2Fxmlrpc%2Flibxmlrpc%2Fxml_to_dandarpc.c;h=b51d99172361f4f06cfa50007df69293794c91ad;hb=5a4c1b1278ffa01e630fde47f7c54888ed20a576;hp=0000000000000000000000000000000000000000;hpb=cee5ab52df1c9f38b6eaff2dd354cb22f59028c7;p=plcapi.git diff --git a/trunk/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c b/trunk/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c new file mode 100644 index 0000000..b51d991 --- /dev/null +++ b/trunk/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c @@ -0,0 +1,319 @@ +/* + This file is part of libXMLRPC - a C library for xml-encoded function calls. + + Author: Dan Libby (dan@libby.com) + Epinions.com may be contacted at feedback@epinions-inc.com +*/ + +/* + Copyright 2000 Epinions, Inc. + + Subject to the following 3 conditions, Epinions, Inc. permits you, free + of charge, to (a) use, copy, distribute, modify, perform and display this + software and associated documentation files (the "Software"), and (b) + permit others to whom the Software is furnished to do so as well. + + 1) The above copyright notice and this permission notice shall be included + without modification in all copies or substantial portions of the + Software. + + 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF + ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY + IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE OR NONINFRINGEMENT. + + 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, + SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT + OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING + NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH + DAMAGES. + +*/ + +#ifdef _WIN32 +#include "xmlrpc_win32.h" +#endif +#include +#include +#include "xml_to_dandarpc.h" +#include "base64.h" + +/* list of tokens used in vocab */ +#define ELEM_METHODCALL "methodCall" +#define ELEM_METHODNAME "methodName" +#define ELEM_METHODRESPONSE "methodResponse" +#define ELEM_ROOT "simpleRPC" + +#define ATTR_ARRAY "array" +#define ATTR_BASE64 "base64" +#define ATTR_BOOLEAN "boolean" +#define ATTR_DATETIME "dateTime.iso8601" +#define ATTR_DOUBLE "double" +#define ATTR_ID "id" +#define ATTR_INT "int" +#define ATTR_MIXED "mixed" +#define ATTR_SCALAR "scalar" +#define ATTR_STRING "string" +#define ATTR_STRUCT "struct" +#define ATTR_TYPE "type" +#define ATTR_VECTOR "vector" +#define ATTR_VERSION "version" + +#define VAL_VERSION_0_9 "0.9" + + +XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xCurrent, xml_element* el) { + if(!xCurrent) { + xCurrent = XMLRPC_CreateValueEmpty(); + } + + if(el->name) { + const char* id = NULL; + const char* type = NULL; + xml_element_attr* attr_iter = Q_Head(&el->attrs); + + while(attr_iter) { + if(!strcmp(attr_iter->key, ATTR_ID)) { + id = attr_iter->val; + } + if(!strcmp(attr_iter->key, ATTR_TYPE)) { + type = attr_iter->val; + } + attr_iter = Q_Next(&el->attrs); + } + + if(id) { + XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact); + } + + if(!strcmp(el->name, ATTR_SCALAR)) { + if(!type || !strcmp(type, ATTR_STRING)) { + XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len); + } + else if(!strcmp(type, ATTR_INT)) { + XMLRPC_SetValueInt(xCurrent, atoi(el->text.str)); + } + else if(!strcmp(type, ATTR_BOOLEAN)) { + XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str)); + } + else if(!strcmp(type, ATTR_DOUBLE)) { + XMLRPC_SetValueDouble(xCurrent, atof(el->text.str)); + } + else if(!strcmp(type, ATTR_DATETIME)) { + XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str); + } + else if(!strcmp(type, ATTR_BASE64)) { + struct buffer_st buf; + base64_decode(&buf, el->text.str, el->text.len); + XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset); + buffer_delete(&buf); + } + } + else if(!strcmp(el->name, ATTR_VECTOR)) { + xml_element* iter = (xml_element*)Q_Head(&el->children); + + if(!type || !strcmp(type, ATTR_MIXED)) { + XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed); + } + else if(!strcmp(type, ATTR_ARRAY)) { + XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array); + } + else if(!strcmp(type, ATTR_STRUCT)) { + XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct); + } + while( iter ) { + XMLRPC_VALUE xNext = XMLRPC_CreateValueEmpty(); + xml_element_to_DANDARPC_REQUEST_worker(request, xNext, iter); + XMLRPC_AddValueToVector(xCurrent, xNext); + iter = (xml_element*)Q_Next(&el->children); + } + } + else { + xml_element* iter = (xml_element*)Q_Head(&el->children); + while( iter ) { + xml_element_to_DANDARPC_REQUEST_worker(request, xCurrent, iter); + iter = (xml_element*)Q_Next(&el->children); + } + + if(!strcmp(el->name, ELEM_METHODCALL)) { + if(request) { + XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); + } + } + else if(!strcmp(el->name, ELEM_METHODRESPONSE)) { + if(request) { + XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); + } + } + else if(!strcmp(el->name, ELEM_METHODNAME)) { + if(request) { + XMLRPC_RequestSetMethodName(request, el->text.str); + } + } + } + } + return xCurrent; +} + +XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el) +{ + return xml_element_to_DANDARPC_REQUEST_worker(NULL, NULL, el); +} + +XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el) +{ + if(request) { + return XMLRPC_RequestSetData(request, xml_element_to_DANDARPC_REQUEST_worker(request, NULL, el)); + } + return NULL; +} + +xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) { +#define BUF_SIZE 512 + xml_element* root = NULL; + if(node) { + char buf[BUF_SIZE]; + const char* id = XMLRPC_GetValueID(node); + XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); + XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request); + int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space); + xml_element* elem_val = xml_elem_new(); + const char* pAttrType = NULL; + + xml_element_attr* attr_type = bNoAddType ? NULL : malloc(sizeof(xml_element_attr)); + + if(attr_type) { + attr_type->key = strdup(ATTR_TYPE); + attr_type->val = 0; + Q_PushTail(&elem_val->attrs, attr_type); + } + + elem_val->name = (type == xmlrpc_vector) ? strdup(ATTR_VECTOR) : strdup(ATTR_SCALAR); + + if(id && *id) { + xml_element_attr* attr_id = malloc(sizeof(xml_element_attr)); + if(attr_id) { + attr_id->key = strdup(ATTR_ID); + attr_id->val = strdup(id); + Q_PushTail(&elem_val->attrs, attr_id); + } + } + + switch(type) { + case xmlrpc_string: + pAttrType = ATTR_STRING; + simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); + break; + case xmlrpc_int: + pAttrType = ATTR_INT; + snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); + simplestring_add(&elem_val->text, buf); + break; + case xmlrpc_boolean: + pAttrType = ATTR_BOOLEAN; + snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); + simplestring_add(&elem_val->text, buf); + break; + case xmlrpc_double: + pAttrType = ATTR_DOUBLE; + snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); + simplestring_add(&elem_val->text, buf); + break; + case xmlrpc_datetime: + pAttrType = ATTR_DATETIME; + simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); + break; + case xmlrpc_base64: + { + struct buffer_st buf; + pAttrType = ATTR_BASE64; + base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); + simplestring_addn(&elem_val->text, buf.data, buf.offset ); + buffer_delete(&buf); + } + break; + case xmlrpc_vector: + { + XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); + XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); + + switch(my_type) { + case xmlrpc_vector_array: + pAttrType = ATTR_ARRAY; + break; + case xmlrpc_vector_mixed: + pAttrType = ATTR_MIXED; + break; + case xmlrpc_vector_struct: + pAttrType = ATTR_STRUCT; + break; + default: + break; + } + + /* recurse through sub-elements */ + while( xIter ) { + xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter); + if(next_el) { + Q_PushTail(&elem_val->children, next_el); + } + xIter = XMLRPC_VectorNext(node); + } + } + break; + default: + break; + } + if(pAttrType && attr_type && !bNoAddType) { + attr_type->val = strdup(pAttrType); + } + root = elem_val; + } + return root; +} + +xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node) { + return DANDARPC_to_xml_element_worker(NULL, node); +} + +xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { + xml_element* wrapper = NULL; + xml_element* root = NULL; + if(request) { + XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); + const char* pStr = NULL; + xml_element_attr* version = malloc(sizeof(xml_element_attr)); + version->key = strdup(ATTR_VERSION); + version->val = strdup(VAL_VERSION_0_9); + + wrapper = xml_elem_new(); + + if(request_type == xmlrpc_request_response) { + pStr = ELEM_METHODRESPONSE; + } + else if(request_type == xmlrpc_request_call) { + pStr = ELEM_METHODCALL; + } + if(pStr) { + wrapper->name = strdup(pStr); + } + + root = xml_elem_new(); + root->name = strdup(ELEM_ROOT); + Q_PushTail(&root->attrs, version); + Q_PushTail(&root->children, wrapper); + + pStr = XMLRPC_RequestGetMethodName(request); + + if(pStr) { + xml_element* method = xml_elem_new(); + method->name = strdup(ELEM_METHODNAME); + simplestring_add(&method->text, pStr); + Q_PushTail(&wrapper->children, method); + } + Q_PushTail(&wrapper->children, + DANDARPC_to_xml_element_worker(request, XMLRPC_RequestGetData(request))); + } + return root; +} +