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

Last change on this file since 962 was 961, checked in by djay, 4 years ago

Make sure not to try accessing mimetype and provenance in case a local file is used. Fix issue with addMapsToMaps. Produce value string only when memory=load for Python support. Make gdal/profile service usable in case memory=protect.

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