source: trunk/zoo-project/zoo-kernel/service.h @ 615

Last change on this file since 615 was 607, checked in by djay, 10 years ago

Introduce the Process Profiles Registry with its documentation.

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