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

Last change on this file since 839 was 839, checked in by djay, 7 years ago

Update the source code for HPC support. Automatically adding nested outputs for the HPC support (should this be available for every support?). Add capability to store the metadata in the Collection DataBase?. Addition of the zcfg2sql to import any existing ZCFG file into the Collection DB. Add the support to invoke a callback (for history purpose) in case a [callback] section contains at least one parameter defined (url). Add support to convert maps and map to JSON (for callback use only by now). Fix some memory leaks (some are still there).

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