Annotation of embedaddon/php/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c, revision 1.1
1.1 ! misho 1: /*
! 2: This file is part of libXMLRPC - a C library for xml-encoded function calls.
! 3:
! 4: Author: Dan Libby (dan@libby.com)
! 5: Epinions.com may be contacted at feedback@epinions-inc.com
! 6: */
! 7:
! 8: /*
! 9: Copyright 2000 Epinions, Inc.
! 10:
! 11: Subject to the following 3 conditions, Epinions, Inc. permits you, free
! 12: of charge, to (a) use, copy, distribute, modify, perform and display this
! 13: software and associated documentation files (the "Software"), and (b)
! 14: permit others to whom the Software is furnished to do so as well.
! 15:
! 16: 1) The above copyright notice and this permission notice shall be included
! 17: without modification in all copies or substantial portions of the
! 18: Software.
! 19:
! 20: 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
! 21: ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
! 22: IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
! 23: PURPOSE OR NONINFRINGEMENT.
! 24:
! 25: 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
! 26: SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
! 27: OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
! 28: NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
! 29: DAMAGES.
! 30:
! 31: */
! 32:
! 33: #ifdef _WIN32
! 34: #include "xmlrpc_win32.h"
! 35: #endif
! 36: #include <string.h>
! 37: #include <stdlib.h>
! 38: #include "xml_to_dandarpc.h"
! 39: #include "base64.h"
! 40:
! 41: /* list of tokens used in vocab */
! 42: #define ELEM_METHODCALL "methodCall"
! 43: #define ELEM_METHODNAME "methodName"
! 44: #define ELEM_METHODRESPONSE "methodResponse"
! 45: #define ELEM_ROOT "simpleRPC"
! 46:
! 47: #define ATTR_ARRAY "array"
! 48: #define ATTR_BASE64 "base64"
! 49: #define ATTR_BOOLEAN "boolean"
! 50: #define ATTR_DATETIME "dateTime.iso8601"
! 51: #define ATTR_DOUBLE "double"
! 52: #define ATTR_ID "id"
! 53: #define ATTR_INT "int"
! 54: #define ATTR_MIXED "mixed"
! 55: #define ATTR_SCALAR "scalar"
! 56: #define ATTR_STRING "string"
! 57: #define ATTR_STRUCT "struct"
! 58: #define ATTR_TYPE "type"
! 59: #define ATTR_VECTOR "vector"
! 60: #define ATTR_VERSION "version"
! 61:
! 62: #define VAL_VERSION_0_9 "0.9"
! 63:
! 64:
! 65: XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xCurrent, xml_element* el) {
! 66: if(!xCurrent) {
! 67: xCurrent = XMLRPC_CreateValueEmpty();
! 68: }
! 69:
! 70: if(el->name) {
! 71: const char* id = NULL;
! 72: const char* type = NULL;
! 73: xml_element_attr* attr_iter = Q_Head(&el->attrs);
! 74:
! 75: while(attr_iter) {
! 76: if(!strcmp(attr_iter->key, ATTR_ID)) {
! 77: id = attr_iter->val;
! 78: }
! 79: if(!strcmp(attr_iter->key, ATTR_TYPE)) {
! 80: type = attr_iter->val;
! 81: }
! 82: attr_iter = Q_Next(&el->attrs);
! 83: }
! 84:
! 85: if(id) {
! 86: XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact);
! 87: }
! 88:
! 89: if(!strcmp(el->name, ATTR_SCALAR)) {
! 90: if(!type || !strcmp(type, ATTR_STRING)) {
! 91: XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len);
! 92: }
! 93: else if(!strcmp(type, ATTR_INT)) {
! 94: XMLRPC_SetValueInt(xCurrent, atoi(el->text.str));
! 95: }
! 96: else if(!strcmp(type, ATTR_BOOLEAN)) {
! 97: XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str));
! 98: }
! 99: else if(!strcmp(type, ATTR_DOUBLE)) {
! 100: XMLRPC_SetValueDouble(xCurrent, atof(el->text.str));
! 101: }
! 102: else if(!strcmp(type, ATTR_DATETIME)) {
! 103: XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str);
! 104: }
! 105: else if(!strcmp(type, ATTR_BASE64)) {
! 106: struct buffer_st buf;
! 107: base64_decode_xmlrpc(&buf, el->text.str, el->text.len);
! 108: XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset);
! 109: buffer_delete(&buf);
! 110: }
! 111: }
! 112: else if(!strcmp(el->name, ATTR_VECTOR)) {
! 113: xml_element* iter = (xml_element*)Q_Head(&el->children);
! 114:
! 115: if(!type || !strcmp(type, ATTR_MIXED)) {
! 116: XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed);
! 117: }
! 118: else if(!strcmp(type, ATTR_ARRAY)) {
! 119: XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array);
! 120: }
! 121: else if(!strcmp(type, ATTR_STRUCT)) {
! 122: XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct);
! 123: }
! 124: while( iter ) {
! 125: XMLRPC_VALUE xNext = XMLRPC_CreateValueEmpty();
! 126: xml_element_to_DANDARPC_REQUEST_worker(request, xNext, iter);
! 127: XMLRPC_AddValueToVector(xCurrent, xNext);
! 128: iter = (xml_element*)Q_Next(&el->children);
! 129: }
! 130: }
! 131: else {
! 132: xml_element* iter = (xml_element*)Q_Head(&el->children);
! 133: while( iter ) {
! 134: xml_element_to_DANDARPC_REQUEST_worker(request, xCurrent, iter);
! 135: iter = (xml_element*)Q_Next(&el->children);
! 136: }
! 137:
! 138: if(!strcmp(el->name, ELEM_METHODCALL)) {
! 139: if(request) {
! 140: XMLRPC_RequestSetRequestType(request, xmlrpc_request_call);
! 141: }
! 142: }
! 143: else if(!strcmp(el->name, ELEM_METHODRESPONSE)) {
! 144: if(request) {
! 145: XMLRPC_RequestSetRequestType(request, xmlrpc_request_response);
! 146: }
! 147: }
! 148: else if(!strcmp(el->name, ELEM_METHODNAME)) {
! 149: if(request) {
! 150: XMLRPC_RequestSetMethodName(request, el->text.str);
! 151: }
! 152: }
! 153: }
! 154: }
! 155: return xCurrent;
! 156: }
! 157:
! 158: XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el)
! 159: {
! 160: return xml_element_to_DANDARPC_REQUEST_worker(NULL, NULL, el);
! 161: }
! 162:
! 163: XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el)
! 164: {
! 165: if(request) {
! 166: return XMLRPC_RequestSetData(request, xml_element_to_DANDARPC_REQUEST_worker(request, NULL, el));
! 167: }
! 168: return NULL;
! 169: }
! 170:
! 171: xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) {
! 172: #define BUF_SIZE 512
! 173: xml_element* root = NULL;
! 174: if(node) {
! 175: char buf[BUF_SIZE];
! 176: const char* id = XMLRPC_GetValueID(node);
! 177: XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node);
! 178: XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request);
! 179: int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space);
! 180: xml_element* elem_val = xml_elem_new();
! 181: const char* pAttrType = NULL;
! 182:
! 183: xml_element_attr* attr_type = bNoAddType ? NULL : malloc(sizeof(xml_element_attr));
! 184:
! 185: if(attr_type) {
! 186: attr_type->key = strdup(ATTR_TYPE);
! 187: attr_type->val = 0;
! 188: Q_PushTail(&elem_val->attrs, attr_type);
! 189: }
! 190:
! 191: elem_val->name = (type == xmlrpc_vector) ? strdup(ATTR_VECTOR) : strdup(ATTR_SCALAR);
! 192:
! 193: if(id && *id) {
! 194: xml_element_attr* attr_id = malloc(sizeof(xml_element_attr));
! 195: if(attr_id) {
! 196: attr_id->key = strdup(ATTR_ID);
! 197: attr_id->val = strdup(id);
! 198: Q_PushTail(&elem_val->attrs, attr_id);
! 199: }
! 200: }
! 201:
! 202: switch(type) {
! 203: case xmlrpc_string:
! 204: pAttrType = ATTR_STRING;
! 205: simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node));
! 206: break;
! 207: case xmlrpc_int:
! 208: pAttrType = ATTR_INT;
! 209: snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node));
! 210: simplestring_add(&elem_val->text, buf);
! 211: break;
! 212: case xmlrpc_boolean:
! 213: pAttrType = ATTR_BOOLEAN;
! 214: snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node));
! 215: simplestring_add(&elem_val->text, buf);
! 216: break;
! 217: case xmlrpc_double:
! 218: pAttrType = ATTR_DOUBLE;
! 219: snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node));
! 220: simplestring_add(&elem_val->text, buf);
! 221: break;
! 222: case xmlrpc_datetime:
! 223: pAttrType = ATTR_DATETIME;
! 224: simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node));
! 225: break;
! 226: case xmlrpc_base64:
! 227: {
! 228: struct buffer_st buf;
! 229: pAttrType = ATTR_BASE64;
! 230: base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node));
! 231: simplestring_addn(&elem_val->text, buf.data, buf.offset );
! 232: buffer_delete(&buf);
! 233: }
! 234: break;
! 235: case xmlrpc_vector:
! 236: {
! 237: XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node);
! 238: XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node);
! 239:
! 240: switch(my_type) {
! 241: case xmlrpc_vector_array:
! 242: pAttrType = ATTR_ARRAY;
! 243: break;
! 244: case xmlrpc_vector_mixed:
! 245: pAttrType = ATTR_MIXED;
! 246: break;
! 247: case xmlrpc_vector_struct:
! 248: pAttrType = ATTR_STRUCT;
! 249: break;
! 250: default:
! 251: break;
! 252: }
! 253:
! 254: /* recurse through sub-elements */
! 255: while( xIter ) {
! 256: xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter);
! 257: if(next_el) {
! 258: Q_PushTail(&elem_val->children, next_el);
! 259: }
! 260: xIter = XMLRPC_VectorNext(node);
! 261: }
! 262: }
! 263: break;
! 264: default:
! 265: break;
! 266: }
! 267: if(pAttrType && attr_type && !bNoAddType) {
! 268: attr_type->val = strdup(pAttrType);
! 269: }
! 270: root = elem_val;
! 271: }
! 272: return root;
! 273: }
! 274:
! 275: xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node) {
! 276: return DANDARPC_to_xml_element_worker(NULL, node);
! 277: }
! 278:
! 279: xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) {
! 280: xml_element* wrapper = NULL;
! 281: xml_element* root = NULL;
! 282: if(request) {
! 283: XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request);
! 284: const char* pStr = NULL;
! 285: xml_element_attr* version = malloc(sizeof(xml_element_attr));
! 286: version->key = strdup(ATTR_VERSION);
! 287: version->val = strdup(VAL_VERSION_0_9);
! 288:
! 289: wrapper = xml_elem_new();
! 290:
! 291: if(request_type == xmlrpc_request_response) {
! 292: pStr = ELEM_METHODRESPONSE;
! 293: }
! 294: else if(request_type == xmlrpc_request_call) {
! 295: pStr = ELEM_METHODCALL;
! 296: }
! 297: if(pStr) {
! 298: wrapper->name = strdup(pStr);
! 299: }
! 300:
! 301: root = xml_elem_new();
! 302: root->name = strdup(ELEM_ROOT);
! 303: Q_PushTail(&root->attrs, version);
! 304: Q_PushTail(&root->children, wrapper);
! 305:
! 306: pStr = XMLRPC_RequestGetMethodName(request);
! 307:
! 308: if(pStr) {
! 309: xml_element* method = xml_elem_new();
! 310: method->name = strdup(ELEM_METHODNAME);
! 311: simplestring_add(&method->text, pStr);
! 312: Q_PushTail(&wrapper->children, method);
! 313: }
! 314: Q_PushTail(&wrapper->children,
! 315: DANDARPC_to_xml_element_worker(request, XMLRPC_RequestGetData(request)));
! 316: }
! 317: return root;
! 318: }
! 319:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>