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

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

Add status_code key to the lenv section to support returning a specific HTTP error code from the service code. Fix callback invocation to support inputs arrays at step 1 and 2. Fix issue with cpu usage. Fix issue with mapserver publication when an input is optional. Fix callback invocation at step 7 in case the service has failed on the HPC side.

  • Property svn:keywords set to Id
File size: 37.7 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2015 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service.h"
26
27
28#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[12]={
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  };
941  sprintf(tmpLen,"%d",len+1);
942  addToMap(_cursor->content,"length",tmpLen);
943  int i=0;
944  for(i=0;i<12;i++){
945    map* tmpVI=getMap(tmp->content,tmpV[i]);
946    if(tmpVI!=NULL){
947#ifdef DEBUG
948      fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
949#endif
950      setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
951    }
952  }
953   
954  addToMap(_cursor->content,"isArray","true");
955  return 0;
956}
957
958/**
959 * Set a key value pair to a map contained in a Maps
960 *
961 * @param m the maps
962 * @param key the maps name
963 * @param subkey the map name included in the maps corresponding to key
964 * @param value the corresponding value to add in the map
965 */
966void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
967  maps* _tmpm=getMaps(m,key);
968  if(_tmpm!=NULL){
969    map* _ztmpm=getMap(_tmpm->content,subkey);
970    if(_ztmpm!=NULL){
971      if(_ztmpm->value!=NULL)
972        free(_ztmpm->value);
973      _ztmpm->value=zStrdup(value);
974    }else{
975      maps *tmp=createMaps(key);
976      tmp->content=createMap(subkey,value);
977      addMapsToMaps(&_tmpm,tmp);
978      freeMaps(&tmp);
979      free(tmp);
980    }
981  }else{
982    maps *tmp=createMaps(key);
983    tmp->content=createMap(subkey,value);
984    addMapsToMaps(&m,tmp);
985    freeMaps(&tmp);
986    free(tmp);
987  }
988}
989
990/**
991 * Create an empty elements
992 *
993 * @return a pointer to the allocated elements
994 */
995elements* createEmptyElements(){
996  elements* res=(elements*)malloc(ELEMENTS_SIZE);
997  res->name=NULL;
998  res->content=NULL;
999  res->metadata=NULL;
1000  res->additional_parameters=NULL; 
1001  res->format=NULL;
1002  res->defaults=NULL;
1003  res->supported=NULL;
1004  res->child=NULL;
1005  res->next=NULL;
1006  return res;
1007}
1008
1009/**
1010 * Create a named elements
1011 *
1012 * @param name the elements name
1013 * @return a pointer to the allocated elements
1014 */
1015elements* createElements(const char* name){
1016  elements* res=(elements*)malloc(ELEMENTS_SIZE);
1017  res->name=zStrdup(name);
1018  res->content=NULL;
1019  res->metadata=NULL;
1020  res->additional_parameters=NULL;
1021  res->format=NULL;
1022  res->defaults=NULL;
1023  res->supported=NULL;
1024  res->child=NULL;
1025  res->next=NULL;
1026  return res;
1027}
1028
1029/**
1030 * Set the name of an elements
1031 *
1032 * @param name the elements name
1033 * @return a pointer to the allocated elements
1034 */
1035void setElementsName(elements** elem,char* name){
1036  elements* res=*elem;
1037  res->name=zStrdup(name);
1038  res->content=NULL;
1039  res->metadata=NULL;
1040  res->format=NULL;
1041  res->defaults=NULL;
1042  res->supported=NULL;
1043  res->child=NULL;
1044  res->next=NULL;
1045}
1046
1047/**
1048 * Dump an elements on stderr
1049 *
1050 * @param e the elements to dump
1051 */
1052void dumpElements(elements* e){
1053  elements* tmp=e;
1054  while(tmp!=NULL){
1055    fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
1056    fprintf(stderr," > CONTENT [%s]\n",tmp->name);
1057    dumpMap(tmp->content);
1058    fprintf(stderr," > METADATA [%s]\n",tmp->name);
1059    dumpMap(tmp->metadata);
1060    fprintf(stderr," > ADDITIONAL PARAMETERS [%s]\n",tmp->name);
1061    dumpMap(tmp->additional_parameters);
1062    fprintf(stderr," > FORMAT [%s]\n",tmp->format);
1063    iotype* tmpio=tmp->defaults;
1064    int ioc=0;
1065    while(tmpio!=NULL){
1066      fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
1067      dumpMap(tmpio->content);
1068      tmpio=tmpio->next;
1069      ioc++;
1070    }
1071    tmpio=tmp->supported;
1072    ioc=0;
1073    while(tmpio!=NULL){
1074      fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
1075      dumpMap(tmpio->content);
1076      tmpio=tmpio->next;
1077      ioc++;
1078    }
1079    if(tmp->child!=NULL){
1080      fprintf(stderr," > CHILD \n");
1081      dumpElements(tmp->child);
1082    }
1083    fprintf(stderr,"------------------\n");
1084    tmp=tmp->next;
1085  }
1086}
1087
1088/**
1089 * Dump an elements on stderr using the YAML syntaxe
1090 *
1091 * @param e the elements to dump
1092 */
1093void dumpElementsAsYAML(elements* e,int level){
1094  elements* tmp=e;
1095  int i;
1096  while(tmp!=NULL){
1097    for(i=0;i<2+(4*level);i++)
1098      fprintf(stderr," ");
1099    fprintf(stderr,"%s:\n",tmp->name);
1100    map* mcurs=tmp->content;
1101    while(mcurs!=NULL){
1102      for(i=0;i<4+(4*level);i++)
1103        fprintf(stderr," ");
1104      _dumpMap(mcurs);
1105      mcurs=mcurs->next;
1106    }
1107    mcurs=tmp->metadata;
1108    if(mcurs!=NULL){
1109      for(i=0;i<4+(4*level);i++)
1110        fprintf(stderr," ");
1111      fprintf(stderr,"MetaData:\n");
1112      while(mcurs!=NULL){
1113        for(i=0;i<6+(4*level);i++)
1114          fprintf(stderr," ");
1115        _dumpMap(mcurs);
1116        mcurs=mcurs->next;
1117      }
1118    }
1119    for(i=0;i<4+(4*level);i++)
1120      fprintf(stderr," ");
1121    if(tmp->format!=NULL)
1122      fprintf(stderr,"%s:\n",tmp->format);
1123    else{
1124      fprintf(stderr,"Child:\n");
1125      if(tmp->child!=NULL)
1126        dumpElementsAsYAML(tmp->child,level+1);
1127    }
1128    iotype* tmpio=tmp->defaults;
1129    int ioc=0;
1130    while(tmpio!=NULL){
1131      for(i=0;i<6+(4*level);i++)
1132        fprintf(stderr," ");
1133      fprintf(stderr,"default:\n");
1134      mcurs=tmpio->content;
1135      while(mcurs!=NULL){
1136        for(i=0;i<8+(4*level);i++)
1137          fprintf(stderr," ");
1138        if(strcasecmp(mcurs->name,"range")==0){
1139          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1140        }else
1141          _dumpMap(mcurs);
1142        mcurs=mcurs->next;
1143      }
1144      tmpio=tmpio->next;
1145      ioc++;
1146    }
1147    tmpio=tmp->supported;
1148    ioc=0;
1149    while(tmpio!=NULL){
1150      for(i=0;i<6+(4*level);i++)
1151        fprintf(stderr," ");
1152      fprintf(stderr,"supported:\n");
1153      mcurs=tmpio->content;
1154      while(mcurs!=NULL){
1155        for(i=0;i<8+(4*level);i++)
1156          fprintf(stderr," ");
1157        if(strcasecmp(mcurs->name,"range")==0){
1158          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1159        }else
1160          _dumpMap(mcurs);
1161        mcurs=mcurs->next;
1162      }
1163      tmpio=tmpio->next;
1164      ioc++;
1165    }
1166    tmp=tmp->next;
1167  }
1168}
1169
1170/**
1171 * Duplicate an elements
1172 *
1173 * @param e the elements to clone
1174 * @return the allocated elements containing a copy of the elements e
1175 */
1176elements* dupElements(elements* e){
1177  elements* cursor=e;
1178  elements* tmp=NULL;
1179  if(cursor!=NULL && cursor->name!=NULL){
1180#ifdef DEBUG
1181    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1182    dumpElements(e);
1183    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1184#endif
1185    tmp=(elements*)malloc(ELEMENTS_SIZE);
1186    tmp->name=zStrdup(cursor->name);
1187    tmp->content=NULL;
1188    addMapToMap(&tmp->content,cursor->content);
1189    tmp->metadata=NULL;
1190    addMapToMap(&tmp->metadata,cursor->metadata);
1191    tmp->additional_parameters=NULL;
1192    addMapToMap(&tmp->additional_parameters,cursor->additional_parameters);
1193    if(cursor->format!=NULL)
1194      tmp->format=zStrdup(cursor->format);
1195    else
1196      tmp->format=NULL;
1197    if(cursor->defaults!=NULL){
1198      tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
1199      tmp->defaults->content=NULL;
1200      addMapToMap(&tmp->defaults->content,cursor->defaults->content);
1201      tmp->defaults->next=NULL;
1202#ifdef DEBUG
1203      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1204      dumpMap(tmp->defaults->content);
1205#endif
1206    }else
1207      tmp->defaults=NULL;
1208    if(cursor->supported!=NULL && cursor->supported->content!=NULL){
1209      tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
1210      tmp->supported->content=NULL;
1211      addMapToMap(&tmp->supported->content,cursor->supported->content);
1212      tmp->supported->next=NULL;
1213      iotype *tmp2=cursor->supported->next;
1214      while(tmp2!=NULL){
1215        addMapToIoType(&tmp->supported,tmp2->content);
1216#ifdef DEBUG
1217        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1218        dumpMap(tmp->defaults->content);
1219#endif
1220        tmp2=tmp2->next;
1221      }
1222    }
1223    else
1224      tmp->supported=NULL;
1225    if(cursor->child!=NULL)
1226      tmp->child=dupElements(cursor->child);
1227    else
1228      tmp->child=NULL;
1229    if(cursor->next!=NULL)
1230      tmp->next=dupElements(cursor->next);
1231    else
1232      tmp->next=NULL;
1233  }
1234  return tmp;
1235}
1236
1237/**
1238 * Add an elements to another elements.
1239 *
1240 * @see dupElements
1241 * @param m the elements to add the e
1242 * @param e the elements to be added to m
1243 */
1244void addToElements(elements** m,elements* e){
1245  elements* tmp=e;
1246  if(*m==NULL){
1247    (*m)=dupElements(tmp);
1248  }else{
1249    addToElements(&(*m)->next,tmp);
1250  }
1251}
1252
1253/**
1254 * Set the name of a service
1255 *
1256 * @param name the service name
1257 */
1258void setServiceName(service** serv,char* name){
1259  service* res=*serv;
1260  res->name=zStrdup(name);
1261  res->content=NULL;
1262  res->metadata=NULL;
1263  res->inputs=NULL;
1264  res->outputs=NULL;
1265}
1266
1267/**
1268 * Dump a service on stderr
1269 *
1270 * @param s the service to dump
1271 */
1272void dumpService(service* s){
1273  if(s==NULL)
1274    return;
1275  fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
1276  if(s->content!=NULL){
1277    fprintf(stderr,"CONTENT MAP\n");
1278    dumpMap(s->content);
1279    if(s->metadata!=NULL)
1280      fprintf(stderr,"CONTENT METADATA\n");
1281    dumpMap(s->metadata);
1282    if(s->additional_parameters!=NULL)
1283      fprintf(stderr,"CONTENT AdditionalParameters\n");
1284    dumpMap(s->additional_parameters);
1285  }
1286  if(s->inputs!=NULL){
1287    fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
1288    dumpElements(s->inputs);
1289  }
1290  if(s->outputs!=NULL){
1291    fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
1292    dumpElements(s->outputs);
1293  }
1294  fprintf(stderr,"++++++++++++++++++\n");
1295}
1296
1297/**
1298 * Dump a service on stderr using the YAML syntaxe
1299 *
1300 * @param s the service to dump
1301 */
1302void dumpServiceAsYAML(service* s){
1303  int i;
1304  fprintf(stderr,"# %s\n\n",s->name);
1305  if(s->content!=NULL){
1306    map* mcurs=s->content;
1307    dumpMap(mcurs);
1308    mcurs=s->metadata;
1309    if(mcurs!=NULL){
1310      fprintf(stderr,"MetaData:\n");
1311      while(mcurs!=NULL){
1312        for(i=0;i<2;i++)
1313          fprintf(stderr," ");
1314        _dumpMap(mcurs);
1315        mcurs=mcurs->next;
1316      }
1317    }
1318  }
1319  if(s->inputs!=NULL){
1320    fprintf(stderr,"\ninputs:\n");
1321    dumpElementsAsYAML(s->inputs,0);
1322  }
1323  if(s->outputs!=NULL){
1324    fprintf(stderr,"\noutputs:\n");
1325    dumpElementsAsYAML(s->outputs,0);
1326  }
1327}
1328
1329/**
1330 * Duplicate a service
1331 *
1332 * @param s the service to clone
1333 * @return the allocated service containing a copy of the serfvice s
1334 */
1335service* dupService(service* s){
1336  service *res=(service*)malloc(SERVICE_SIZE);
1337  res->name=zStrdup(s->name);
1338  res->content=NULL;
1339  addMapToMap(&res->content,s->content);
1340  res->metadata=NULL;
1341  addMapToMap(&res->metadata,s->metadata);
1342  res->additional_parameters=NULL;
1343  addMapToMap(&res->additional_parameters,s->additional_parameters);
1344  res->inputs=dupElements(s->inputs);
1345  res->outputs=dupElements(s->outputs);
1346  return res;
1347}
1348
1349/**
1350 * Print the registry on stderr.
1351 *
1352 * @param r the registry
1353 */
1354void dumpRegistry(registry* r){
1355  registry* p=r;
1356  while(p!=NULL){
1357    fprintf(stderr,"%s \n",p->name);
1358    services* s=p->content;
1359    s=p->content;
1360    while(s!=NULL){
1361      dumpService(s->content);
1362      s=s->next;
1363    }
1364    p=p->next;
1365  }
1366}
1367
1368/**
1369 * Add a service to the registry
1370 *
1371 * @param reg the resgitry to add the service
1372 * @param name the registry name to update
1373 * @param content the service to add
1374 */
1375bool addServiceToRegistry(registry** reg,char* name,service* content){
1376  registry *l=*reg;
1377  int isInitial=-1;
1378  if(l==NULL){
1379    l=(registry*)malloc(REGISTRY_SIZE);
1380    isInitial=1;
1381  }
1382  if(l!=NULL){
1383    int hasLevel=-1;
1384    while(isInitial<0 && l!=NULL){
1385      if(l->name!=NULL && strcasecmp(name,l->name)==0){
1386        hasLevel=1;
1387        break;
1388      }
1389      l=l->next;
1390    }
1391    if(hasLevel<0){
1392      if(isInitial<0)
1393        l=(registry*)malloc(REGISTRY_SIZE);
1394      l->name=zStrdup(name);
1395      l->content=NULL;
1396      l->next=NULL;
1397    }
1398    if(l->content==NULL){
1399      l->content=(services*)malloc(SERVICES_SIZE);
1400      l->content->content=dupService(content);
1401      l->content->next=NULL;
1402    }
1403    else{
1404      services* s=l->content;
1405      while(s->next!=NULL)
1406        s=s->next;
1407      s->next=(services*)malloc(SERVICES_SIZE);
1408      s->next->content=dupService(content);
1409      s->next->next=NULL;
1410    }
1411    l->next=NULL;
1412    if(isInitial>0)
1413      *reg=l;
1414    else{
1415      registry *r=*reg;
1416      while(r->next!=NULL)
1417        r=r->next;
1418      r->next=l;
1419      r->next->next=NULL;
1420    }
1421    return true;
1422  }
1423  else
1424    return false;
1425}
1426
1427/**
1428 * Free memory allocated for the registry
1429 *
1430 * @param r the registry
1431 */
1432void freeRegistry(registry** r){
1433  registry* lr=*r;
1434  while(lr!=NULL){
1435    services* s=lr->content;
1436    free(lr->name);
1437    while(s!=NULL){
1438      service* s1=s->content;
1439      s=s->next;
1440      if(s1!=NULL){
1441        freeService(&s1);
1442        free(s1);
1443        s1=NULL;
1444      }
1445    }
1446    lr=lr->next;
1447  }   
1448}
1449
1450/**
1451 * Access a service in the registry
1452 *
1453 * @param r the registry
1454 * @param level the regitry to search ("concept", "generic" or "implementation")
1455 * @param sname the service name
1456 * @return the service pointer if a corresponding service was found or NULL
1457 */
1458service* getServiceFromRegistry(registry* r,char  *level,char* sname){
1459  registry *lr=r;
1460  while(lr!=NULL){
1461    if(strcasecmp(lr->name,level)==0){
1462      services* s=lr->content;
1463      while(s!=NULL){
1464        if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
1465          return s->content;
1466        s=s->next;
1467      }
1468      break;
1469    }
1470    lr=lr->next;
1471  }
1472  return NULL;
1473}
1474
1475/**
1476 * Apply inheritance to an out map from a reference in map
1477 *
1478 * @param out the map to update
1479 * @param in the reference map (containing inherited properties)
1480 */
1481void inheritMap(map** out,map* in){
1482  map* content=in;
1483  if((*out)==NULL){
1484    addMapToMap(out,in);
1485    return;
1486  }
1487  while(content!=NULL){
1488    map* cmap=getMap(*out,content->name);
1489    if(cmap==NULL)
1490      addToMap(*out,content->name,content->value);
1491    content=content->next;
1492  }
1493}
1494
1495/**
1496 * Apply inheritance to an out iotype from a reference in iotype
1497 *
1498 * @param out the iotype to update
1499 * @param in the reference iotype (containing inherited properties)
1500 */
1501void inheritIOType(iotype** out,iotype* in){
1502  iotype* io=in;
1503  iotype* oio=*out;
1504  if(io!=NULL){
1505    if(*out==NULL){
1506      *out=(iotype*)malloc(IOTYPE_SIZE);
1507      (*out)->content=NULL;
1508      addMapToMap(&(*out)->content,io->content);
1509      (*out)->next=NULL;
1510      oio=*out;
1511      inheritIOType(&oio->next,io->next);
1512    }else{
1513      inheritIOType(&oio->next,io->next);
1514    }
1515  }
1516}
1517
1518/**
1519 * Apply inheritance to an out elements from a reference in elements
1520 *
1521 * @param out the elements to update
1522 * @param in the reference elements (containing inherited properties)
1523 */
1524void inheritElements(elements** out,elements* in){
1525  elements* content=in;
1526  while(content!=NULL && *out!=NULL){
1527    elements* cmap=getElements(*out,content->name);
1528    if(cmap==NULL)
1529      addToElements(out,content);
1530    else{
1531      inheritMap(&cmap->content,content->content);
1532      inheritMap(&cmap->metadata,content->metadata);
1533      if(cmap->format==NULL && content->format!=NULL)
1534        cmap->format=zStrdup(content->format);
1535      inheritIOType(&cmap->defaults,content->defaults);
1536      if(cmap->supported==NULL)
1537        inheritIOType(&cmap->supported,content->supported);
1538      else{
1539        iotype* p=content->supported;
1540        while(p!=NULL){
1541          addMapToIoType(&cmap->supported,p->content);
1542          p=p->next;
1543        }
1544      }
1545    }
1546    content=content->next;
1547  }
1548}
1549
1550/**
1551 * Apply inheritance to a service based on a registry
1552 *
1553 * @param r the registry storing profiles hierarchy
1554 * @param s the service to update depending on its inheritance
1555 */
1556void inheritance(registry *r,service** s){
1557  if(r==NULL)
1558    return;
1559  service* ls=*s;
1560  if(ls->content==NULL)
1561    return;
1562  map* profile=getMap(ls->content,"extend");
1563  map* level=getMap(ls->content,"level");
1564  if(profile!=NULL&&level!=NULL){
1565    service* s1;
1566    if(strncasecmp(level->value,"profile",7)==0)
1567      s1=getServiceFromRegistry(r,(char*)"generic",profile->value);
1568    else
1569      s1=getServiceFromRegistry(r,level->value,profile->value);
1570     
1571    inheritMap(&ls->content,s1->content);
1572    inheritMap(&ls->metadata,s1->metadata);
1573    if(ls->inputs==NULL && s1->inputs!=NULL){
1574      ls->inputs=dupElements(s1->inputs);
1575    }else{
1576      inheritElements(&ls->inputs,s1->inputs);
1577    }
1578    if(ls->outputs==NULL && s1->outputs!=NULL){
1579      ls->outputs=dupElements(s1->outputs);
1580    }else
1581      inheritElements(&ls->outputs,s1->outputs);
1582  }
1583}
1584
1585/**
1586 * Convert a maps to a char*** (only used for Fortran support)
1587 *
1588 * @param m the maps to convert
1589 * @param c the resulting array
1590 */
1591void mapsToCharXXX(maps* m,char*** c){
1592  maps* tm=m;
1593  int i=0;
1594  int j=0;
1595  char tmp[10][30][1024];
1596  memset(tmp,0,1024*10*10);
1597  while(tm!=NULL){
1598    if(i>=10)
1599      break;
1600    strcpy(tmp[i][j],"name");
1601    j++;
1602    strcpy(tmp[i][j],tm->name);
1603    j++;
1604    map* tc=tm->content;
1605    while(tc!=NULL){
1606      if(j>=30)
1607        break;
1608      strcpy(tmp[i][j],tc->name);
1609      j++;
1610      strcpy(tmp[i][j],tc->value);
1611      j++;
1612      tc=tc->next;
1613    }
1614    tm=tm->next;
1615    j=0;
1616    i++;
1617  }
1618  memcpy(c,tmp,10*10*1024);
1619}
1620
1621/**
1622 * Convert a char*** to a maps (only used for Fortran support)
1623 *
1624 * @param c the array to convert
1625 * @param m the resulting maps
1626 */
1627void charxxxToMaps(char*** c,maps**m){
1628  maps* trorf=*m;
1629  int i,j;
1630  char tmp[10][30][1024];
1631  memcpy(tmp,c,10*30*1024);
1632  for(i=0;i<10;i++){
1633    if(strlen(tmp[i][1])==0)
1634      break;
1635    trorf->name=tmp[i][1];
1636    trorf->content=NULL;
1637    trorf->next=NULL;
1638    for(j=2;j<29;j+=2){
1639      if(strlen(tmp[i][j+1])==0)
1640        break;
1641      if(trorf->content==NULL)
1642        trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
1643      else
1644        addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
1645    }
1646    trorf=trorf->next;
1647  }
1648  m=&trorf;
1649}
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