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

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

Added some new logging functionality (function logMessage(), macros zooLog, zooLogMsg). Added utility functions setErrorMessage(), hasvalue(), and nonempty() in service.c. Added enum WPSException and arrays WPSExceptionText and WPSExceptionCode (see also function setErrorMessage). New conditional definition of type bool in service.c (to fix issue with bool). Null pointer check in function addToMap. Added missing return values and explicit type casts in some functions. Removed Windows-specific code in function dumpBackFinalFile (zoo_service_loader.c) that may cause error for async raw data output in formats other than XML.

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