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

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

Added some recent changes from trunk (r889), including some new utility functions and exception handling and new (conditional) definition of type bool. Added some new logic concerning Python and Mono environment and search paths. Fixed problem with Mono updateStatus function. Changed response_print.h to #include locale.h unconditionally and xlocale.h conditionally; xlocale.h is non-standard and can probably be dropped.

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