initial load of upstream version 1.06.32
[xmlrpc-c] / tools / xmlrpc / dumpvalue.c
1 /* dumpvalue() service, which prints to Standard Output the value of
2    an xmlrpc_value.
3
4    We've put this in a separate module in hopes that it eventually can be
5    used for debugging purposes in other places.
6 */
7
8 #define _GNU_SOURCE
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13
14 #include "config.h"  /* information about this build environment */
15 #include "casprintf.h"
16 #include "mallocvar.h"
17
18 #include "xmlrpc-c/base.h"
19
20 #include "dumpvalue.h"
21
22
23
24 static void
25 dumpInt(const char *   const prefix,
26         xmlrpc_value * const valueP) {
27
28     xmlrpc_env env;
29     xmlrpc_int value;
30     
31     xmlrpc_env_init(&env);
32
33     xmlrpc_parse_value(&env, valueP, "i", &value);
34     
35     if (env.fault_occurred)
36         printf("Unable to parse integer xmlrpc_value %lx.  %s\n",
37                (unsigned long)valueP, env.fault_string);
38     else
39         printf("%sInteger: %d\n", prefix, value);
40
41     xmlrpc_env_clean(&env);
42 }
43
44
45
46 static void
47 dumpBool(const char *   const prefix,
48          xmlrpc_value * const valueP) {
49
50     xmlrpc_env env;
51     xmlrpc_bool value;
52     
53     xmlrpc_env_init(&env);
54
55     xmlrpc_parse_value(&env, valueP, "b", &value);
56     
57     if (env.fault_occurred)
58         printf("Unable to parse boolean xmlrpc_value %lx.  %s\n",
59                (unsigned long)valueP, env.fault_string);
60     else
61         printf("%sBoolean: %s\n", prefix, value ? "TRUE" : "FALSE");
62
63     xmlrpc_env_clean(&env);
64 }
65
66
67
68
69 static void
70 dumpDouble(const char *   const prefix,
71            xmlrpc_value * const valueP) {
72
73     xmlrpc_env env;
74     xmlrpc_double value;
75     
76     xmlrpc_env_init(&env);
77
78     xmlrpc_parse_value(&env, valueP, "d", &value);
79     
80     if (env.fault_occurred)
81         printf("Unable to parse floating point number xmlrpc_value %lx.  %s\n",
82                (unsigned long)valueP, env.fault_string);
83     else
84         printf("%sFloating Point: %f\n", prefix, value);
85
86     xmlrpc_env_clean(&env);
87 }
88
89
90
91 static void
92 dumpDatetime(const char *   const prefix,
93              xmlrpc_value * const valueP) {
94
95     printf("%sDon't know how to print datetime value %lx.\n", 
96            prefix, (unsigned long) valueP);
97 }
98
99
100
101 static void
102 dumpString(const char *   const prefix,
103            xmlrpc_value * const valueP) {
104
105     xmlrpc_env env;
106     const char * value;
107     
108     xmlrpc_env_init(&env);
109
110     xmlrpc_parse_value(&env, valueP, "s", &value);
111     
112     if (env.fault_occurred)
113         printf("Unable to parse string xmlrpc_value %lx.  %s\n",
114                (unsigned long)valueP, env.fault_string);
115     else
116         printf("%sString: '%s'\n", prefix, value);
117
118     xmlrpc_env_clean(&env);
119 }
120
121
122
123 static void
124 dumpBase64(const char *   const prefix,
125            xmlrpc_value * const valueP) {
126
127     xmlrpc_env env;
128     const unsigned char * value;
129     size_t length;
130     
131     xmlrpc_env_init(&env);
132
133     xmlrpc_parse_value(&env, valueP, "6", &value, &length);
134     
135     if (env.fault_occurred)
136         printf("Unable to parse base64 bit string xmlrpc_value %lx.  %s\n",
137                (unsigned long)valueP, env.fault_string);
138     else {
139         unsigned int i;
140
141         printf("%sBit string: ", prefix);
142         for (i = 0; i < length; ++i)
143             printf("%02x", value[i]);
144     }
145     xmlrpc_env_clean(&env);
146 }
147
148
149
150 static void
151 dumpArray(const char *   const prefix,
152           xmlrpc_value * const arrayP) {
153
154     xmlrpc_env env;
155     unsigned int arraySize;
156
157     xmlrpc_env_init(&env);
158
159     XMLRPC_ASSERT_ARRAY_OK(arrayP);
160
161     arraySize = xmlrpc_array_size(&env, arrayP);
162     if (env.fault_occurred)
163         printf("Unable to get array size.  %s\n", env.fault_string);
164     else {
165         int const spaceCount = strlen(prefix);
166
167         unsigned int i;
168         const char * blankPrefix;
169
170         printf("%sArray of %u items:\n", prefix, arraySize);
171
172         casprintf(&blankPrefix, "%*s", spaceCount, "");
173
174         for (i = 0; i < arraySize; ++i) {
175             xmlrpc_value * valueP;
176
177             xmlrpc_array_read_item(&env, arrayP, i, &valueP);
178
179             if (env.fault_occurred)
180                 printf("Unable to get array item %u\n", i);
181             else {
182                 const char * prefix2;
183
184                 casprintf(&prefix2, "%s  Index %2u ", blankPrefix, i);
185                 dumpValue(prefix2, valueP);
186                 strfree(prefix2);
187
188                 xmlrpc_DECREF(valueP);
189             }
190         }
191         strfree(blankPrefix);
192     }
193     xmlrpc_env_clean(&env);
194 }
195
196
197
198 static void
199 dumpStructMember(const char *   const prefix,
200                  xmlrpc_value * const structP,
201                  unsigned int   const index) {
202
203     xmlrpc_env env;
204
205     xmlrpc_value * keyP;
206     xmlrpc_value * valueP;
207     
208     xmlrpc_env_init(&env);
209
210     xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP);
211
212     if (env.fault_occurred)
213         printf("Unable to get struct member %u\n", index);
214     else {
215         int const blankCount = strlen(prefix);
216         const char * prefix2;
217         const char * blankPrefix;
218
219         casprintf(&prefix2, "%s  Key:   ", prefix);
220         dumpValue(prefix2, keyP);
221         strfree(prefix2);
222
223         casprintf(&blankPrefix, "%*s", blankCount, "");
224         
225         casprintf(&prefix2, "%s  Value: ", blankPrefix);
226         dumpValue(prefix2, valueP);
227         strfree(prefix2);
228
229         strfree(blankPrefix);
230
231         xmlrpc_DECREF(keyP);
232         xmlrpc_DECREF(valueP);
233     }
234     xmlrpc_env_clean(&env);
235 }
236
237
238
239 static void
240 dumpStruct(const char *   const prefix,
241            xmlrpc_value * const structP) {
242
243     xmlrpc_env env;
244     unsigned int structSize;
245
246     xmlrpc_env_init(&env);
247
248     structSize = xmlrpc_struct_size(&env, structP);
249     if (env.fault_occurred)
250         printf("Unable to get struct size.  %s\n", env.fault_string);
251     else {
252         unsigned int i;
253
254         printf("%sStruct of %u members:\n", prefix, structSize);
255
256         for (i = 0; i < structSize; ++i) {
257             const char * prefix1;
258
259             if (i == 0)
260                 prefix1 = strdup(prefix);
261             else {
262                 int const blankCount = strlen(prefix);
263                 casprintf(&prefix1, "%*s", blankCount, "");
264             }            
265             dumpStructMember(prefix1, structP, i);
266
267             strfree(prefix1);
268         }
269     }
270     xmlrpc_env_clean(&env);
271 }
272
273
274
275 static void
276 dumpCPtr(const char *   const prefix,
277          xmlrpc_value * const valueP) {
278
279     xmlrpc_env env;
280     const char * value;
281
282     xmlrpc_env_init(&env);
283
284     xmlrpc_parse_value(&env, valueP, "p", &value);
285         
286     if (env.fault_occurred)
287         printf("Unable to parse C pointer xmlrpc_value %lx.  %s\n",
288                (unsigned long)valueP, env.fault_string);
289     else
290         printf("%sC pointer: '%p'\n", prefix, value);
291
292     xmlrpc_env_clean(&env);
293 }
294
295
296
297 static void
298 dumpNil(const char *   const prefix,
299         xmlrpc_value * const valueP) {
300
301     xmlrpc_env env;
302
303     xmlrpc_env_init(&env);
304
305     xmlrpc_parse_value(&env, valueP, "n");
306         
307     if (env.fault_occurred)
308         printf("Unable to parse nil value xmlrpc_value %lx.  %s\n",
309                (unsigned long)valueP, env.fault_string);
310     else
311         printf("%sNil\n", prefix);
312
313     xmlrpc_env_clean(&env);
314 }
315
316
317
318 static void
319 dumpUnknown(const char *   const prefix,
320             xmlrpc_value * const valueP) {
321
322     printf("%sDon't recognize value type %u of xmlrpc_value %lx.\n", 
323            prefix, xmlrpc_value_type(valueP), (unsigned long)valueP);
324     printf("%sCan't print it.\n", prefix);
325 }
326
327
328
329 void
330 dumpValue(const char *   const prefix,
331           xmlrpc_value * const valueP) {
332
333     switch (xmlrpc_value_type(valueP)) {
334     case XMLRPC_TYPE_INT:
335         dumpInt(prefix, valueP);
336         break;
337     case XMLRPC_TYPE_BOOL: 
338         dumpBool(prefix, valueP);
339         break;
340     case XMLRPC_TYPE_DOUBLE: 
341         dumpDouble(prefix, valueP);
342         break;
343     case XMLRPC_TYPE_DATETIME:
344         dumpDatetime(prefix, valueP);
345         break;
346     case XMLRPC_TYPE_STRING: 
347         dumpString(prefix, valueP);
348         break;
349     case XMLRPC_TYPE_BASE64:
350         dumpBase64(prefix, valueP);
351         break;
352     case XMLRPC_TYPE_ARRAY: 
353         dumpArray(prefix, valueP);
354         break;
355     case XMLRPC_TYPE_STRUCT:
356         dumpStruct(prefix, valueP);
357         break;
358     case XMLRPC_TYPE_C_PTR:
359         dumpCPtr(prefix, valueP);
360         break;
361     case XMLRPC_TYPE_NIL:
362         dumpNil(prefix, valueP);
363         break;
364     default:
365         dumpUnknown(prefix, valueP);
366     }
367 }