fixed a problem in utils where I was using a va_list after calling va_end on the...
[OpenSRF.git] / src / gateway / fieldmapper-c-xml-out.pl
1 #!/usr/bin/perl
2 use strict;
3 use lib '../perlmods/';
4
5 my $map = {};
6 eval "
7         use lib '../../../Open-ILS/src/perlmods/';
8         use OpenILS::Utils::Fieldmapper;  
9 ";
10 $map = $Fieldmapper::fieldmap unless ($@);
11
12
13 if(!$ARGV[1]) {
14         print "usage: $0 <header_file> <source_file>\n";
15         exit;
16 }
17
18 warn "Generating fieldmapper-c code...\n";
19
20
21 print $ARGV[0] . "\n";
22 print $ARGV[1] . "\n";
23
24 open(HEADER, ">$ARGV[0]");
25 open(SOURCE, ">$ARGV[1]");
26
27 warn "Generating fieldmapper-c code...\n";
28
29 print HEADER <<C;
30 #ifndef _TOXML_H_
31 #define _TOXML_H_
32
33 char* json_string_to_xml(char*);
34
35 #endif
36 C
37
38 print SOURCE <<C;
39
40 #include <string.h>
41
42 /* and the JSON parser, so we can read the response we're XMLizing */
43 #include <string.h>
44 #include <stdio.h>
45 #include "objson/object.h"
46 #include "objson/json_parser.h"
47 #include "utils.h"
48
49 char* json_string_to_xml(char*);
50 void _rest_xml_output(growing_buffer*, object*, char*, int, int);
51 char * _lookup_fm_field(char*,int);
52 char* _escape_xml (char*);
53
54 char* json_string_to_xml(char* content) {
55         object * obj;
56         growing_buffer * res_xml;
57         char * output;
58         int i;
59
60         obj = json_parse_string( content );
61         res_xml = buffer_init(1024);
62
63         if (!obj)
64                 return NULL;
65         
66         buffer_add(res_xml, "<response>");
67
68         if(obj->is_array) {
69                 for( i = 0; i!= obj->size; i++ ) {
70                         _rest_xml_output(res_xml, obj->get_index(obj,i), NULL, 0,0);
71                 }
72         } else {
73                 _rest_xml_output(res_xml, obj, NULL, 0,0);
74         }
75
76         buffer_add(res_xml, "</response>");
77
78         output = buffer_data(res_xml);
79         buffer_free(res_xml);
80         free_object(obj);
81
82         return output;
83 }
84
85 char* _escape_xml (char* text) {
86         char* out;
87         growing_buffer* b = buffer_init(256);
88         int len = strlen(text);
89         int i;
90         for (i = 0; i < len; i++) {
91                 if (text[i] == '&')
92                         buffer_add(b,"&amp;");
93                 else if (text[i] == '<')
94                         buffer_add(b,"&lt;");
95                 else if (text[i] == '>')
96                         buffer_add(b,"&gt;");
97                 else
98                         buffer_add_char(b,text[i]);
99         }
100         out = buffer_data(b);
101         buffer_free(b);
102         return out;
103 }
104
105 void _rest_xml_output(growing_buffer* buf, object* obj, char * fm_class, int fm_index, int notag) {
106         char * tag;
107         int i;
108         
109         if(!obj) return;
110
111         if (obj->classname)
112                 notag = 1;
113
114         if(fm_class) {
115                 tag = _lookup_fm_field(fm_class,fm_index);
116         } else {
117                 tag = strdup("datum");
118         }
119
120         
121    /* add class hints if we have a class name */
122    if(obj->classname) {
123         if(obj->is_null) {
124                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\"/></%s>", tag, obj->classname, tag);
125                         return;
126                 } else {
127                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\">", tag, obj->classname);
128                 }
129         }
130
131
132         /* now add the data */
133         if(obj->is_null) {
134                 if (!notag)
135                         buffer_fadd(buf, "<%s/>",tag);
136         } else if(obj->is_bool && obj->bool_value) {
137                 if (notag)
138                         buffer_add(buf, "true");
139                 else
140                         buffer_fadd(buf, "<%s>true</%s>",tag,tag);
141                 
142         } else if(obj->is_bool && ! obj->bool_value) {
143                 if (notag)
144                         buffer_add(buf, "false");
145                 else
146                         buffer_fadd(buf, "<%s>false</%s>",tag,tag);
147
148         } else if (obj->is_string) {
149                 if (notag) {
150                         char * t = _escape_xml(obj->string_data);
151                         buffer_add(buf,t);
152                         free(t);
153                 } else {
154                         char * t = _escape_xml(obj->string_data);
155                         buffer_fadd(buf,"<%s>%s</%s>",tag,t,tag);
156                         free(t);
157                 }
158
159         } else if(obj->is_number) {
160
161                 if (notag)
162                         buffer_fadd(buf,"%ld",obj->num_value);
163                 else
164                         buffer_fadd(buf,"<%s>%ld</%s>",tag,obj->num_value,tag);
165
166
167         } else if(obj->is_double) {
168                 if (notag)
169                         buffer_fadd(buf,"%lf",tag,obj->double_value,tag);
170                 else
171                         buffer_fadd(buf,"<%s>%lf</%s>",tag,obj->double_value,tag);
172
173
174         } else if (obj->is_array) {
175                 if (!notag) {
176                         if(!fm_class)
177                                 buffer_add(buf,"<array>");
178                         else
179                                 buffer_fadd(buf,"<%s>",tag);
180                 }
181
182                 for( i = 0; i!= obj->size; i++ ) {
183                         _rest_xml_output(buf, obj->get_index(obj,i), obj->classname, i,0);
184                 }
185
186                 if (!notag) {
187                         if(!fm_class)
188                                 buffer_add(buf,"</array>");
189                         else
190                                 buffer_fadd(buf,"</%s>",tag);
191                 }
192
193         } else if (obj->is_hash) {
194
195                 if (!notag) {
196                         if(!fm_class)
197                                 buffer_add(buf,"<hash>");
198                         else
199                                 buffer_fadd(buf,"<%s>",tag);
200                 }
201
202                 object_iterator* itr = new_iterator(obj);
203                 object_node* tmp;
204                 while( (tmp = itr->next(itr)) ) {
205                         if (notag) {
206                                 buffer_fadd(buf,"<%s>",tmp->key);
207                         } else {
208                                 buffer_add(buf,"<pair>");
209                                 buffer_fadd(buf,"<key>%s</key><value>",tmp->key);
210                         }
211
212                         _rest_xml_output(buf, tmp->item, NULL,0,notag);
213
214                         if (notag) {
215                                 buffer_fadd(buf,"</%s>",tmp->key);
216                         } else {
217                                 buffer_add(buf,"</value></pair>");
218                         }
219                 }
220                 free_iterator(itr);
221
222                 if (!notag) {
223                         if(!fm_class)
224                                 buffer_add(buf,"</hash>");
225                         else
226                                 buffer_fadd(buf,"</%s>",tag);
227                 }
228
229         }
230
231         if (obj->classname)
232                 buffer_fadd(buf,"</Object></%s>",tag);
233
234         free(tag);
235 }
236
237 char * _lookup_fm_field(char * class, int pos) {
238
239 C
240
241 print SOURCE "  if (class == NULL) return NULL;";
242
243 for my $object (keys %$map) {
244
245         my $short_name                          = $map->{$object}->{hint};
246
247         print SOURCE <<"        C";
248
249         else if (!strcmp(class, "$short_name")) {
250                 switch (pos) {
251         C
252
253         for my $field (keys %{$map->{$object}->{fields}}) {
254                 my $position = $map->{$object}->{fields}->{$field}->{position};
255
256                 print SOURCE <<"                C";
257                         case $position:
258                                 return strdup("$field");
259                                 break;
260                 C
261         }
262         print SOURCE "          }\n";
263         print SOURCE "  }\n";
264 }
265 print SOURCE '  return strdup("datum");'."\n";
266 print SOURCE "}\n";
267
268 close HEADER;
269 close SOURCE;
270
271 warn  "done\n";
272