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

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

Fixes for supporting properly the memory=protect which force the ZOO-Kernel to not store any downloaded files in memory. Add footer to the HPC support. Fix the autotools to build service_json and sshapi only when required so, when HPC support is activated, this also avoid adding too much dependencies at compilation time. Store md5 of the downloaded files to avoid uploading on HPC server the same file more than once, in case the md5 correspond.

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