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

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

Use curl_multi_wait only in case libcurl minor version number is upper or equal to 28.

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