Annotation of embedaddon/php/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c, revision 1.1.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>