Mercurial > hg > Members > kono > tree_dandy2
annotate xml.c @ 35:3b92a4b17049 default tip
fix for macosx Yosemite
author | Nozomi |
---|---|
date | Thu, 19 May 2016 18:18:34 +0900 |
parents | 6754fbb63ac7 |
children |
rev | line source |
---|---|
0 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <unistd.h> | |
5 #include <libxml/parser.h> | |
6 #include "object.h" | |
7 #include "xml.h" | |
8 | |
9 #include "error.h" | |
10 | |
11 #define ALIGN_16BYTE 16 | |
12 | |
13 extern int decode(char *cont, FILE *outfile); | |
14 | |
15 static inline char *skip_to_number(char *cont) | |
16 { | |
17 if (cont == NULL) return(NULL); | |
18 for (;(*cont < '+' || *cont > '9') && (*cont != '\0');cont++) {} | |
19 if (*cont == '\0') | |
20 { | |
21 fprintf(stderr,"Content data is short\n"); | |
22 return(NULL); | |
23 } | |
24 return(cont); | |
25 } | |
26 | |
27 | |
28 static inline char *pickup_exponent(int *exp, char *cont) | |
29 { | |
30 int n,value=0,shift=10; | |
31 | |
32 if (*cont == ',' || *cont == '\n') return(NULL); | |
33 | |
34 for (;*cont != ',' && *cont != '\n' && *cont != '\t';cont++) | |
35 { | |
36 if (*cont == '-') | |
37 { | |
35 | 38 shift = 0; |
0 | 39 } |
40 else if (*cont >= '0' && *cont <= '9') | |
41 { | |
42 value *= 10; | |
43 value += *cont - 48; | |
44 } | |
45 else if (*cont == '+' || *cont == ' ') | |
46 { | |
47 // ignore | |
48 } | |
49 else | |
50 { | |
51 fprintf(stderr,"Pick up exponent failed : %c(%d)\n",*cont,*cont); | |
52 return(NULL); | |
53 } | |
54 } | |
55 | |
56 for (n=0;n < value;n++) shift *= shift; | |
57 | |
58 if (value == 0) | |
59 { | |
60 *exp = 1; | |
61 } | |
62 else | |
63 { | |
64 *exp = shift; | |
65 } | |
66 return(cont-1); | |
67 } | |
68 | |
69 | |
70 static inline char *pickup_float(char *cont, float *index) | |
71 { | |
72 int sign=1,exp=1; | |
73 float shift=10,val_dec=0,val_int=0; | |
74 | |
75 cont = skip_to_number(cont); | |
76 if (cont == NULL) return(NULL); | |
77 | |
78 for (;*cont != ',' && *cont != '\n' && *cont != '\t';cont++) | |
79 { | |
80 if (*cont == '-') | |
81 { | |
82 sign = -1; | |
83 } | |
84 else if (*cont == '.') | |
85 { | |
86 shift = 0.1; | |
87 } | |
88 else if (*cont >= '0' && *cont <= '9') | |
89 { | |
90 if (shift == 10) | |
91 { | |
92 val_int *= shift; | |
93 val_int += *cont - 48; | |
94 } | |
95 else | |
96 { | |
97 val_dec += (*cont - 48) * shift; | |
98 shift *= 0.1; | |
99 } | |
100 } | |
101 else if (*cont == 'e' || *cont == 'E') | |
102 { | |
103 cont = pickup_exponent(&exp,cont+1); | |
104 if (cont == NULL) return(NULL); | |
105 } | |
106 else if (*cont == '+' || *cont == '/' || *cont == ' ') | |
107 { | |
108 // ignore | |
109 } | |
110 else | |
111 { | |
112 fprintf(stderr,"Pick up float failed : %c(%d)\n",*cont,*cont); | |
113 return(NULL); | |
114 } | |
115 } | |
116 | |
117 *index = sign * (val_int + val_dec) * exp; | |
118 cont++; | |
119 return(cont); | |
120 } | |
121 | |
122 | |
123 static FVECTOR *get_surface_data(SURFACE *surf, xmlNodePtr cur) | |
124 { | |
125 int n; | |
126 char *cont; | |
127 float *index; | |
128 FVECTOR *data[4]; | |
129 FILE *outfile = NULL; | |
130 | |
131 /* | |
132 data[0]: point position | |
133 data[1]: point direction | |
134 data[2]: point QT position | |
135 data[3]: point color | |
136 */ | |
137 | |
138 data[0] = (FVECTOR *)malloc(sizeof(FVECTOR)*(surf->size)*4); | |
139 data[1] = data[0] + surf->size; | |
140 data[2] = data[1] + surf->size; | |
141 data[3] = data[2] + surf->size; | |
142 | |
143 for (;cur;cur=cur->next) | |
144 { | |
145 if (!xmlStrcmp(cur->name,(xmlChar*)"coordinate")) | |
146 { | |
147 cont = (char *)xmlNodeGetContent(cur); | |
148 for (n=0,index=(float*)data[0];n < surf->size;n++,index+=4) | |
149 { | |
150 cont = pickup_float(cont,index); | |
151 cont = pickup_float(cont,index+1); | |
152 cont = pickup_float(cont,index+2); | |
153 index[3] = 1.0; | |
154 | |
155 if (cont == NULL) | |
156 { | |
157 fprintf(stderr,"Analyzing surface data failed coordinate\n"); | |
158 return(NULL); | |
159 } | |
160 } | |
161 } | |
162 else if (!xmlStrcmp(cur->name,(xmlChar*)"normal")) | |
163 { | |
164 cont = (char *)xmlNodeGetContent(cur); | |
165 for (n=0,index=(float*)data[1];n < surf->size;n++,index+=4) | |
166 { | |
167 cont = pickup_float(cont,index); | |
168 cont = pickup_float(cont,index+1); | |
169 cont = pickup_float(cont,index+2); | |
170 index[3] = 1.0; | |
171 | |
172 if (cont == NULL) | |
173 { | |
174 fprintf(stderr,"Analyzing surface data failed normal\n"); | |
175 return(NULL); | |
176 } | |
177 } | |
178 } | |
179 else if (!xmlStrcmp(cur->name,(xmlChar*)"model")) | |
180 { | |
181 cont = (char *)xmlNodeGetContent(cur); | |
182 //for (n=0,index=(float*)data[2]; n < surf->size;n++,index+=4) | |
183 for (n=0,index=(float*)data[2]; n < 1; n++,index+=4) | |
184 { | |
185 cont = pickup_float(cont,index); | |
186 cont = pickup_float(cont,index+1); | |
187 cont = pickup_float(cont,index+2); | |
188 //cont = pickup_float(cont,index+3); | |
189 index[3] = 1.0; | |
190 | |
191 if (cont == NULL) | |
192 { | |
193 fprintf(stderr,"Analyzing surface data failed model\n"); | |
194 return(NULL); | |
195 } | |
196 } | |
197 } | |
198 else if (!xmlStrcmp(cur->name,(xmlChar*)"texture")) | |
199 { | |
200 cont = (char *)xmlNodeGetContent(cur); | |
201 if (cont == NULL) | |
202 { | |
203 for (n=0,index=(float*)data[3];n < surf->size;n++,index+=4) | |
204 { | |
205 index[0] = 0.0; | |
206 index[1] = 0.0; | |
207 index[2] = 0.0; | |
208 index[3] = 0.0; | |
209 } | |
210 } | |
211 else | |
212 { | |
213 for (n=0,index=(float*)data[3]; n < surf->size; n++,index+=4) | |
214 { | |
215 cont = pickup_float(cont,index); | |
216 cont = pickup_float(cont,index+1); | |
217 index[2] = 1.0; | |
218 index[3] = 0.0; | |
219 | |
220 if (cont == NULL) | |
221 { | |
222 fprintf(stderr,"Analyzing surface data failed last\n"); | |
223 return(NULL); | |
224 } | |
225 } | |
226 } | |
227 } | |
228 else if(!xmlStrcmp(cur->name,(xmlChar*)"image")) | |
229 { | |
230 surf->image_name = (char *)xmlGetProp(cur,(xmlChar *)"name"); | |
16
7e7e6f73b11f
make tmp image file in /tmp/
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 char *buf = (char*)malloc(strlen(surf->image_name)+10); |
7e7e6f73b11f
make tmp image file in /tmp/
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 buf[0] = 0; |
7e7e6f73b11f
make tmp image file in /tmp/
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 strcat(buf,"/tmp/"); |
7e7e6f73b11f
make tmp image file in /tmp/
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
234 surf->image_name = strcat(buf, surf->image_name); |
0 | 235 |
236 outfile = fopen(surf->image_name,"wb"); | |
237 if(NULL == outfile) | |
238 { | |
239 printf("error open file\n"); | |
240 } | |
241 | |
242 cont = (char *)xmlNodeGetContent(cur); | |
243 decode(cont, outfile); | |
244 fclose(outfile); | |
245 // unlink(surf->image_name); | |
246 } | |
247 } | |
248 return(data[0]); | |
249 } | |
250 | |
251 | |
252 static SURFACE *create_surface_data(xmlNodePtr cur) | |
253 { | |
254 char *name; | |
255 char *parent_name; | |
256 SURFACE *surface; | |
257 | |
258 | |
259 surface = (SURFACE *)malloc(sizeof(SURFACE)); | |
260 if (surface == NULL) | |
261 { | |
262 fprintf(stderr,"malloc failed at create_surface_data"); | |
263 return(NULL); | |
264 } | |
265 surface->size = atoi((char *)xmlGetProp(cur,(xmlChar *)"size")); | |
266 name = (char *)xmlGetProp(cur,(xmlChar *)"name"); | |
267 parent_name = (char *)xmlGetProp(cur,(xmlChar *)"parent"); | |
268 surface->name = name; | |
269 surface->parent_name = parent_name; | |
270 surface->next = NULL; | |
271 | |
272 surface->data[0] = get_surface_data(surface,cur->children); | |
273 surface->data[1] = get_surface_data(surface,cur->children)+surface->size; | |
274 surface->data[2] = get_surface_data(surface,cur->children)+surface->size*2; | |
275 surface->data[3] = get_surface_data(surface,cur->children)+surface->size*3; | |
276 | |
277 | |
278 return(surface); | |
279 } | |
280 | |
281 | |
282 | |
283 static SURFACE *get_node_point(SURFACE *surfaces, char *name) | |
284 { | |
285 SURFACE *list = surfaces; | |
286 SURFACE *node = NULL; | |
287 while(list != NULL) | |
288 { | |
289 if(!xmlStrcmp((xmlChar *)list->name,(xmlChar *)name)) | |
290 { | |
291 node = list; | |
292 } | |
293 list = list->next; | |
294 } | |
295 return node; | |
296 } | |
297 | |
298 | |
299 static SURFACE *create_tree(SURFACE *surfaces) | |
300 { | |
301 SURFACE *linear_list; | |
302 SURFACE *list_top = NULL; | |
303 SURFACE *parent; | |
304 | |
305 linear_list = surfaces; | |
306 | |
307 while(linear_list != NULL) | |
308 { | |
309 if(xmlStrcmp((xmlChar *)linear_list->parent_name, (xmlChar *)"NULL")) | |
310 { | |
311 parent = get_node_point(surfaces,linear_list->parent_name); | |
312 if(parent->child == NULL) | |
313 { | |
314 parent->child = linear_list; | |
315 } | |
316 else | |
317 { | |
318 parent->child->brother = linear_list; | |
319 } | |
320 linear_list->parent = parent; | |
321 __debug("name = %s, parent name = %s\n",linear_list->name, linear_list->parent_name); | |
322 __debug(" parent = %s\n",linear_list->parent->name); | |
323 __debug(" parent->child = %s\n",linear_list->parent->child->name); | |
324 | |
325 linear_list->child = NULL; | |
326 linear_list->brother = NULL; | |
327 linear_list = linear_list->next; | |
328 } | |
329 else | |
330 { | |
331 list_top = linear_list; | |
332 list_top->parent = NULL; | |
333 list_top->brother = NULL; | |
334 list_top->child = NULL; | |
335 linear_list = linear_list->next; | |
336 //printf("top name = %s\n",list_top->name); | |
337 } | |
338 } | |
339 | |
340 return list_top; | |
341 } | |
342 | |
343 | |
344 static OBJECT *create_object(xmlDocPtr doc) | |
345 { | |
25
6754fbb63ac7
64bit and sys.c removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
16
diff
changeset
|
346 char *align; |
0 | 347 OBJECT *obj; |
348 SURFACE *tmp,**joint; | |
349 xmlNodePtr cur; | |
350 | |
351 cur = xmlDocGetRootElement(doc); | |
352 if (cur == NULL) | |
353 { | |
354 fprintf(stderr,"XML file is empty\n"); | |
355 return(NULL); | |
356 } | |
357 | |
358 if (xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D")) | |
359 { | |
360 fprintf(stderr,"This data format isn't OBJECT-3D\n"); | |
361 return(NULL); | |
362 } | |
363 | |
25
6754fbb63ac7
64bit and sys.c removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
16
diff
changeset
|
364 if (posix_memalign((void**)&align,16,sizeof(OBJECT)) < 0) |
0 | 365 { |
366 fprintf(stderr,"malloc failed at create_object : OBJECT\n"); | |
367 return(NULL); | |
368 } | |
369 | |
370 obj = (OBJECT *)align; | |
371 init_object(obj); | |
372 | |
373 obj->surfaces = NULL; | |
374 joint = &(obj->surfaces); | |
375 | |
376 for (cur=cur->children; cur; cur=cur->next) | |
377 { | |
378 if (!xmlStrcmp(cur->name,(xmlChar*)"surface")) | |
379 { | |
380 tmp = create_surface_data(cur); | |
381 if (tmp == NULL) | |
382 { | |
383 printf("temp is NULL\n"); | |
384 free_object(obj); | |
385 return(NULL); | |
386 } | |
387 *joint = tmp; | |
388 joint = &(tmp->next); | |
389 } | |
390 } | |
391 | |
392 obj->surfaces = create_tree(obj->surfaces); | |
393 | |
394 return(obj); | |
395 } | |
396 | |
397 | |
398 //static int read_xml_3d_file(const char *file_name) | |
399 OBJECT *read_xml_3d_file(const char *file_name) | |
400 { | |
401 xmlDocPtr doc; | |
402 OBJECT *ptr; | |
403 | |
404 doc = xmlParseFile(file_name); | |
405 if(doc == NULL) | |
406 { | |
407 printf("It seems that %s is not a xml data.\n", file_name); | |
408 } | |
409 | |
410 ptr = create_object(doc); | |
411 if(ptr == NULL) | |
412 { | |
413 printf("XML create_object failed : %s\n",file_name); | |
414 } | |
415 | |
416 xmlFreeDoc(doc); | |
417 return(ptr); | |
418 } |