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>