source: trunk/zoo-project/zoo-kernel/service.c @ 957

Last change on this file since 957 was 957, checked in by knut, 22 months ago

Added function for allocating memory for map values (allocateMapValue). Fixed issue with getting attributes from input data node. Added code to support MIME subtype attributes in key-value pairs.

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