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

Last change on this file since 653 was 652, checked in by djay, 10 years ago

Better concurrency gesture for asynchronous requests, add db backend support for status informations.

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