source: branches/prototype-v0/zoo-project/zoo-kernel/service.c @ 881

Last change on this file since 881 was 881, checked in by djay, 6 years ago

Make sure to initialize properly every field of a service.

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