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

Last change on this file since 803 was 790, checked in by djay, 8 years ago

Add support for nested inputs and outputs.

File size: 18.0 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 occurred
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 nleveld=-1;
87  int level=0;
88  int plevel=level;
89  int nlevel=0;
90  int pnlevel=0;
91  int ilevel=-1;
92  int blevel=-1;
93  int ttype=0;
94  int outputs=-1;
95  int noutputs=-1;
96  int wait_metadata=-1;
97  char *cur_key;
98  do {
99    yaml_parser_scan(&parser, &token);
100    switch(token.type)
101    {
102    /* Stream start/end */
103    case YAML_STREAM_START_TOKEN: 
104#ifdef DEBUG_YAML
105      puts("STREAM START"); 
106#endif
107      break;
108    case YAML_STREAM_END_TOKEN:   
109#ifdef DEBUG_YAML
110      puts("STREAM END");   
111#endif
112      break;
113    /* Token types (read before actual token) */
114    case YAML_KEY_TOKEN:   
115#ifdef DEBUG_YAML
116      printf("(Key token)   "); 
117#endif
118      ttype=0;
119      break;
120    case YAML_VALUE_TOKEN: 
121#ifdef DEBUG_YAML
122      printf("(Value token) "); 
123#endif
124      ttype=1;
125      break;
126    /* Block delimeters */
127    case YAML_BLOCK_SEQUENCE_START_TOKEN: 
128#ifdef DEBUG_YAML
129      puts("<b>Start Block (Sequence)</b>"); 
130#endif
131      break;
132    case YAML_BLOCK_ENTRY_TOKEN:         
133#ifdef DEBUG_YAML
134      puts("<b>Start Block (Entry)</b>");   
135#endif
136      break;
137    case YAML_BLOCK_END_TOKEN:     
138      blevel--;
139      if(ilevel>=0)
140        ilevel--;
141#ifdef DEBUG_YAML
142      printf("<b>End block</b> (%d,%d,%d,%d)\n", blevel,level,ilevel,ttype); 
143#endif
144      break;
145    /* Data */
146    case YAML_BLOCK_MAPPING_START_TOKEN: 
147#ifdef DEBUG_YAML
148      puts("[Block mapping]");           
149#endif
150      blevel++;
151      break;
152    case YAML_SCALAR_TOKEN:
153      if((blevel-1)/2<nlevel){
154        pnlevel=nlevel;
155        nlevel=(blevel-1)/2;
156        nleveld=1;
157      }else
158        nleveld=-1;
159      if(ttype==0){
160        cur_key=zStrdup((char *)token.data.scalar.value);
161      }
162      if(ttype==1){
163        if(current_content==NULL){
164          current_content=createMap(cur_key,(char *)token.data.scalar.value);
165        }else{
166          addToMap(current_content,cur_key,(char *)token.data.scalar.value);
167        }
168        free(cur_key);
169        cur_key=NULL;
170      }
171
172      if(ttype==0 && blevel==0 && level==0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0 && blevel==0){
173        addMapToMap(&my_service->content,current_content);
174#ifdef DEBUG_YAML
175        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
176#endif
177        freeMap(&current_content);
178        free(current_content);
179        current_content=NULL;
180        wait_metadata=1;
181      }
182      if(ttype==0 && blevel>0 && level>0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0){
183        if(current_element->content==NULL && current_content!=NULL)
184          addMapToMap(&current_element->content,current_content);
185#ifdef DEBUG_YAML
186        dumpMap(current_content);
187        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
188#endif
189        freeMap(&current_content);
190        free(current_content);
191        current_content=NULL;
192        wait_metadata=1;
193      }
194      if(strcasecmp((char *)token.data.scalar.value,"Child")==0){
195        elements* cursor=my_service->inputs;
196        if(outputs==1)
197          cursor=my_service->outputs;
198        for(int i=0;(blevel/2)>1 && i<(blevel/2)-1 && cursor!=NULL;i++){
199          while(cursor->next!=NULL)
200            cursor=cursor->next;
201          if(cursor->child!=NULL){
202            cursor=cursor->child;
203          }
204        }
205        if(current_content!=NULL){
206          addMapToMap(&current_element->content,current_content);
207          freeMap(&current_content);
208          free(current_content);
209          current_content=NULL;
210        }
211        if(current_element!=NULL){
212          if(blevel/2>1 && cursor!=NULL){
213            if(cursor->child==NULL)
214              cursor->child=dupElements(current_element);
215            else
216              addToElements(&cursor->child,current_element);
217          }
218          else{
219            if(outputs<0)
220              if(my_service->inputs==NULL)
221                my_service->inputs=dupElements(current_element);
222              else
223                addToElements(&my_service->inputs,current_element);
224            else
225              if(my_service->inputs==NULL)
226                my_service->outputs=dupElements(current_element);
227              else
228                addToElements(&my_service->outputs,current_element);
229          }
230          freeElements(&current_element);
231          free(current_element);
232          current_element=NULL;
233        }
234        nlevel+=1;
235      }
236      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"inputs")==0 && blevel==0){
237        if(wait_metadata>0){
238          addMapToMap(&my_service->metadata,current_content);
239          wait_metadata=-1;
240        }else{
241          if(current_content!=NULL && my_service->content==NULL)
242            addMapToMap(&my_service->content,current_content);
243        }
244#ifdef DEBUG_YAML
245        dumpMap(current_content);
246        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
247#endif
248        freeMap(&current_content);
249        free(current_content);
250        current_content=NULL;
251        wait_metadata=false;
252        level++;
253      }
254      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"outputs")==0 && blevel==1){
255        outputs=1;
256        level++;
257#ifdef DEBUG_YAML
258        dumpMap(current_content);
259        printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
260#endif
261        if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
262          current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
263          current_element->defaults->content=NULL;
264          current_element->defaults->next=NULL;
265          addMapToMap(&current_element->defaults->content,current_content);
266#ifdef DEBUG_YAML
267          dumpElements(current_element);
268          dumpMap(current_content);
269          fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
270#endif
271          freeMap(&current_content);
272          free(current_content);
273          current_content=NULL;
274        }else{
275          if(current_content!=NULL && ilevel<=0){
276            addMapToIoType(&current_element->supported,current_content);
277#ifdef DEBUG_YAML
278            dumpElements(current_element);
279            dumpMap(current_content);
280            fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
281#endif
282            freeMap(&current_content);
283            free(current_content);
284            current_content=NULL;
285          }
286        }
287      }
288      if(level==1 && strcasecmp((char *)token.data.scalar.value,"default")==0){
289        ilevel=0;
290      }
291      if(level==1 && strcasecmp((char *)token.data.scalar.value,"supported")==0){
292#ifdef DEBUG_YAML
293        dumpMap(current_content);
294        printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
295#endif
296        if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
297          current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
298          current_element->defaults->content=NULL;
299          current_element->defaults->next=NULL;
300          addMapToMap(&current_element->defaults->content,current_content);
301#ifdef DEBUG_YAML
302          dumpElements(current_element);
303          dumpMap(current_content);
304          fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
305#endif
306          freeMap(&current_content);
307          free(current_content);
308          current_content=NULL;
309        }else{
310          if(current_content!=NULL && ilevel<=0){
311            if(current_element->supported==NULL){
312              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
313              current_element->supported->content=NULL;
314              current_element->supported->next=NULL;
315            }
316            addMapToMap(&current_element->supported->content,current_content);
317#ifdef DEBUG_YAML
318            dumpElements(current_element);
319            fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
320#endif
321            freeMap(&current_content);
322            free(current_content);
323            current_content=NULL;
324          }
325        }
326        ilevel=1;
327      }
328
329
330      if(strncasecmp((char *)token.data.scalar.value,"ComplexData",11)==0 || 
331         strncasecmp((char *)token.data.scalar.value,"LiteralData",10)==0 || 
332         strncasecmp((char *)token.data.scalar.value,"ComplexOutput",13)==0 || 
333         strncasecmp((char *)token.data.scalar.value,"LiteralOutput",12)==0 || 
334         strncasecmp((char *)token.data.scalar.value,"BoundingBoxOutput",13)==0 || 
335         strncasecmp((char *)token.data.scalar.value,"BoundingBoxData",12)==0){
336        current_element->format=zStrdup((char *)token.data.scalar.value);
337        free(cur_key);
338        cur_key=NULL;
339        if(wait_metadata>0 && current_content!=NULL){
340          addMapToMap(&current_element->metadata,current_content);
341          wait_metadata=-1;
342        }else{
343          if(current_content!=NULL){
344            addMapToMap(&current_element->content,current_content);
345          }
346        }
347#ifdef DEBUG_YAML
348        dumpMap(current_content);
349        fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
350#endif
351        freeMap(&current_content);
352        free(current_content);
353        current_content=NULL;
354#ifdef DEBUG_YAML
355        dumpElements(current_element);
356#endif
357      }
358
359      if(strcasecmp(token.data.scalar.value,"default")!=0 && strcasecmp(token.data.scalar.value,"supported")!=0 && level==1 && (blevel-1)%2==0 && blevel!=1 && (blevel-1)/2==nlevel){
360        if(current_element==NULL)
361          current_element=createElements((char *)token.data.scalar.value);
362        else{
363          if(current_content!=NULL){
364            if(current_element->defaults==NULL){
365              current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
366              current_element->defaults->content=NULL;
367              current_element->defaults->next=NULL;
368              addMapToMap(&current_element->defaults->content,current_content);
369            }else{
370              if(current_element->supported==NULL){
371                current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
372                current_element->supported->content=NULL;
373                current_element->supported->next=NULL;
374                addMapToMap(&current_element->supported->content,current_content);
375              }else
376                addMapToIoType(&current_element->supported,current_content);
377            }
378            freeMap(&current_content);
379            free(current_content);
380            current_content=NULL;
381          }
382         
383          elements* cursor=my_service->inputs;
384          if(outputs==1)
385            cursor=my_service->outputs;
386          int llevel=((blevel-1)/2);
387          if(nleveld>0)
388            llevel=((blevel-1)/2)+1;
389          for(int i=0;llevel>1 && i<llevel-1 && cursor!=NULL;i++){
390            while(cursor->next!=NULL)
391              cursor=cursor->next;
392            if(cursor->child!=NULL){
393              cursor=cursor->child;
394            }
395          }
396          if(llevel>1)
397            if(cursor->child==NULL)
398              cursor->child=dupElements(current_element);
399            else
400              addToElements(&cursor->child,current_element);
401          else
402            if(cursor==NULL)
403              cursor=dupElements(current_element);
404            else
405              addToElements(&cursor,current_element);
406          freeElements(&current_element);
407          free(current_element);
408          current_element=NULL;
409          current_element=createElements((char *)token.data.scalar.value);
410        }
411      }
412      if(blevel==1 && level==1){
413        if(current_element!=NULL && current_content!=NULL){
414          if(current_element->defaults==NULL){
415            current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
416            current_element->defaults->content=NULL;
417            current_element->defaults->next=NULL;
418            addMapToMap(&current_element->defaults->content,current_content);
419          }else{
420            if(current_element->supported==NULL){
421              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
422              current_element->supported->content=NULL;
423              current_element->supported->next=NULL;
424              addMapToMap(&current_element->supported->content,current_content);
425            }else
426              addMapToIoType(&current_element->supported,current_content);
427          }
428          freeMap(&current_content);
429          free(current_content);
430          current_content=NULL;
431        }
432        if(nleveld<0){
433          if(current_element!=NULL){
434            if(outputs<0)
435              if(my_service->inputs==NULL)
436                my_service->inputs=dupElements(current_element);
437              else
438                addToElements(&my_service->inputs,current_element);
439            else
440              if(my_service->outputs==NULL)
441                my_service->outputs=dupElements(current_element);
442              else
443                addToElements(&my_service->outputs,current_element);
444            freeElements(&current_element);
445            free(current_element);
446          }
447        }
448        else{
449          if(current_element!=NULL){
450            elements* cursor=my_service->inputs;
451            if(outputs==1)
452              cursor=my_service->outputs;
453            while(cursor->next!=NULL)
454              cursor=cursor->next;
455            for(int i=0;pnlevel>1 && i<pnlevel-1 && cursor!=NULL;i++){
456              while(cursor->next!=NULL)
457                cursor=cursor->next;
458              if(cursor->child!=NULL){
459                cursor=cursor->child;
460              }
461            }
462            if(cursor->child==NULL)
463              cursor->child=dupElements(current_element);
464            else
465              addToElements(&cursor->child,current_element);
466            freeElements(&current_element);
467            free(current_element);
468          }
469        }   
470        plevel=level;
471        current_element=createElements((char *)token.data.scalar.value);       
472      }
473      if(blevel==1 && level==2){
474        if(current_element!=NULL && current_content!=NULL){
475          if(current_element->defaults==NULL){
476            current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
477            current_element->defaults->content=NULL;
478            current_element->defaults->next=NULL;
479            addMapToMap(&current_element->defaults->content,current_content);
480          }else{
481            if(current_element->supported==NULL){
482              current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
483              current_element->supported->content=NULL;
484              current_element->supported->next=NULL;
485              addMapToMap(&current_element->supported->content,current_content);
486            }else
487              addMapToIoType(&current_element->supported,current_content);
488          }
489          freeMaps(&current_content);
490          free(current_content);
491          current_content=NULL;
492        }
493        if(current_element!=NULL){
494          if(plevel==level){
495            if(my_service->outputs==NULL)
496              my_service->outputs=dupElements(current_element);
497            else
498              addToElements(&my_service->outputs,current_element);
499          }else{
500            if(my_service->inputs==NULL)
501              my_service->inputs=dupElements(current_element);
502            else
503              addToElements(&my_service->inputs,current_element);
504          }
505          freeElements(&current_element);
506          free(current_element);
507        }
508        plevel=level;
509        current_element=createElements((char *)token.data.scalar.value);       
510       
511      }
512
513      if(noutputs>0)
514        outputs=1;
515      if(strcasecmp((char *)token.data.scalar.value,"outputs")==0 && ttype==0 && blevel==0){
516        noutputs=1;
517      }
518     
519
520
521#ifdef DEBUG_YAML
522      printf("scalar %s (%d,%d,%d,%d,%d)\n", token.data.scalar.value,blevel,level,plevel,ilevel,ttype); 
523#endif
524      break;
525    /* Others */
526    default:
527      if(token.type==0){
528        char tmp[1024];
529        sprintf(tmp,"Wrong charater found in %s: \\t",name);
530        setMapInMaps(conf,"lenv","message",tmp);
531        return -1;
532      }
533#ifdef DEBUG_YAML
534      printf("Got token of type %d\n", token.type);
535#endif
536      break;
537    }
538    if(token.type != YAML_STREAM_END_TOKEN )
539      yaml_token_delete(&token);
540  } while(token.type != YAML_STREAM_END_TOKEN);
541  yaml_token_delete(&token);
542
543
544#ifdef DEBUG_YAML
545  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
546#endif
547  if(current_element!=NULL && current_content!=NULL){
548    if(current_element->defaults==NULL){
549      current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
550      current_element->defaults->content=NULL;
551      current_element->defaults->next=NULL;
552      addMapToMap(&current_element->defaults->content,current_content);
553    }else{
554      if(current_element->supported==NULL){
555        current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
556        current_element->supported->content=NULL;
557        current_element->supported->next=NULL;
558        addMapToMap(&current_element->supported->content,current_content);
559      }else
560        addMapToIoType(&current_element->supported,current_content);
561    }
562#ifdef DEBUG_YAML
563    dumpMap(current_content);
564    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
565#endif
566    freeMap(&current_content);
567    free(current_content);
568    current_content=NULL;
569  }
570
571  if(current_element!=NULL){
572    if(nlevel>0){
573      elements* cursor=my_service->inputs;
574      if(outputs==1)
575        cursor=my_service->outputs;
576      for(int i=0;nlevel>1 && i<nlevel-1 && cursor!=NULL;i++){
577        while(cursor->next!=NULL)
578          cursor=cursor->next;
579        if(cursor->child!=NULL){
580          cursor=cursor->child;
581        }
582      }
583      if(cursor->child==NULL)
584        cursor->child=dupElements(current_element);
585      else
586        addToElements(&cursor->child,current_element);
587    }else{
588      if(my_service->outputs==NULL)
589        my_service->outputs=dupElements(current_element);
590      else
591        addToElements(&my_service->outputs,current_element);
592    }
593    freeElements(&current_element);
594    free(current_element);
595    current_element=NULL;
596  }
597  /* END new code */
598
599  /* Cleanup */
600  yaml_parser_delete(&parser);
601  fclose(fh);
602
603#ifdef DEBUG_YAML
604  dumpService(my_service);
605#endif
606  *service=my_service;
607
608  return 1;
609}
610#ifdef __cplusplus
611}
612#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