source: trunk/zoo-project/zoo-kernel/service.c @ 689

Last change on this file since 689 was 682, checked in by djay, 10 years ago

Fix GetResult? and POST asynchronous requests on Windows. Prevent CONTENT_TYPE=text/xml before creating the process using CreateProcess?. Revert modifications made r587 for using url_decode directly inside zoo_loader.c, the url_decode call should be in kvpParseInputs (from request_parser.c), indeed, there should not be any decoding required in other cases than Execute requests. Fix issue in mapsFromPyDict, small changes in mapFromPyDict to fix parsing result value (only) for Python 3.

  • Property svn:keywords set to Id
File size: 32.4 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2015 GeoLabs SARL
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 "service.h"
26
27/**
28 * Dump a map on stderr
29 *
30 * @param t the map to dump
31 */
32void _dumpMap(map* t){
33  if(t!=NULL){
34    fprintf(stderr,"%s: %s\n",t->name,t->value);
35    fflush(stderr);
36  }else{
37    fprintf(stderr,"NULL\n");
38    fflush(stderr);
39  }
40}
41
42/**
43 * Dump a map on stderr, see _dumpMap()
44 *
45 * @param t the map to dump
46 */
47void dumpMap(map* t){
48  map* tmp=t;
49  while(tmp!=NULL){
50    _dumpMap(tmp);
51    tmp=tmp->next;
52  }
53}
54
55/**
56 * Dump a map to a file
57 *
58 * @param t the map to dump to file
59 * @param file the file to store the map
60 */
61void dumpMapToFile(map* t,FILE* file){
62  map* tmp=t;
63  while(tmp!=NULL){
64    fprintf(file,"%s = %s\n",tmp->name,tmp->value);
65    tmp=tmp->next;
66  }
67}
68
69/**
70 * Dump a maps on stderr, see dumpMap().
71 *
72 * @param m the map to dump
73 */
74void dumpMaps(maps* m){
75  maps* tmp=m;
76  while(tmp!=NULL){
77    fprintf(stderr,"MAP => [%s] \n",tmp->name);
78    dumpMap(tmp->content);
79    tmp=tmp->next;
80  }
81}
82
83/**
84 * Dump a maps to a file, see dumpMapToFile().
85 *
86 * @param m the map to dump
87 * @param file_path the full path to the file name to store the map
88 */
89void dumpMapsToFile(maps* m,char* file_path,int limit){
90  FILE* file=fopen(file_path,"w+");
91  maps* tmp=m;
92  int cnt=0;
93  while(tmp!=NULL){
94    fprintf(file,"[%s]\n",tmp->name);
95    dumpMapToFile(tmp->content,file);
96    fflush(file);
97    tmp=tmp->next;
98    cnt++;
99    if(limit>=0 && cnt==limit)
100      tmp=NULL;
101  }
102  fflush(file);
103  fclose(file);
104}
105
106/**
107 * Create a new map
108 *
109 * @param name the key to add to the map
110 * @param value the corresponding value to add to the map
111 * @return the allocated map
112 */
113map* createMap(const char* name,const char* value){
114  map* tmp=(map *)malloc(MAP_SIZE);
115  tmp->name=zStrdup(name);
116  tmp->value=zStrdup(value);
117  tmp->next=NULL;
118  return tmp;
119}
120
121/**
122 * Count number of map in a map
123 *
124 * @param m the maps to count
125 * @return number of map in a map
126 */
127int count(map* m){
128  map* tmp=m;
129  int c=0;
130  while(tmp!=NULL){
131    c++;
132    tmp=tmp->next;
133  }
134  return c;
135}
136
137/**
138 * Verify if a key exist in a map
139 *
140 * @param m the map to search for the key
141 * @param key the key to search in the map
142 * @return true if the key wwas found, false in other case
143 */
144bool hasKey(map* m,const char *key){
145  map* tmp=m;
146  while(tmp!=NULL){
147    if(strcasecmp(tmp->name,key)==0)
148      return true;
149    tmp=tmp->next;
150  }
151#ifdef DEBUG_MAP
152  fprintf(stderr,"NOT FOUND \n");
153#endif
154  return false;
155}
156
157/**
158 * Access a specific maps
159 *
160 * @param m the maps to search for the key
161 * @param key the key to search in the maps
162 * @return a pointer on the maps found or NULL if not found
163 */
164maps* getMaps(maps* m,const char *key){
165  maps* tmp=m;
166  while(tmp!=NULL){
167    if(strcasecmp(tmp->name,key)==0){
168      return tmp;
169    }
170    tmp=tmp->next;
171  }
172  return NULL;
173}
174
175/**
176 * Access a specific map
177 *
178 * @param m the map to search for the key
179 * @param key the key to search in the map
180 * @return a pointer on the map found or NULL if not found
181 */
182map* getMap(map* m,const char *key){
183  map* tmp=m;
184  while(tmp!=NULL){
185    if(strcasecmp(tmp->name,key)==0){
186      return tmp;
187    }
188    tmp=tmp->next;
189  }
190  return NULL;
191}
192
193
194/**
195 * Access the last map
196 *
197 * @param m the map to search for the lastest map
198 * @return a pointer on the lastest map found or NULL if not found
199 */
200map* getLastMap(map* m){
201  map* tmp=m;
202  while(tmp!=NULL){
203    if(tmp->next==NULL){
204      return tmp;
205    }
206    tmp=tmp->next;
207  }
208  return NULL;
209}
210
211/**
212 * Access a specific map from a maps
213 *
214 * @param m the maps to search for the key
215 * @param key the key to search in the maps
216 * @param subkey the key to search in the map (found for the key, if any)
217 * @return a pointer on the map found or NULL if not found
218 */
219map* getMapFromMaps(maps* m,const char* key,const char* subkey){
220  maps* _tmpm=getMaps(m,key);
221  if(_tmpm!=NULL){
222    map* _ztmpm=getMap(_tmpm->content,subkey);
223    return _ztmpm;
224  }
225  else return NULL;
226}
227
228/**
229 * Free allocated memory of a map.
230 * Require to call free on mo after calling this function.
231 *
232 * @param mo the map to free
233 */
234void freeMap(map** mo){
235  map* _cursor=*mo;
236  if(_cursor!=NULL){
237#ifdef DEBUG
238    fprintf(stderr,"freeMap\n");
239#endif
240    free(_cursor->name);
241    free(_cursor->value);
242    if(_cursor->next!=NULL){
243      freeMap(&_cursor->next);
244      free(_cursor->next);
245    }
246  }
247}
248
249/**
250 * Free allocated memory of a maps.
251 * Require to call free on mo after calling this function.
252 *
253 * @param mo the maps to free
254 */
255void freeMaps(maps** mo){
256  maps* _cursor=*mo;
257  if(_cursor && _cursor!=NULL){
258#ifdef DEBUG
259    fprintf(stderr,"freeMaps\n");
260#endif
261    free(_cursor->name);
262    if(_cursor->content!=NULL){
263      freeMap(&_cursor->content);
264      free(_cursor->content);
265    }
266    if(_cursor->next!=NULL){
267      freeMaps(&_cursor->next);
268      free(_cursor->next);
269    }
270  }
271}
272
273/**
274 * Verify if an elements contains a name equal to the given key.
275 *
276 * @param e the elements to search for the key
277 * @param key the elements name to search
278 * @return true if the elements contains the name, false in other cases.
279 */ 
280bool hasElement(elements* e,const char* key){
281  elements* tmp=e;
282  while(tmp!=NULL){
283    if(strcasecmp(key,tmp->name)==0)
284      return true;
285    tmp=tmp->next;
286  }
287  return false;
288}
289
290/**
291 * Access a specific elements named key.
292 *
293 * @param m the elements to search
294 * @param key the elements name to search
295 * @return a pointer to the specific element if found, NULL in other case.
296 */ 
297elements* getElements(elements* m,char *key){
298  elements* tmp=m;
299  while(tmp!=NULL){
300    if(strcasecmp(tmp->name,key)==0)
301      return tmp;
302    tmp=tmp->next;
303  }
304  return NULL;
305}
306
307/**
308 * Free allocated memory of an iotype.
309 * Require to call free on i after calling this function.
310 *
311 * @param i the iotype to free
312 */
313void freeIOType(iotype** i){
314  iotype* _cursor=*i;
315  if(_cursor!=NULL){
316    if(_cursor->next!=NULL){
317      freeIOType(&_cursor->next);
318      free(_cursor->next);
319    }
320    freeMap(&_cursor->content);
321    free(_cursor->content);
322  }
323}
324
325/**
326 * Free allocated memory of an elements.
327 * Require to call free on e after calling this function.
328 *
329 * @param e the iotype to free
330 */
331void freeElements(elements** e){
332  elements* tmp=*e;
333  if(tmp!=NULL){
334    if(tmp->name!=NULL)
335      free(tmp->name);
336    freeMap(&tmp->content);
337    if(tmp->content!=NULL)
338      free(tmp->content);
339    freeMap(&tmp->metadata);
340    if(tmp->metadata!=NULL)
341      free(tmp->metadata);
342    if(tmp->format!=NULL)
343      free(tmp->format);
344    freeIOType(&tmp->defaults);
345    if(tmp->defaults!=NULL)
346      free(tmp->defaults);
347    freeIOType(&tmp->supported);
348    if(tmp->supported!=NULL){
349      free(tmp->supported);
350    }
351    freeElements(&tmp->next);
352    if(tmp->next!=NULL)
353      free(tmp->next);
354  }
355}
356
357/**
358 * Free allocated memory of a service.
359 * Require to call free on e after calling this function.
360 *
361 * @param s the service to free
362 */
363void freeService(service** s){
364  service* tmp=*s;
365  if(tmp!=NULL){
366    if(tmp->name!=NULL)
367      free(tmp->name);
368    freeMap(&tmp->content);
369    if(tmp->content!=NULL)
370      free(tmp->content);
371    freeMap(&tmp->metadata);
372    if(tmp->metadata!=NULL)
373      free(tmp->metadata);
374    freeElements(&tmp->inputs);
375    if(tmp->inputs!=NULL)
376      free(tmp->inputs);
377    freeElements(&tmp->outputs);
378    if(tmp->outputs!=NULL)
379      free(tmp->outputs);
380  }
381}
382
383/**
384 * Add key value pair to an existing map.
385 *
386 * @param m the map to add the KVP
387 * @param n the key to add
388 * @param v the corresponding value to add
389 */
390void addToMap(map* m,const char* n,const char* v){
391  if(hasKey(m,n)==false){
392    map* _cursor=m;
393    while(_cursor->next!=NULL){
394      _cursor=_cursor->next;
395    }
396    _cursor->next=createMap(n,v);
397  }
398  else{
399    map *tmp=getMap(m,n);
400    if(tmp->value!=NULL)
401      free(tmp->value);
402    tmp->value=zStrdup(v);
403  }
404}
405
406/**
407 * Add a key and an integer value to an existing map.
408 *
409 * @param m the map to add the KVP
410 * @param n the key to add
411 * @param v the corresponding value to add
412 */
413void addIntToMap(map* m,const char* n,const int v){
414  char svalue[10];
415  sprintf(svalue,"%d",v);
416  if(hasKey(m,n)==false){
417    map* _cursor=m;
418    while(_cursor->next!=NULL){
419      _cursor=_cursor->next;
420    }
421    _cursor->next=createMap(n,svalue);
422  }
423  else{
424    map *tmp=getMap(m,n);
425    if(tmp->value!=NULL)
426      free(tmp->value);
427    tmp->value=zStrdup(svalue);
428  }
429}
430
431/**
432 * Add a key and a binary value to an existing map.
433 *
434 * @param m the map to add the KVP
435 * @param n the key to add
436 * @param v the corresponding value to add
437 * @param size the size of the given value
438 */
439void addToMapWithSize(map* m,const char* n,const char* v,int size){
440  if(hasKey(m,n)==false){
441    map* _cursor=m;
442    if(_cursor!=NULL){
443      addToMap(m,n,"");
444    }else{
445      m=createMap(n,"");
446    }
447  }
448  char sname[10]="size";
449  if(strlen(n)>5)
450    sprintf(sname,"size_%s",n+6);
451  map *tmp=getMap(m,n);
452  if(tmp->value!=NULL)
453    free(tmp->value);
454  tmp->value=(char*)malloc((size+1)*sizeof(char));
455  memmove(tmp->value,v,size*sizeof(char));
456  tmp->value[size]=0;
457  char sin[128];
458  sprintf(sin,"%d",size);
459  addToMap(m,sname,sin);
460}
461
462/**
463 * Add a map at the end of another map.
464 *
465 * @param mo the map to add mi
466 * @param mi the map to add to mo
467 */
468void addMapToMap(map** mo,map* mi){
469  map* tmp=mi;
470  map* _cursor=*mo;
471  while(tmp!=NULL){
472    if(_cursor==NULL){
473      *mo=createMap(tmp->name,tmp->value);
474      (*mo)->next=NULL;
475    }
476    else{
477#ifdef DEBUG
478      fprintf(stderr,"_CURSOR\n");
479      dumpMap(_cursor);
480#endif
481      while(_cursor->next!=NULL)
482        _cursor=_cursor->next;
483      map* tmp1=getMap(*mo,tmp->name);
484      if(tmp1==NULL){
485        _cursor->next=createMap(tmp->name,tmp->value);
486      }
487      else{
488        addToMap(*mo,tmp->name,tmp->value);
489      }
490    }
491    _cursor=*mo;
492    tmp=tmp->next;
493#ifdef DEBUG
494    fprintf(stderr,"MO\n");
495    dumpMap(*mo);
496#endif
497  }
498}
499
500/**
501 * Add a map to iotype.
502 *
503 * @param io the iotype to add the map
504 * @param mi the map to add to io
505 */
506void addMapToIoType(iotype** io,map* mi){
507  iotype* tmp=*io;
508  while(tmp->next!=NULL){
509    tmp=tmp->next;
510  }
511  tmp->next=(iotype*)malloc(IOTYPE_SIZE);
512  tmp->next->content=NULL;
513  addMapToMap(&tmp->next->content,mi);
514  tmp->next->next=NULL;
515}
516
517/**
518 * Access a specific map or set its value.
519 *
520 * @param m the map to search for the key
521 * @param key the key to search/add in the map
522 * @param value the value to add if the key does not exist
523 * @return a pointer on the map found or NULL if not found
524 */
525map* getMapOrFill(map** m,const char *key,const char* value){
526  map* tmp=*m;
527  map* tmpMap=getMap(tmp,key);
528  if(tmpMap==NULL){
529    if(tmp!=NULL){
530      addToMap((*m),key,value);
531    }
532    else
533      (*m)=createMap(key,value);
534    tmpMap=getMap(*m,key);
535  }
536  return tmpMap;
537}
538
539/**
540 * Verify if a map is contained in another map.
541 *
542 * @param m the map to search for i
543 * @param i the map to search in m
544 * @return true if i was found in m, false in other case
545 */
546bool contains(map* m,map* i){
547  while(i!=NULL){     
548    if(strcasecmp(i->name,"value")!=0 &&
549       strcasecmp(i->name,"xlink:href")!=0 &&
550       strcasecmp(i->name,"useMapServer")!=0 &&
551       strcasecmp(i->name,"asReference")!=0){
552      map *tmp;
553      if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL && 
554         strcasecmp(i->value,tmp->value)!=0)
555        return false;
556    }
557    i=i->next;
558  }
559  return true;
560}
561
562/**
563 * Access a specific iotype from an elements.
564 *
565 * @param e the elements to search for the name
566 * @param name the name to search in the elements e
567 * @param values the map to verify it was contained in the defaults or
568 *  supported content of the elements e
569 * @return a pointer on the iotype found or NULL if not found
570 */
571iotype* getIoTypeFromElement(elements* e,char *name, map* values){
572  elements* cursor=e;
573  while(cursor!=NULL){
574    if(strcasecmp(cursor->name,name)==0){
575      if(contains(cursor->defaults->content,values)==true)
576        return cursor->defaults;
577      else{
578        iotype* tmp=cursor->supported;
579        while(tmp!=NULL){
580          if(contains(tmp->content,values)==true)
581            return tmp;     
582          tmp=tmp->next;
583        }
584      }
585    }
586    cursor=cursor->next;
587  }
588  return NULL;
589}
590
591/**
592 * Load binary values from a map (in) and add them to another map (out)
593 *
594 * @param out the map to add binaries values
595 * @param in the map containing the binary values to add ti out
596 * @param pos index of the binary in an array (in case of "MapArray")
597 */
598void loadMapBinary(map** out,map* in,int pos){
599  map* size=getMap(in,"size");
600  map *lout=*out;
601  if(size!=NULL && pos>0){
602    char tmp[11];
603    sprintf(tmp,"size_%d",pos);
604    size=getMap(in,tmp);
605    sprintf(tmp,"value_%d",pos);
606    map* tmpVin=getMap(in,tmp);
607    map* tmpVout=getMap(lout,tmp);
608    free(tmpVout->value);
609    tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
610    memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
611    tmpVout->value[atoi(size->value)]=0;
612  }else{
613    if(size!=NULL){
614      map* tmpVin=getMap(in,"value");
615      map* tmpVout=getMap(lout,"value");
616      free(tmpVout->value);
617      tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
618      memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
619      tmpVout->value[atoi(size->value)]=0;
620    }
621  }
622}
623 
624/**
625 * Load binary values from a map (in) and add them to another map (out).
626 * This function will take care of MapArray.
627 * @see loadMapBinary
628 *
629 * @param out the map to add binaries values
630 * @param in the map containing the binary values to add ti out
631 */
632void loadMapBinaries(map** out,map* in){
633  map* size=getMap(in,"size");
634  map* length=getMap(in,"length");
635  if(length!=NULL){
636    int len=atoi(length->value);
637    int i=0;
638    for(i=0;i<len;i++){
639      loadMapBinary(out,in,i);
640    }
641  }
642  else
643    if(size!=NULL)
644      loadMapBinary(out,in,-1);
645}
646
647/**
648 * Duplicate a Maps
649 *
650 * @param mo the maps to clone
651 * @return the allocated maps containing a copy of the mo maps
652 */
653maps* dupMaps(maps** mo){
654  maps* _cursor=*mo;
655  maps* res=NULL;
656  if(_cursor!=NULL){
657    res=(maps*)malloc(MAPS_SIZE);
658    res->name=zStrdup(_cursor->name);
659    res->content=NULL;
660    res->next=NULL;
661    map* mc=_cursor->content;
662    if(mc!=NULL){
663      addMapToMap(&res->content,mc);
664      loadMapBinaries(&res->content,mc);
665    }
666    res->next=dupMaps(&_cursor->next);
667  }
668  return res;
669}
670
671/**
672 * Add a maps at the end of another maps.
673 *
674 * @see addMapToMap, dupMaps, getMaps
675 * @param mo the maps to add mi
676 * @param mi the maps to add to mo
677 */
678void addMapsToMaps(maps** mo,maps* mi){
679  maps* tmp=mi;
680  maps* _cursor=*mo;
681  while(tmp!=NULL){
682    if(_cursor==NULL){
683      *mo=dupMaps(&mi);
684    }
685    else{
686      while(_cursor->next!=NULL)
687        _cursor=_cursor->next;
688      maps* tmp1=getMaps(*mo,tmp->name);
689      if(tmp1==NULL)
690        _cursor->next=dupMaps(&tmp);
691      else
692        addMapToMap(&tmp1->content,tmp->content);
693      _cursor=*mo;
694    }
695    tmp=tmp->next;
696  }
697}
698
699/**
700 * Access a specific map array element
701 *
702 * @param m the map to search for the key
703 * @param key the key to search in the map
704 * @param index of the MapArray
705 * @return a pointer on the map found or NULL if not found
706 */
707map* getMapArray(map* m,const char* key,int index){
708  char tmp[1024];
709  if(index>0)
710    sprintf(tmp,"%s_%d",key,index);
711  else
712    sprintf(tmp,"%s",key);
713#ifdef DEBUG
714  fprintf(stderr,"** KEY %s\n",tmp);
715#endif
716  map* tmpMap=getMap(m,tmp);
717#ifdef DEBUG
718  if(tmpMap!=NULL)
719    dumpMap(tmpMap);
720#endif
721  return tmpMap;
722}
723
724/**
725 * Add a key value in a MapArray for a specific index
726 *
727 * @param m the map to search for the key
728 * @param key the key to search in the map
729 * @param index the index of the MapArray
730 * @param value the value to set in the MapArray
731 * @return a pointer on the map found or NULL if not found
732 */
733void setMapArray(map* m,const char* key,int index,const char* value){
734  char tmp[1024];
735  if(index>0){
736    sprintf(tmp,"%s_%d",key,index);
737    map* len=getMap(m,"length");
738    if((len!=NULL && atoi(len->value)<index+1) || len==NULL){
739      char tmp0[5];
740      sprintf(tmp0,"%d",index+1);
741      addToMap(m,"length",tmp0);
742    }
743  }
744  else
745    sprintf(tmp,"%s",key);
746  map* tmpSize=getMapArray(m,"size",index);
747  if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
748#ifdef DEBUG
749    fprintf(stderr,"%s\n",tmpSize->value);
750#endif
751    map* ptr=getMapOrFill(&m,tmp,(char *)"");
752    free(ptr->value);
753    ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
754    memcpy(ptr->value,value,atoi(tmpSize->value)); 
755  }
756  else
757    addToMap(m,tmp,value);
758}
759
760/**
761 * Access the map "type"
762 *
763 * @param mt the map
764 * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
765 *  other case
766 */
767map* getMapType(map* mt){
768  map* tmap=getMap(mt,(char *)"mimeType");
769  if(tmap==NULL){
770    tmap=getMap(mt,"dataType");
771    if(tmap==NULL){
772      tmap=getMap(mt,"CRS");
773    }
774  }
775#ifdef DEBUG
776  dumpMap(tmap);
777#endif
778  return tmap;
779}
780
781/**
782 * Add a Maps containing a MapArray to a Maps
783 *
784 * @see getMapType
785 * @param mo the maps
786 * @param mi the maps
787 * @param typ the map "type"
788 * @return
789 */
790int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
791  maps* tmp=mi;   
792  maps* _cursor=getMaps(*mo,tmp->name);
793
794  if(_cursor==NULL)
795    return -1;
796
797  map* tmpLength=getMap(_cursor->content,"length");
798  char tmpLen[10];
799  int len=1;
800  if(tmpLength!=NULL){
801    len=atoi(tmpLength->value);
802  }
803
804  char *tmpV[12]={
805    (char*)"size",
806    (char*)"value",
807    (char*)"uom",
808    (char*)"Reference",
809    (char*)"Order",
810    (char*)"cache_file",
811    (char*)"fmimeType",
812    (char*)"xlink:href",
813    typ,
814    (char*)"schema",
815    (char*)"encoding",
816    (char*)"isCached"
817  };
818  sprintf(tmpLen,"%d",len+1);
819  addToMap(_cursor->content,"length",tmpLen);
820  int i=0;
821  for(i=0;i<12;i++){
822    map* tmpVI=getMap(tmp->content,tmpV[i]);
823    if(tmpVI!=NULL){
824#ifdef DEBUG
825      fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
826#endif
827      setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
828    }
829  }
830   
831  addToMap(_cursor->content,"isArray","true");
832  return 0;
833}
834
835/**
836 * Set a key value pair to a map contained in a Maps
837 *
838 * @param m the maps
839 * @param key the maps name
840 * @param subkey the map name included in the maps corresponding to key
841 * @param value the corresponding value to add in the map
842 */
843void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
844  maps* _tmpm=getMaps(m,key);
845  if(_tmpm!=NULL){
846    map* _ztmpm=getMap(_tmpm->content,subkey);
847    if(_ztmpm!=NULL){
848      if(_ztmpm->value!=NULL)
849        free(_ztmpm->value);
850      _ztmpm->value=zStrdup(value);
851    }else{
852      maps *tmp=(maps*)malloc(MAPS_SIZE);
853      tmp->name=zStrdup(key);
854      tmp->content=createMap(subkey,value);
855      tmp->next=NULL;
856      addMapsToMaps(&_tmpm,tmp);
857      freeMaps(&tmp);
858      free(tmp);
859    }
860  }else{
861    maps *tmp=(maps*)malloc(MAPS_SIZE);
862    tmp->name=zStrdup(key);
863    tmp->content=createMap(subkey,value);
864    tmp->next=NULL;
865    addMapsToMaps(&m,tmp);
866    freeMaps(&tmp);
867    free(tmp);
868  }
869}
870
871/**
872 * Dump an elements on stderr
873 *
874 * @param e the elements to dump
875 */
876void dumpElements(elements* e){
877  elements* tmp=e;
878  while(tmp!=NULL){
879    fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
880    fprintf(stderr," > CONTENT [%s]\n",tmp->name);
881    dumpMap(tmp->content);
882    fprintf(stderr," > METADATA [%s]\n",tmp->name);
883    dumpMap(tmp->metadata);
884    fprintf(stderr," > FORMAT [%s]\n",tmp->format);
885    iotype* tmpio=tmp->defaults;
886    int ioc=0;
887    while(tmpio!=NULL){
888      fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
889      dumpMap(tmpio->content);
890      tmpio=tmpio->next;
891      ioc++;
892    }
893    tmpio=tmp->supported;
894    ioc=0;
895    while(tmpio!=NULL){
896      fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
897      dumpMap(tmpio->content);
898      tmpio=tmpio->next;
899      ioc++;
900    }
901    fprintf(stderr,"------------------\n");
902    tmp=tmp->next;
903  }
904}
905
906/**
907 * Dump an elements on stderr using the YAML syntaxe
908 *
909 * @param e the elements to dump
910 */
911void dumpElementsAsYAML(elements* e){
912  elements* tmp=e;
913  int i;
914  while(tmp!=NULL){
915    for(i=0;i<2;i++)
916      fprintf(stderr," ");
917    fprintf(stderr,"%s:\n",tmp->name);
918    map* mcurs=tmp->content;
919    while(mcurs!=NULL){
920      for(i=0;i<4;i++)
921        fprintf(stderr," ");
922      _dumpMap(mcurs);
923      mcurs=mcurs->next;
924    }
925    mcurs=tmp->metadata;
926    if(mcurs!=NULL){
927      for(i=0;i<4;i++)
928        fprintf(stderr," ");
929      fprintf(stderr,"MetaData:\n");
930      while(mcurs!=NULL){
931        for(i=0;i<6;i++)
932          fprintf(stderr," ");
933        _dumpMap(mcurs);
934        mcurs=mcurs->next;
935      }
936    }
937    for(i=0;i<4;i++)
938      fprintf(stderr," ");
939    fprintf(stderr,"%s:\n",tmp->format);
940    iotype* tmpio=tmp->defaults;
941    int ioc=0;
942    while(tmpio!=NULL){
943      for(i=0;i<6;i++)
944        fprintf(stderr," ");
945      fprintf(stderr,"default:\n");
946      mcurs=tmpio->content;
947      while(mcurs!=NULL){
948        for(i=0;i<8;i++)
949          fprintf(stderr," ");
950        if(strcasecmp(mcurs->name,"range")==0){
951          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
952        }else
953          _dumpMap(mcurs);
954        mcurs=mcurs->next;
955      }
956      tmpio=tmpio->next;
957      ioc++;
958    }
959    tmpio=tmp->supported;
960    ioc=0;
961    while(tmpio!=NULL){
962      for(i=0;i<6;i++)
963        fprintf(stderr," ");
964      fprintf(stderr,"supported:\n");
965      mcurs=tmpio->content;
966      while(mcurs!=NULL){
967        for(i=0;i<8;i++)
968          fprintf(stderr," ");
969        if(strcasecmp(mcurs->name,"range")==0){
970          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
971        }else
972          _dumpMap(mcurs);
973        mcurs=mcurs->next;
974      }
975      tmpio=tmpio->next;
976      ioc++;
977    }
978    tmp=tmp->next;
979  }
980}
981
982/**
983 * Duplicate an elements
984 *
985 * @param e the elements to clone
986 * @return the allocated elements containing a copy of the elements e
987 */
988elements* dupElements(elements* e){
989  elements* cursor=e;
990  elements* tmp=NULL;
991  if(cursor!=NULL){
992#ifdef DEBUG
993    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
994    dumpElements(e);
995    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
996#endif
997    tmp=(elements*)malloc(ELEMENTS_SIZE);
998    tmp->name=zStrdup(e->name);
999    tmp->content=NULL;
1000    addMapToMap(&tmp->content,e->content);
1001    tmp->metadata=NULL;
1002    addMapToMap(&tmp->metadata,e->metadata);
1003    if(e->format!=NULL)
1004      tmp->format=zStrdup(e->format);
1005    else
1006      tmp->format=NULL;
1007    if(e->defaults!=NULL){
1008      tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
1009      tmp->defaults->content=NULL;
1010      addMapToMap(&tmp->defaults->content,e->defaults->content);
1011      tmp->defaults->next=NULL;
1012#ifdef DEBUG
1013      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1014      dumpMap(tmp->defaults->content);
1015#endif
1016    }else
1017      tmp->defaults=NULL;
1018    if(e->supported!=NULL){
1019      tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
1020      tmp->supported->content=NULL;
1021      addMapToMap(&tmp->supported->content,e->supported->content);
1022      tmp->supported->next=NULL;
1023      iotype *tmp2=e->supported->next;
1024      while(tmp2!=NULL){
1025        addMapToIoType(&tmp->supported,tmp2->content);
1026#ifdef DEBUG
1027        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1028        dumpMap(tmp->defaults->content);
1029#endif
1030        tmp2=tmp2->next;
1031      }
1032    }
1033    else
1034      tmp->supported=NULL;
1035    tmp->next=dupElements(cursor->next);
1036  }
1037  return tmp;
1038}
1039
1040/**
1041 * Add an elements to another elements.
1042 *
1043 * @see dupElements
1044 * @param m the elements to add the e
1045 * @param e the elements to be added to m
1046 */
1047void addToElements(elements** m,elements* e){
1048  elements* tmp=e;
1049  if(*m==NULL){
1050    *m=dupElements(tmp);
1051  }else{
1052    addToElements(&(*m)->next,tmp);
1053  }
1054}
1055 
1056/**
1057 * Dump a service on stderr
1058 *
1059 * @param s the service to dump
1060 */
1061void dumpService(service* s){
1062  if(s==NULL)
1063    return;
1064  fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
1065  if(s->content!=NULL){
1066    fprintf(stderr,"CONTENT MAP\n");
1067    dumpMap(s->content);
1068    fprintf(stderr,"CONTENT METADATA\n");
1069    dumpMap(s->metadata);
1070  }
1071  if(s->inputs!=NULL){
1072    fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
1073    dumpElements(s->inputs);
1074  }
1075  if(s->outputs!=NULL){
1076    fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
1077    dumpElements(s->outputs);
1078  }
1079  fprintf(stderr,"++++++++++++++++++\n");
1080}
1081
1082/**
1083 * Dump a service on stderr using the YAML syntaxe
1084 *
1085 * @param s the service to dump
1086 */
1087void dumpServiceAsYAML(service* s){
1088  int i;
1089  fprintf(stderr,"# %s\n\n",s->name);
1090  if(s->content!=NULL){
1091    map* mcurs=s->content;
1092    dumpMap(mcurs);
1093    mcurs=s->metadata;
1094    if(mcurs!=NULL){
1095      fprintf(stderr,"MetaData:\n");
1096      while(mcurs!=NULL){
1097        for(i=0;i<2;i++)
1098          fprintf(stderr," ");
1099        _dumpMap(mcurs);
1100        mcurs=mcurs->next;
1101      }
1102    }
1103  }
1104  if(s->inputs!=NULL){
1105    fprintf(stderr,"\ninputs:\n");
1106    dumpElementsAsYAML(s->inputs);
1107  }
1108  if(s->outputs!=NULL){
1109    fprintf(stderr,"\noutputs:\n");
1110    dumpElementsAsYAML(s->outputs);
1111  }
1112}
1113
1114/**
1115 * Duplicate a service
1116 *
1117 * @param s the service to clone
1118 * @return the allocated service containing a copy of the serfvice s
1119 */
1120service* dupService(service* s){
1121  service *res=(service*)malloc(SERVICE_SIZE);
1122  res->name=zStrdup(s->name);
1123  res->content=NULL;
1124  addMapToMap(&res->content,s->content);
1125  res->metadata=NULL;
1126  addMapToMap(&res->metadata,s->metadata);
1127  res->inputs=dupElements(s->inputs);
1128  res->outputs=dupElements(s->outputs);
1129  return res;
1130}
1131
1132/**
1133 * Print the registry on stderr.
1134 *
1135 * @param r the registry
1136 */
1137void dumpRegistry(registry* r){
1138  registry* p=r;
1139  while(p!=NULL){
1140    fprintf(stderr,"%s \n",p->name);
1141    services* s=p->content;
1142    s=p->content;
1143    while(s!=NULL){
1144      dumpService(s->content);
1145      s=s->next;
1146    }
1147    p=p->next;
1148  }
1149}
1150
1151/**
1152 * Add a service to the registry
1153 *
1154 * @param reg the resgitry to add the service
1155 * @param name the registry name to update
1156 * @param content the service to add
1157 */
1158bool addServiceToRegistry(registry** reg,char* name,service* content){
1159  registry *l=*reg;
1160  int isInitial=-1;
1161  if(l==NULL){
1162    l=(registry*)malloc(REGISTRY_SIZE);
1163    isInitial=1;
1164  }
1165  if(l!=NULL){
1166    int hasLevel=-1;
1167    while(isInitial<0 && l!=NULL){
1168      if(l->name!=NULL && strcasecmp(name,l->name)==0){
1169        hasLevel=1;
1170        break;
1171      }
1172      l=l->next;
1173    }
1174    if(hasLevel<0){
1175      if(isInitial<0)
1176        l=(registry*)malloc(REGISTRY_SIZE);
1177      l->name=zStrdup(name);
1178      l->content=NULL;
1179      l->next=NULL;
1180    }
1181    if(l->content==NULL){
1182      l->content=(services*)malloc(SERVICES_SIZE);
1183      l->content->content=dupService(content);
1184      l->content->next=NULL;
1185    }
1186    else{
1187      services* s=l->content;
1188      while(s->next!=NULL)
1189        s=s->next;
1190      s->next=(services*)malloc(SERVICES_SIZE);
1191      s->next->content=dupService(content);
1192      s->next->next=NULL;
1193    }
1194    l->next=NULL;
1195    if(isInitial>0)
1196      *reg=l;
1197    else{
1198      registry *r=*reg;
1199      while(r->next!=NULL)
1200        r=r->next;
1201      r->next=l;
1202      r->next->next=NULL;
1203    }
1204    return true;
1205  }
1206  else
1207    return false;
1208}
1209
1210/**
1211 * Free memory allocated for the registry
1212 *
1213 * @param r the registry
1214 */
1215void freeRegistry(registry** r){
1216  registry* lr=*r;
1217  while(lr!=NULL){
1218    services* s=lr->content;
1219    free(lr->name);
1220    while(s!=NULL){
1221      service* s1=s->content;
1222      s=s->next;
1223      if(s1!=NULL){
1224        freeService(&s1);
1225        free(s1);
1226        s1=NULL;
1227      }
1228    }
1229    lr=lr->next;
1230  }   
1231}
1232
1233/**
1234 * Access a service in the registry
1235 *
1236 * @param r the registry
1237 * @param level the regitry to search ("concept", "generic" or "implementation")
1238 * @param sname the service name
1239 * @return the service pointer if a corresponding service was found or NULL
1240 */
1241service* getServiceFromRegistry(registry* r,char  *level,char* sname){
1242  registry *lr=r;
1243  while(lr!=NULL){
1244    if(strcasecmp(lr->name,level)==0){
1245      services* s=lr->content;
1246      while(s!=NULL){
1247        if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
1248          return s->content;
1249        s=s->next;
1250      }
1251      break;
1252    }
1253    lr=lr->next;
1254  }
1255  return NULL;
1256}
1257
1258/**
1259 * Apply inheritance to an out map from a reference in map
1260 *
1261 * @param out the map to update
1262 * @param in the reference map (containing inherited properties)
1263 */
1264void inheritMap(map** out,map* in){
1265  map* content=in;
1266  if((*out)==NULL){
1267    addMapToMap(out,in);
1268    return;
1269  }
1270  while(content!=NULL){
1271    map* cmap=getMap(*out,content->name);
1272    if(cmap==NULL)
1273      addToMap(*out,content->name,content->value);
1274    content=content->next;
1275  }
1276}
1277
1278/**
1279 * Apply inheritance to an out iotype from a reference in iotype
1280 *
1281 * @param out the iotype to update
1282 * @param in the reference iotype (containing inherited properties)
1283 */
1284void inheritIOType(iotype** out,iotype* in){
1285  iotype* io=in;
1286  iotype* oio=*out;
1287  if(io!=NULL){
1288    if(*out==NULL){
1289      *out=(iotype*)malloc(IOTYPE_SIZE);
1290      (*out)->content=NULL;
1291      addMapToMap(&(*out)->content,io->content);
1292      (*out)->next=NULL;
1293      oio=*out;
1294      inheritIOType(&oio->next,io->next);
1295    }else{
1296      inheritIOType(&oio->next,io->next);
1297    }
1298  }
1299}
1300
1301/**
1302 * Apply inheritance to an out elements from a reference in elements
1303 *
1304 * @param out the elements to update
1305 * @param in the reference elements (containing inherited properties)
1306 */
1307void inheritElements(elements** out,elements* in){
1308  elements* content=in;
1309  while(content!=NULL && *out!=NULL){
1310    elements* cmap=getElements(*out,content->name);
1311    if(cmap==NULL)
1312      addToElements(out,content);
1313    else{
1314      inheritMap(&cmap->content,content->content);
1315      inheritMap(&cmap->metadata,content->metadata);
1316      if(cmap->format==NULL && content->format!=NULL)
1317        cmap->format=zStrdup(content->format);
1318      inheritIOType(&cmap->defaults,content->defaults);
1319      if(cmap->supported==NULL)
1320        inheritIOType(&cmap->supported,content->supported);
1321      else{
1322        iotype* p=content->supported;
1323        while(p!=NULL){
1324          addMapToIoType(&cmap->supported,p->content);
1325          p=p->next;
1326        }
1327      }
1328    }
1329    content=content->next;
1330  }
1331}
1332
1333/**
1334 * Apply inheritance to a service based on a registry
1335 *
1336 * @param r the registry storing profiles hierarchy
1337 * @param s the service to update depending on its inheritance
1338 */
1339void inheritance(registry *r,service** s){
1340  if(r==NULL)
1341    return;
1342  service* ls=*s;
1343  if(ls->content==NULL)
1344    return;
1345  map* profile=getMap(ls->content,"extend");
1346  map* level=getMap(ls->content,"level");
1347  if(profile!=NULL&&level!=NULL){
1348    service* s1;
1349    if(strncasecmp(level->value,"profile",7)==0)
1350      s1=getServiceFromRegistry(r,(char*)"generic",profile->value);
1351    else
1352      s1=getServiceFromRegistry(r,level->value,profile->value);
1353     
1354    inheritMap(&ls->content,s1->content);
1355    inheritMap(&ls->metadata,s1->metadata);
1356    if(ls->inputs==NULL && s1->inputs!=NULL){
1357      ls->inputs=dupElements(s1->inputs);
1358    }else{
1359      inheritElements(&ls->inputs,s1->inputs);
1360    }
1361    if(ls->outputs==NULL && s1->outputs!=NULL){
1362      ls->outputs=dupElements(s1->outputs);
1363    }else
1364      inheritElements(&ls->outputs,s1->outputs);
1365  }
1366}
1367
1368/**
1369 * Convert a maps to a char*** (only used for Fortran support)
1370 *
1371 * @param m the maps to convert
1372 * @param c the resulting array
1373 */
1374void mapsToCharXXX(maps* m,char*** c){
1375  maps* tm=m;
1376  int i=0;
1377  int j=0;
1378  char tmp[10][30][1024];
1379  memset(tmp,0,1024*10*10);
1380  while(tm!=NULL){
1381    if(i>=10)
1382      break;
1383    strcpy(tmp[i][j],"name");
1384    j++;
1385    strcpy(tmp[i][j],tm->name);
1386    j++;
1387    map* tc=tm->content;
1388    while(tc!=NULL){
1389      if(j>=30)
1390        break;
1391      strcpy(tmp[i][j],tc->name);
1392      j++;
1393      strcpy(tmp[i][j],tc->value);
1394      j++;
1395      tc=tc->next;
1396    }
1397    tm=tm->next;
1398    j=0;
1399    i++;
1400  }
1401  memcpy(c,tmp,10*10*1024);
1402}
1403
1404/**
1405 * Convert a char*** to a maps (only used for Fortran support)
1406 *
1407 * @param c the array to convert
1408 * @param m the resulting maps
1409 */
1410void charxxxToMaps(char*** c,maps**m){
1411  maps* trorf=*m;
1412  int i,j;
1413  char tmp[10][30][1024];
1414  memcpy(tmp,c,10*30*1024);
1415  for(i=0;i<10;i++){
1416    if(strlen(tmp[i][1])==0)
1417      break;
1418    trorf->name=tmp[i][1];
1419    trorf->content=NULL;
1420    trorf->next=NULL;
1421    for(j=2;j<29;j+=2){
1422      if(strlen(tmp[i][j+1])==0)
1423        break;
1424      if(trorf->content==NULL)
1425        trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
1426      else
1427        addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
1428    }
1429    trorf=trorf->next;
1430  }
1431  m=&trorf;
1432}
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