Patch from Scott McKellar:
[Evergreen.git] / Open-ILS / src / apachemods / json_xml.c
1 #include "json_xml.h"
2 #include "fieldmapper_lookup.h"
3
4 static void _rest_xml_output(growing_buffer*, const jsonObject*, char*, int, int);
5 static char* _escape_xml (const char*);
6
7 char* json_string_to_xml(char* content) {
8         jsonObject * obj;
9         growing_buffer * res_xml;
10         int i;
11
12         obj = json_parse_string( content );
13
14         if (!obj)
15                 return NULL;
16         
17         res_xml = buffer_init(1024);
18         buffer_add(res_xml, "<response>");
19
20         if(obj->type == JSON_ARRAY ) {
21                 for( i = 0; i!= obj->size; i++ ) {
22                         _rest_xml_output(res_xml, jsonObjectGetIndex(obj,i), NULL, 0,0);
23                 }
24         } else {
25                 _rest_xml_output(res_xml, obj, NULL, 0,0);
26         }
27
28         buffer_add(res_xml, "</response>");
29
30         jsonObjectFree(obj);
31         return buffer_release(res_xml);
32 }
33
34 char* _escape_xml (const char* text) {
35         growing_buffer* b = buffer_init(256);
36         int len = strlen(text);
37         int i;
38         for (i = 0; i < len; i++) {
39                 if (text[i] == '&')
40                         buffer_add(b,"&amp;");
41                 else if (text[i] == '<')
42                         buffer_add(b,"&lt;");
43                 else if (text[i] == '>')
44                         buffer_add(b,"&gt;");
45                 else
46                         buffer_add_char(b,text[i]);
47         }
48         return buffer_release(b);
49 }
50
51 static void _rest_xml_output(growing_buffer* buf, const jsonObject* obj,
52                 char * obj_class, int arr_index, int notag) {
53         char * tag;
54         int i;
55         
56         if(!obj) return;
57
58         if (obj->classname)
59                 notag = 1;
60
61         if(isFieldmapper(obj_class)) {
62                 tag = fm_pton(obj_class,arr_index);
63         } else if(obj_class) {
64                 tag = strdup(obj_class);
65         } else {
66                 tag = strdup("datum");
67         }
68
69         
70    /* add class hints if we have a class name */
71    if(obj->classname) {
72         if(obj->type == JSON_NULL) {
73                         buffer_fadd(buf,"<%s><Object class_hint=\"%s\"/></%s>", tag, obj->classname, tag);
74                         free(tag);
75                         return;
76                 } else {
77                         buffer_fadd(buf,"<%s><Object class_hint=\"%s\">", tag, obj->classname);
78                 }
79         }
80
81
82         /* now add the data */
83         if(obj->type == JSON_NULL) {
84                 if (!notag)
85                         buffer_fadd(buf, "<%s/>",tag);
86         } else if(obj->type == JSON_BOOL && obj->value.b) {
87                 if (notag)
88                         buffer_add(buf, "true");
89                 else
90                         buffer_fadd(buf, "<%s>true</%s>",tag,tag);
91                 
92         } else if(obj->type == JSON_BOOL && ! obj->value.b) {
93                 if (notag)
94                         buffer_add(buf, "false");
95                 else
96                         buffer_fadd(buf, "<%s>false</%s>",tag,tag);
97
98         } else if (obj->type == JSON_STRING) {
99                 if (notag) {
100                         char * t = _escape_xml(jsonObjectGetString(obj));
101                         buffer_add(buf,t);
102                         free(t);
103                 } else {
104                         char * t = _escape_xml(jsonObjectGetString(obj));
105                         buffer_fadd(buf,"<%s>%s</%s>",tag,t,tag);
106                         free(t);
107                 }
108
109         } else if(obj->type == JSON_NUMBER) {
110                 double x = jsonObjectGetNumber(obj);
111                 if (notag) {
112                         if (x == (int)x)
113                                 buffer_fadd(buf,"%d",(int)x);
114                         else
115                                 buffer_fadd(buf,"%f",x);
116                 } else {
117                         if (x == (int)x)
118                                 buffer_fadd(buf,"<%s>%d</%s>",tag, (int)x,tag);
119                         else
120                                 buffer_fadd(buf,"<%s>%f</%s>",tag, x,tag);
121                 }
122
123         } else if (obj->type == JSON_ARRAY) {
124                 if (!notag) {
125                         if(!isFieldmapper(obj_class))
126                                 buffer_add(buf,"<array>");
127                         else
128                                 buffer_fadd(buf,"<%s>",tag);
129                 }
130
131                 for( i = 0; i!= obj->size; i++ ) {
132                         _rest_xml_output(buf, jsonObjectGetIndex(obj,i), obj->classname, i,0);
133                 }
134
135                 if (!notag) {
136                         if(!isFieldmapper(obj_class))
137                                 buffer_add(buf,"</array>");
138                         else
139                                 buffer_fadd(buf,"</%s>",tag);
140                 }
141
142         } else if (obj->type == JSON_HASH) {
143
144                 if (!notag) {
145                         if(!obj_class)
146                                 buffer_add(buf,"<hash>");
147                         else
148                                 buffer_fadd(buf,"<%s>",tag);
149                 }
150
151                 jsonObjectIterator* itr = jsonNewObjectIterator(obj);
152                 jsonObjectNode* tmp;
153                 while( (tmp = jsonObjectIteratorNext(itr)) ) {
154                         if (notag) {
155                                 buffer_fadd(buf,"<%s>",tmp->key);
156                         } else {
157                                 buffer_add(buf,"<pair>");
158                                 buffer_fadd(buf,"<key>%s</key><value>",tmp->key);
159                         }
160
161                         _rest_xml_output(buf, tmp->item, NULL,0,notag);
162
163                         if (notag) {
164                                 buffer_fadd(buf,"</%s>",tmp->key);
165                         } else {
166                                 buffer_add(buf,"</value></pair>");
167                         }
168                 }
169                 jsonObjectIteratorFree(itr);
170
171                 if (!notag) {
172                         if(!obj_class)
173                                 buffer_add(buf,"</hash>");
174                         else
175                                 buffer_fadd(buf,"</%s>",tag);
176                 }
177
178         }
179
180         if (obj->classname)
181                 buffer_fadd(buf,"</Object></%s>",tag);
182
183         free(tag);
184 }
185