source: trunk/zoo-project/zoo-kernel/service_yaml.c @ 772

Last change on this file since 772 was 745, checked in by djay, 8 years ago

Fix issue when XML request contains empty nodes for inputs

File size: 13.8 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2014 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <ctype.h>
27#include <service.h>
28#include <yaml.h>
29
30static service* my_service=NULL;
31static map* current_content=NULL;
32static elements* current_element=NULL;
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38/**
39 * Read and parse a ZCFG file in YAML format
40 *
41 * @param conf the conf maps containing the main.cfg settings
42 * @param file the file name to read
43 * @param service the service structure to fill
44 * @param name the service name
45 * @return 1 on success, -1 if error occured
46 */
47int getServiceFromYAML(maps* conf, char* file,service** service,char *name){
48  FILE *fh;
49  if(current_content!=NULL){
50    freeMap(&current_content);
51    free(current_content);
52    current_content=NULL;
53  }
54#ifdef DEBUG_SERVICE_CONF
55  fprintf(stderr,"(STARTING)FREE current_element\n");
56#endif
57  if(current_element!=NULL){
58    freeElements(&current_element);
59    free(current_element);
60    current_element=NULL;
61  }
62  my_service=NULL;
63 
64  my_service=*service;
65  my_service->name=strdup(name);
66  my_service->content=NULL;
67  my_service->metadata=NULL;
68  my_service->inputs=NULL;
69  my_service->outputs=NULL;
70  fh = fopen(file,"r");
71  if (fh==NULL){
72    fprintf(stderr,"error : file not found\n") ;
73    return -1;
74  }
75  yaml_parser_t parser;
76  yaml_token_t  token;   /* new variable */
77
78  /* Initialize parser */
79  if(!yaml_parser_initialize(&parser))
80    fputs("Failed to initialize parser!\n", stderr);
81  if(fh == NULL)
82    fputs("Failed to open file!\n", stderr);
83  /* Set input file */
84  yaml_parser_set_input_file(&parser, fh);
85  /* BEGIN new code */
86  int level=0;
87  int plevel=level;
88  int ilevel=-1;
89  int blevel=-1;
90  int ttype=0;
91  int wait_metadata=-1;
92  char *cur_key;
93  do {
94    yaml_parser_scan(&parser, &token);
95    switch(token.type)
96    {
97    /* Stream start/end */
98    case YAML_STREAM_START_TOKEN: 
99#ifdef DEBUG_YAML
100      puts("STREAM START"); 
101#endif
102      break;
103    case YAML_STREAM_END_TOKEN:   
104#ifdef DEBUG_YAML
105      puts("STREAM END");   
106#endif
107      break;
108    /* Token types (read before actual token) */
109    case YAML_KEY_TOKEN:   
110#ifdef DEBUG_YAML
111      printf("(Key token)   "); 
112#endif
113      ttype=0;
114      break;
115    case YAML_VALUE_TOKEN: 
116#ifdef DEBUG_YAML
117      printf("(Value token) "); 
118#endif
119      ttype=1;
120      break;
121    /* Block delimeters */
122    case YAML_BLOCK_SEQUENCE_START_TOKEN: 
123#ifdef DEBUG_YAML
124      puts("<b>Start Block (Sequence)</b>"); 
125#endif
126      break;
127    case YAML_BLOCK_ENTRY_TOKEN:         
128#ifdef DEBUG_YAML
129      puts("<b>Start Block (Entry)</b>");   
130#endif
131      break;
132    case YAML_BLOCK_END_TOKEN:     
133      blevel--;
134      if(ilevel>=0)
135        ilevel--;
136#ifdef DEBUG_YAML
137      printf("<b>End block</b> (%d,%d,%d,%d)\n", blevel,level,ilevel,ttype); 
138#endif
139      break;
140    /* Data */
141    case YAML_BLOCK_MAPPING_START_TOKEN: 
142#ifdef DEBUG_YAML
143      puts("[Block mapping]");           
144#endif
145      blevel++;
146      break;
147    case YAML_SCALAR_TOKEN: 
148      if(ttype==0){
149        cur_key=zStrdup((char *)token.data.scalar.value);
150      }
151      if(ttype==1){
152        if(current_content==NULL){
153          current_content=createMap(cur_key,(char *)token.data.scalar.value);
154        }else{
155          addToMap(current_content,cur_key,(char *)token.data.scalar.value);
156        }
157        free(cur_key);
158        cur_key=NULL;
159      }
160
161      if(ttype==0 && blevel==0 && level==0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0 && blevel==0){
162        addMapToMap(&my_service->content,current_content);
163#ifdef DEBUG_YAML
164        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
165#endif
166        freeMap(&current_content);
167        free(current_content);
168        current_content=NULL;
169        wait_metadata=1;
170      }
171      if(ttype==0 && blevel>0 && level>0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0){
172        if(current_element->content==NULL && current_content!=NULL)
173          addMapToMap(&current_element->content,current_content);
174#ifdef DEBUG_YAML
175        dumpMap(current_content);
176        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
177#endif
178        freeMap(&current_content);
179        free(current_content);
180        current_content=NULL;
181        wait_metadata=1;
182      }
183      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"inputs")==0 && blevel==0){
184        if(wait_metadata>0){
185          addMapToMap(&my_service->metadata,current_content);
186          wait_metadata=-1;
187        }else{
188          if(current_content!=NULL && my_service->content==NULL)
189            addMapToMap(&my_service->content,current_content);
190        }
191#ifdef DEBUG_YAML
192        dumpMap(current_content);
193        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
194#endif
195        freeMap(&current_content);
196        free(current_content);
197        current_content=NULL;
198        wait_metadata=false;
199        level++;
200      }
201      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"outputs")==0 && blevel==1){
202        level++;
203#ifdef DEBUG_YAML
204        dumpMap(current_content);
205        printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
206#endif
207        if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
208          current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
209          current_element->defaults->content=NULL;
210          current_element->defaults->next=NULL;
211          addMapToMap(&current_element->defaults->content,current_content);
212#ifdef DEBUG_YAML
213          dumpElements(current_element);
214          dumpMap(current_content);
215          fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
216#endif
217          freeMap(&current_content);
218          free(current_content);
219          current_content=NULL;
220        }else{
221          if(current_content!=NULL && ilevel<=0){
222            addMapToIoType(&current_element->supported,current_content);
223#ifdef DEBUG_YAML
224            dumpElements(current_element);
225            dumpMap(current_content);
226            fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
227#endif
228            freeMap(&current_content);
229            free(current_content);
230            current_content=NULL;
231          }
232        }
233      }
234      if(level==1 && strcasecmp((char *)token.data.scalar.value,"default")==0){
235        ilevel=0;
236      }
237      if(level==1 && strcasecmp((char *)token.data.scalar.value,"supported")==0){
238#ifdef DEBUG_YAML
239        dumpMap(current_content);
240        printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
241#endif
242        if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
243          current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
244          current_element->defaults->content=NULL;
245          current_element->defaults->next=NULL;
246          addMapToMap(&current_element->defaults->content,current_content);
247#ifdef DEBUG_YAML
248          dumpElements(current_element);
249          dumpMap(current_content);
250          fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
251#endif
252          freeMap(&current_content);
253          free(current_content);
254          current_content=NULL;
255        }else{
256          if(current_content!=NULL && ilevel<=0){
257            if(current_element->supported==NULL){
258              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
259              current_element->supported->content=NULL;
260              current_element->supported->next=NULL;
261            }
262            addMapToMap(&current_element->supported->content,current_content);
263#ifdef DEBUG_YAML
264            dumpElements(current_element);
265            fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
266#endif
267            freeMap(&current_content);
268            free(current_content);
269            current_content=NULL;
270          }
271        }
272        ilevel=1;
273      }
274
275
276      if(strncasecmp((char *)token.data.scalar.value,"ComplexData",11)==0 || 
277         strncasecmp((char *)token.data.scalar.value,"LiteralData",10)==0 || 
278         strncasecmp((char *)token.data.scalar.value,"ComplexOutput",13)==0 || 
279         strncasecmp((char *)token.data.scalar.value,"LiteralOutput",12)==0 || 
280         strncasecmp((char *)token.data.scalar.value,"BoundingBoxOutput",13)==0 || 
281         strncasecmp((char *)token.data.scalar.value,"BoundingBoxData",12)==0){
282        current_element->format=zStrdup((char *)token.data.scalar.value);
283        free(cur_key);
284        cur_key=NULL;
285        if(wait_metadata>0 && current_content!=NULL){
286          addMapToMap(&current_element->metadata,current_content);
287          wait_metadata=-1;
288        }else{
289          if(current_content!=NULL){
290            addMapToMap(&current_element->content,current_content);
291          }
292        }
293#ifdef DEBUG_YAML
294        dumpMap(current_content);
295        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
296#endif
297        freeMap(&current_content);
298        free(current_content);
299        current_content=NULL;
300#ifdef DEBUG_YAML
301        dumpElements(current_element);
302#endif
303      }
304
305      if(blevel==1 && level==1){
306        if(current_element!=NULL && current_content!=NULL){
307          if(current_element->defaults==NULL){
308            current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
309            current_element->defaults->content=NULL;
310            current_element->defaults->next=NULL;
311            addMapToMap(&current_element->defaults->content,current_content);
312          }else{
313            if(current_element->supported==NULL){
314              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
315              current_element->supported->content=NULL;
316              current_element->supported->next=NULL;
317              addMapToMap(&current_element->supported->content,current_content);
318            }else
319              addMapToIoType(&current_element->supported,current_content);
320          }
321        }
322        if(current_element!=NULL){
323          if(my_service->inputs==NULL)
324            my_service->inputs=dupElements(current_element);
325          else
326            addToElements(&my_service->inputs,current_element);
327          freeElements(&current_element);
328          free(current_element);
329        }
330        plevel=level;
331        current_element=(elements*)malloc(ELEMENTS_SIZE);
332        current_element->name=zStrdup((char *)token.data.scalar.value);
333        current_element->content=NULL;
334        current_element->metadata=NULL;
335        current_element->format=NULL;
336        current_element->defaults=NULL;
337        current_element->supported=NULL;
338        current_element->next=NULL;
339       
340      }
341      if(blevel==1 && level==2){
342        if(current_element!=NULL && current_content!=NULL){
343          if(current_element->defaults==NULL){
344            current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
345            current_element->defaults->content=NULL;
346            current_element->defaults->next=NULL;
347            addMapToMap(&current_element->defaults->content,current_content);
348          }else{
349            if(current_element->supported==NULL){
350              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
351              current_element->supported->content=NULL;
352              current_element->supported->next=NULL;
353              addMapToMap(&current_element->supported->content,current_content);
354            }else
355              addMapToIoType(&current_element->supported,current_content);
356          }
357        }
358        if(current_element!=NULL){
359          if(plevel==level){
360            if(my_service->outputs==NULL)
361              my_service->outputs=dupElements(current_element);
362            else
363              addToElements(&my_service->outputs,current_element);
364          }else{
365            if(my_service->inputs==NULL)
366              my_service->inputs=dupElements(current_element);
367            else
368              addToElements(&my_service->inputs,current_element);
369          }
370          freeElements(&current_element);
371          free(current_element);
372        }
373        plevel=level;
374        current_element=(elements*)malloc(ELEMENTS_SIZE);
375        current_element->name=zStrdup((char *)token.data.scalar.value);
376        current_element->content=NULL;
377        current_element->metadata=NULL;
378        current_element->format=NULL;
379        current_element->defaults=NULL;
380        current_element->supported=NULL;
381        current_element->next=NULL;
382       
383      }
384
385
386#ifdef DEBUG_YAML
387      printf("scalar %s (%d,%d,%d,%d,%d)\n", token.data.scalar.value,blevel,level,plevel,ilevel,ttype); 
388#endif
389      break;
390    /* Others */
391    default:
392      if(token.type==0){
393        char tmp[1024];
394        sprintf(tmp,"Wrong charater found in %s: \\t",name);
395        setMapInMaps(conf,"lenv","message",tmp);
396        return -1;
397      }
398#ifdef DEBUG_YAML
399      printf("Got token of type %d\n", token.type);
400#endif
401      break;
402    }
403    if(token.type != YAML_STREAM_END_TOKEN )
404      yaml_token_delete(&token);
405  } while(token.type != YAML_STREAM_END_TOKEN);
406  yaml_token_delete(&token);
407
408
409#ifdef DEBUG_YAML
410  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
411#endif
412  if(current_element!=NULL && current_content!=NULL){
413    if(current_element->defaults==NULL){
414      current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
415      current_element->defaults->content=NULL;
416      current_element->defaults->next=NULL;
417      addMapToMap(&current_element->defaults->content,current_content);
418    }else{
419      if(current_element->supported==NULL){
420        current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
421        current_element->supported->content=NULL;
422        current_element->supported->next=NULL;
423        addMapToMap(&current_element->supported->content,current_content);
424      }else
425        addMapToIoType(&current_element->supported,current_content);
426    }
427#ifdef DEBUG_YAML
428    dumpMap(current_content);
429    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
430#endif
431    freeMap(&current_content);
432    free(current_content);
433    current_content=NULL;
434  }
435  if(current_element!=NULL){
436    if(my_service->outputs==NULL)
437      my_service->outputs=dupElements(current_element);
438    else
439      addToElements(&my_service->outputs,current_element);
440    freeElements(&current_element);
441    free(current_element);
442    current_element=NULL;
443  }
444  /* END new code */
445
446  /* Cleanup */
447  yaml_parser_delete(&parser);
448  fclose(fh);
449
450#ifdef DEBUG_YAML
451  dumpService(my_service);
452#endif
453  *service=my_service;
454
455  return 1;
456}
457#ifdef __cplusplus
458}
459#endif
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png