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

Last change on this file since 943 was 943, checked in by knut, 5 years ago

Fix problem with the parsing of system environment variables (Windows version). Need to verify that problem does not pertain to non-Windows versions also.

  • Property svn:keywords set to Id
File size: 42.4 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    if(limit>=0 && cnt==limit)
133      tmp=NULL;
134    cnt++;
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,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
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