]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/gateway/fieldmapper-c-xml-out.pl
staving off memory leaks
[working/Evergreen.git] / OpenSRF / 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 "opensrf/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         for( i = 0; i!= obj->size; i++ ) {
69                 _rest_xml_output(res_xml, obj->get_index(obj,i), NULL, 0,0);
70         }
71
72         buffer_add(res_xml, "</response>");
73
74         output = buffer_data(res_xml);
75         buffer_free(res_xml);
76
77         return output;
78 }
79
80 char* _escape_xml (char* text) {
81         char* out;
82         growing_buffer* b = buffer_init(256);
83         int len = strlen(text);
84         int i;
85         for (i = 0; i < len; i++) {
86                 if (text[i] == '&')
87                         buffer_add(b,"&amp;");
88                 else if (text[i] == '<')
89                         buffer_add(b,"&lt;");
90                 else if (text[i] == '>')
91                         buffer_add(b,"&gt;");
92                 else
93                         buffer_add_char(b,text[i]);
94         }
95         out = buffer_data(b);
96         buffer_free(b);
97         fprintf(stderr," XXX Escaped string: %s\\n", out);
98         fflush(stderr);
99         return out;
100 }
101
102 void _rest_xml_output(growing_buffer* buf, object* obj, char * fm_class, int fm_index, int notag) {
103         char * tag;
104         int i;
105         
106         if (obj->classname)
107                 notag = 1;
108
109         if(fm_class) {
110                 tag = _lookup_fm_field(fm_class,fm_index);
111         } else {
112                 tag = strdup("datum");
113         }
114         
115         /* add class hints if we have a class name */
116         if(obj->classname) {
117                 if(obj->is_null) {
118                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\"/></%s>", tag, obj->classname, tag);
119                         return;
120                 } else {
121                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\">", tag, obj->classname);
122                 }
123         }
124
125         /* now add the data */
126         if(obj->is_null) {
127                 if (!notag)
128                         buffer_fadd(buf, "<%s/>",tag);
129         } else if(obj->is_bool && obj->bool_value) {
130                 if (notag)
131                         buffer_add(buf, "true");
132                 else
133                         buffer_fadd(buf, "<%s>true</%s>",tag,tag);
134                 
135         } else if(obj->is_bool && ! obj->bool_value) {
136                 if (notag)
137                         buffer_add(buf, "false");
138                 else
139                         buffer_fadd(buf, "<%s>false</%s>",tag,tag);
140
141         } else if (obj->is_string) {
142                 if (notag) {
143                         char * t = _escape_xml(obj->string_data);
144                         buffer_add(buf,t);
145                         free(t);
146                 } else {
147                         char * t = _escape_xml(obj->string_data);
148                         buffer_fadd(buf,"<%s>%s</%s>",tag,t,tag);
149                         free(t);
150                 }
151
152         } else if(obj->is_number) {
153                 if (notag)
154                         buffer_fadd(buf,"%ld",obj->num_value);
155                 else
156                         buffer_fadd(buf,"<%s>%ld</%s>",tag,obj->num_value,tag);
157
158         } else if(obj->is_double) {
159                 if (notag)
160                         buffer_fadd(buf,"%lf",tag,obj->double_value,tag);
161                 else
162                         buffer_fadd(buf,"<%s>%lf</%s>",tag,obj->double_value,tag);
163
164
165         } else if (obj->is_array) {
166                 if (!notag) {
167                         if(!fm_class)
168                                 buffer_add(buf,"<array>");
169                         else
170                                 buffer_fadd(buf,"<%s>",tag);
171                 }
172
173                 for( i = 0; i!= obj->size; i++ ) {
174                         _rest_xml_output(buf, obj->get_index(obj,i), obj->classname, i,0);
175                 }
176
177                 if (!notag) {
178                         if(!fm_class)
179                                 buffer_add(buf,"</array>");
180                         else
181                                 buffer_fadd(buf,"</%s>",tag);
182                 }
183
184         } else if (obj->is_hash) {
185
186                 if (!notag) {
187                         if(!fm_class)
188                                 buffer_add(buf,"<hash>");
189                         else
190                                 buffer_fadd(buf,"<%s>",tag);
191                 }
192
193                 object_iterator* itr = new_iterator(obj);
194                 object_node* tmp;
195                 while( (tmp = itr->next(itr)) ) {
196                         if (notag) {
197                                 buffer_fadd(buf,"<%s>",tmp->key);
198                         } else {
199                                 buffer_add(buf,"<pair>");
200                                 buffer_fadd(buf,"<key>%s</key><value>",tmp->key);
201                         }
202
203                         _rest_xml_output(buf, tmp->item, NULL,0,notag);
204
205                         if (notag) {
206                                 buffer_fadd(buf,"</%s>",tmp->key);
207                         } else {
208                                 buffer_add(buf,"</value></pair>");
209                         }
210                 }
211                 free_iterator(itr);
212
213                 if (!notag) {
214                         if(!fm_class)
215                                 buffer_add(buf,"</hash>");
216                         else
217                                 buffer_fadd(buf,"</%s>",tag);
218                 }
219
220         }
221
222         if (obj->classname)
223                 buffer_fadd(buf,"</Object></%s>",tag);
224
225         free(tag);
226 }
227
228 char * _lookup_fm_field(char * class, int pos) {
229
230 C
231
232 print SOURCE "  if (class == NULL) return NULL;";
233
234 for my $object (keys %$map) {
235
236         my $short_name                          = $map->{$object}->{hint};
237
238         print SOURCE <<"        C";
239
240         else if (!strcmp(class, "$short_name")) {
241                 switch (pos) {
242         C
243
244         for my $field (keys %{$map->{$object}->{fields}}) {
245                 my $position = $map->{$object}->{fields}->{$field}->{position};
246
247                 print SOURCE <<"                C";
248                         case $position:
249                                 return strdup("$field");
250                                 break;
251                 C
252         }
253         print SOURCE "          }\n";
254         print SOURCE "  }\n";
255 }
256 print SOURCE '  return strdup("datum");'."\n";
257 print SOURCE "}\n";
258
259 close HEADER;
260 close SOURCE;
261
262 warn  "done\n";
263