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

Last change on this file since 621 was 621, checked in by djay, 6 years ago

Major update. Creation of a basic parsing api. Call validateRequest after fork if any.

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