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>