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

Last change on this file since 623 was 623, checked in by djay, 9 years ago

Fix issue when adding map with size in a map array.

  • 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    char sname[10]="size";
656    if(strlen(n)>5)
657      sprintf(sname,"size_%s",n+6);
658    map *tmp=getMap(m,n);
659    if(tmp->value!=NULL)
660      free(tmp->value);
661    tmp->value=(char*)malloc((size+1)*sizeof(char));
662    memmove(tmp->value,v,size*sizeof(char));
663    tmp->value[size]=0;
664    char sin[128];
665    sprintf(sin,"%d",size);
666    addToMap(m,sname,sin);
667  }
668
669  /**
670   * Add a map at the end of another map.
671   *
672   * @param mo the map to add mi
673   * @param mi the map to add to mo
674   */
675  static void addMapToMap(map** mo,map* mi){
676    map* tmp=mi;
677    map* _cursor=*mo;
678    while(tmp!=NULL){
679      if(_cursor==NULL){
680        *mo=createMap(tmp->name,tmp->value);
681        (*mo)->next=NULL;
682      }
683      else{
684#ifdef DEBUG
685        fprintf(stderr,"_CURSOR\n");
686        dumpMap(_cursor);
687#endif
688        while(_cursor->next!=NULL)
689          _cursor=_cursor->next;
690        map* tmp1=getMap(*mo,tmp->name);
691        if(tmp1==NULL){
692          _cursor->next=createMap(tmp->name,tmp->value);
693        }
694        else{
695          addToMap(*mo,tmp->name,tmp->value);
696        }
697      }
698      _cursor=*mo;
699      tmp=tmp->next;
700#ifdef DEBUG
701      fprintf(stderr,"MO\n");
702      dumpMap(*mo);
703#endif
704    }
705  }
706
707  /**
708   * Add a map to iotype.
709   *
710   * @param io the iotype to add the map
711   * @param mi the map to add to io
712   */
713  static void addMapToIoType(iotype** io,map* mi){
714    iotype* tmp=*io;
715    while(tmp->next!=NULL){
716      tmp=tmp->next;
717    }
718    tmp->next=(iotype*)malloc(IOTYPE_SIZE);
719    tmp->next->content=NULL;
720    addMapToMap(&tmp->next->content,mi);
721    tmp->next->next=NULL;
722  }
723
724  /**
725   * Access a specific map or set its value.
726   *
727   * @param m the map to search for the key
728   * @param key the key to search/add in the map
729   * @param value the value to add if the key does not exist
730   * @return a pointer on the map found or NULL if not found
731   */
732  static map* getMapOrFill(map** m,const char *key,const char* value){
733    map* tmp=*m;
734    map* tmpMap=getMap(tmp,key);
735    if(tmpMap==NULL){
736      if(tmp!=NULL){
737        addToMap((*m),key,value);
738      }
739      else
740        (*m)=createMap(key,value);
741      tmpMap=getMap(*m,key);
742    }
743    return tmpMap;
744  }
745
746  /**
747   * Verify if a map is contained in another map.
748   *
749   * @param m the map to search for i
750   * @param i the map to search in m
751   * @return true if i was found in m, false in other case
752   */
753  static bool contains(map* m,map* i){
754    while(i!=NULL){     
755      if(strcasecmp(i->name,"value")!=0 &&
756         strcasecmp(i->name,"xlink:href")!=0 &&
757         strcasecmp(i->name,"useMapServer")!=0 &&
758         strcasecmp(i->name,"asReference")!=0){
759        map *tmp;
760        if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL && 
761           strcasecmp(i->value,tmp->value)!=0)
762          return false;
763      }
764      i=i->next;
765    }
766    return true;
767  }
768
769  /**
770   * Access a specific iotype from an elements.
771   *
772   * @param e the elements to search for the name
773   * @param name the name to search in the elements e
774   * @param values the map to verify it was contained in the defaults or
775   *  supported content of the elements e
776   * @return a pointer on the iotype found or NULL if not found
777   */
778  static iotype* getIoTypeFromElement(elements* e,char *name, map* values){
779    elements* cursor=e;
780    while(cursor!=NULL){
781      if(strcasecmp(cursor->name,name)==0){
782        if(contains(cursor->defaults->content,values)==true)
783          return cursor->defaults;
784        else{
785          iotype* tmp=cursor->supported;
786          while(tmp!=NULL){
787            if(contains(tmp->content,values)==true)
788              return tmp;           
789            tmp=tmp->next;
790          }
791        }
792      }
793      cursor=cursor->next;
794    }
795    return NULL;
796  }
797
798  /**
799   * Load binary values from a map (in) and add them to another map (out)
800   *
801   * @param out the map to add binaries values
802   * @param in the map containing the binary values to add ti out
803   * @param pos index of the binary in an array (in case of "MapArray")
804   */
805  static void loadMapBinary(map** out,map* in,int pos){
806    map* size=getMap(in,"size");
807    map *lout=*out;
808    if(size!=NULL && pos>0){
809      char tmp[11];
810      sprintf(tmp,"size_%d",pos);
811      size=getMap(in,tmp);
812      sprintf(tmp,"value_%d",pos);
813      map* tmpVin=getMap(in,tmp);
814      map* tmpVout=getMap(lout,tmp);
815      free(tmpVout->value);
816      tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
817      memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
818      tmpVout->value[atoi(size->value)]=0;
819    }else{
820      if(size!=NULL){
821        map* tmpVin=getMap(in,"value");
822        map* tmpVout=getMap(lout,"value");
823        free(tmpVout->value);
824        tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
825        memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
826        tmpVout->value[atoi(size->value)]=0;
827      }
828    }
829  }
830 
831  /**
832   * Load binary values from a map (in) and add them to another map (out).
833   * This function will take care of MapArray.
834   * @see loadMapBinary
835   *
836   * @param out the map to add binaries values
837   * @param in the map containing the binary values to add ti out
838   */
839  static void loadMapBinaries(map** out,map* in){
840    map* size=getMap(in,"size");
841    map* length=getMap(in,"length");
842    if(length!=NULL){
843      int len=atoi(length->value);
844      int i=0;
845      for(i=0;i<len;i++){
846        loadMapBinary(out,in,i);
847      }
848    }
849    else
850      if(size!=NULL)
851        loadMapBinary(out,in,-1);
852  }
853
854  /**
855   * Duplicate a Maps
856   *
857   * @param mo the maps to clone
858   * @return the allocated maps containing a copy of the mo maps
859   */
860  static maps* dupMaps(maps** mo){
861    maps* _cursor=*mo;
862    maps* res=NULL;
863    if(_cursor!=NULL){
864      res=(maps*)malloc(MAPS_SIZE);
865      res->name=zStrdup(_cursor->name);
866      res->content=NULL;
867      res->next=NULL;
868      map* mc=_cursor->content;
869      if(mc!=NULL){
870        addMapToMap(&res->content,mc);
871        loadMapBinaries(&res->content,mc);
872      }
873      res->next=dupMaps(&_cursor->next);
874    }
875    return res;
876  }
877
878  /**
879   * Add a maps at the end of another maps.
880   *
881   * @see addMapToMap, dupMaps, getMaps
882   * @param mo the maps to add mi
883   * @param mi the maps to add to mo
884   */
885  static void addMapsToMaps(maps** mo,maps* mi){
886    maps* tmp=mi;
887    maps* _cursor=*mo;
888    while(tmp!=NULL){
889      if(_cursor==NULL){
890        *mo=dupMaps(&mi);
891      }
892      else{
893        while(_cursor->next!=NULL)
894          _cursor=_cursor->next;
895        maps* tmp1=getMaps(*mo,tmp->name);
896        if(tmp1==NULL)
897          _cursor->next=dupMaps(&tmp);
898        else
899          addMapToMap(&tmp1->content,tmp->content);
900        _cursor=*mo;
901      }
902      tmp=tmp->next;
903    }
904  }
905
906  /**
907   * Access a specific map array element
908   *
909   * @param m the map to search for the key
910   * @param key the key to search in the map
911   * @param index of the MapArray
912   * @return a pointer on the map found or NULL if not found
913   */
914  static map* getMapArray(map* m,const char* key,int index){
915    char tmp[1024];
916    if(index>0)
917      sprintf(tmp,"%s_%d",key,index);
918    else
919      sprintf(tmp,"%s",key);
920#ifdef DEBUG
921    fprintf(stderr,"** KEY %s\n",tmp);
922#endif
923    map* tmpMap=getMap(m,tmp);
924#ifdef DEBUG
925    if(tmpMap!=NULL)
926      dumpMap(tmpMap);
927#endif
928    return tmpMap;
929  }
930
931
932  /**
933   * Add a key value in a MapArray for a specific index
934   *
935   * @param m the map to search for the key
936   * @param key the key to search in the map
937   * @param index the index of the MapArray
938   * @param value the value to set in the MapArray
939   * @return a pointer on the map found or NULL if not found
940   */
941  static void setMapArray(map* m,const char* key,int index,const char* value){
942    char tmp[1024];
943    if(index>0){
944      sprintf(tmp,"%s_%d",key,index);
945      map* len=getMap(m,"length");
946      if((len!=NULL && atoi(len->value)<index+1) || len==NULL){
947        char tmp0[5];
948        sprintf(tmp0,"%d",index+1);
949        addToMap(m,"length",tmp0);
950      }
951    }
952    else
953      sprintf(tmp,"%s",key);
954    map* tmpSize=getMapArray(m,"size",index);
955    if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
956#ifdef DEBUG
957      fprintf(stderr,"%s\n",tmpSize->value);
958#endif
959      map* ptr=getMapOrFill(&m,tmp,(char *)"");
960      free(ptr->value);
961      ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
962      memcpy(ptr->value,value,atoi(tmpSize->value)); 
963    }
964    else
965      addToMap(m,tmp,value);
966  }
967
968  /**
969   * Access the map "type"
970   *
971   * @param mt the map
972   * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
973   *  other case
974   */
975  static map* getMapType(map* mt){
976    map* tmap=getMap(mt,(char *)"mimeType");
977    if(tmap==NULL){
978      tmap=getMap(mt,"dataType");
979      if(tmap==NULL){
980        tmap=getMap(mt,"CRS");
981      }
982    }
983#ifdef DEBUG
984        dumpMap(tmap);
985#endif
986    return tmap;
987  }
988
989  /**
990   * Add a Maps containing a MapArray to a Maps
991   *
992   * @see getMapType
993   * @param mo the maps
994   * @param mi the maps
995   * @param typ the map "type"
996   * @return
997   */
998  static int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
999    maps* tmp=mi;   
1000    maps* _cursor=getMaps(*mo,tmp->name);
1001
1002    if(_cursor==NULL)
1003      return -1;
1004
1005    map* tmpLength=getMap(_cursor->content,"length");
1006    char tmpLen[10];
1007    int len=1;
1008    if(tmpLength!=NULL){
1009      len=atoi(tmpLength->value);
1010    }
1011
1012    char *tmpV[11]={
1013      (char*)"size",
1014      (char*)"value",
1015      (char*)"uom",
1016      (char*)"Reference",
1017      (char*)"cache_file",
1018      (char*)"fmimeType",
1019      (char*)"xlink:href",
1020      typ,
1021      (char*)"schema",
1022      (char*)"encoding",
1023      (char*)"isCached"
1024    };
1025    sprintf(tmpLen,"%d",len+1);
1026    addToMap(_cursor->content,"length",tmpLen);
1027    int i=0;
1028    for(i=0;i<11;i++){
1029      map* tmpVI=getMap(tmp->content,tmpV[i]);
1030      if(tmpVI!=NULL){
1031#ifdef DEBUG
1032        fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
1033#endif
1034        if(i<7)
1035          setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
1036        else
1037          if(strncasecmp(tmpV[7],"mimeType",8)==0)
1038            setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
1039      }
1040    }
1041   
1042    addToMap(_cursor->content,"isArray","true");
1043    return 0;
1044  }
1045
1046  /**
1047   * Set a key value pair to a map contained in a Maps
1048   *
1049   * @param m the maps
1050   * @param key the maps name
1051   * @param subkey the map name included in the maps corresponding to key
1052   * @param value the corresponding value to add in the map
1053   */
1054  static void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
1055    maps* _tmpm=getMaps(m,key);
1056    if(_tmpm!=NULL){
1057      map* _ztmpm=getMap(_tmpm->content,subkey);
1058      if(_ztmpm!=NULL){
1059        if(_ztmpm->value!=NULL)
1060          free(_ztmpm->value);
1061        _ztmpm->value=zStrdup(value);
1062      }else{
1063        maps *tmp=(maps*)malloc(MAPS_SIZE);
1064        tmp->name=zStrdup(key);
1065        tmp->content=createMap(subkey,value);
1066        tmp->next=NULL;
1067        addMapsToMaps(&_tmpm,tmp);
1068        freeMaps(&tmp);
1069        free(tmp);
1070      }
1071    }else{
1072      maps *tmp=(maps*)malloc(MAPS_SIZE);
1073      tmp->name=zStrdup(key);
1074      tmp->content=createMap(subkey,value);
1075      tmp->next=NULL;
1076      addMapsToMaps(&m,tmp);
1077      freeMaps(&tmp);
1078      free(tmp);
1079    }
1080  }
1081
1082  /**
1083   * Dump an elements on stderr
1084   *
1085   * @param e the elements to dump
1086   */
1087  static void dumpElements(elements* e){
1088    elements* tmp=e;
1089    while(tmp!=NULL){
1090      fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
1091      fprintf(stderr," > CONTENT [%s]\n",tmp->name);
1092      dumpMap(tmp->content);
1093      fprintf(stderr," > METADATA [%s]\n",tmp->name);
1094      dumpMap(tmp->metadata);
1095      fprintf(stderr," > FORMAT [%s]\n",tmp->format);
1096      iotype* tmpio=tmp->defaults;
1097      int ioc=0;
1098      while(tmpio!=NULL){
1099        fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
1100        dumpMap(tmpio->content);
1101        tmpio=tmpio->next;
1102        ioc++;
1103      }
1104      tmpio=tmp->supported;
1105      ioc=0;
1106      while(tmpio!=NULL){
1107        fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
1108        dumpMap(tmpio->content);
1109        tmpio=tmpio->next;
1110        ioc++;
1111      }
1112      fprintf(stderr,"------------------\n");
1113      tmp=tmp->next;
1114    }
1115  }
1116
1117  /**
1118   * Dump an elements on stderr using the YAML syntaxe
1119   *
1120   * @param e the elements to dump
1121   */
1122  static void dumpElementsAsYAML(elements* e){
1123    elements* tmp=e;
1124    int i;
1125    while(tmp!=NULL){
1126      for(i=0;i<2;i++)
1127        fprintf(stderr," ");
1128      fprintf(stderr,"%s:\n",tmp->name);
1129      map* mcurs=tmp->content;
1130      while(mcurs!=NULL){
1131        for(i=0;i<4;i++)
1132          fprintf(stderr," ");
1133        _dumpMap(mcurs);
1134        mcurs=mcurs->next;
1135      }
1136      mcurs=tmp->metadata;
1137      if(mcurs!=NULL){
1138        for(i=0;i<4;i++)
1139          fprintf(stderr," ");
1140        fprintf(stderr,"MetaData:\n");
1141        while(mcurs!=NULL){
1142          for(i=0;i<6;i++)
1143            fprintf(stderr," ");
1144          _dumpMap(mcurs);
1145          mcurs=mcurs->next;
1146        }
1147      }
1148      for(i=0;i<4;i++)
1149        fprintf(stderr," ");
1150      fprintf(stderr,"%s:\n",tmp->format);
1151      iotype* tmpio=tmp->defaults;
1152      int ioc=0;
1153      while(tmpio!=NULL){
1154        for(i=0;i<6;i++)
1155          fprintf(stderr," ");
1156        fprintf(stderr,"default:\n");
1157        mcurs=tmpio->content;
1158        while(mcurs!=NULL){
1159          for(i=0;i<8;i++)
1160            fprintf(stderr," ");
1161          if(strcasecmp(mcurs->name,"range")==0){
1162            fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1163          }else
1164            _dumpMap(mcurs);
1165          mcurs=mcurs->next;
1166        }
1167        tmpio=tmpio->next;
1168        ioc++;
1169      }
1170      tmpio=tmp->supported;
1171      ioc=0;
1172      while(tmpio!=NULL){
1173        for(i=0;i<6;i++)
1174          fprintf(stderr," ");
1175        fprintf(stderr,"supported:\n");
1176        mcurs=tmpio->content;
1177        while(mcurs!=NULL){
1178          for(i=0;i<8;i++)
1179            fprintf(stderr," ");
1180          if(strcasecmp(mcurs->name,"range")==0){
1181            fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1182          }else
1183            _dumpMap(mcurs);
1184          mcurs=mcurs->next;
1185        }
1186        tmpio=tmpio->next;
1187        ioc++;
1188      }
1189      tmp=tmp->next;
1190    }
1191  }
1192
1193  /**
1194   * Duplicate an elements
1195   *
1196   * @param e the elements to clone
1197   * @return the allocated elements containing a copy of the elements e
1198   */
1199  static elements* dupElements(elements* e){
1200    elements* cursor=e;
1201    elements* tmp=NULL;
1202    if(cursor!=NULL){
1203#ifdef DEBUG
1204      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1205      dumpElements(e);
1206      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1207#endif
1208      tmp=(elements*)malloc(ELEMENTS_SIZE);
1209      tmp->name=zStrdup(e->name);
1210      tmp->content=NULL;
1211      addMapToMap(&tmp->content,e->content);
1212      tmp->metadata=NULL;
1213      addMapToMap(&tmp->metadata,e->metadata);
1214      if(e->format!=NULL)
1215        tmp->format=zStrdup(e->format);
1216      else
1217        tmp->format=NULL;
1218      if(e->defaults!=NULL){
1219        tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
1220        tmp->defaults->content=NULL;
1221        addMapToMap(&tmp->defaults->content,e->defaults->content);
1222        tmp->defaults->next=NULL;
1223#ifdef DEBUG
1224        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1225        dumpMap(tmp->defaults->content);
1226#endif
1227      }else
1228        tmp->defaults=NULL;
1229      if(e->supported!=NULL){
1230        tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
1231        tmp->supported->content=NULL;
1232        addMapToMap(&tmp->supported->content,e->supported->content);
1233        tmp->supported->next=NULL;
1234        iotype *tmp2=e->supported->next;
1235        while(tmp2!=NULL){
1236          addMapToIoType(&tmp->supported,tmp2->content);
1237#ifdef DEBUG
1238          fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1239          dumpMap(tmp->defaults->content);
1240#endif
1241          tmp2=tmp2->next;
1242        }
1243      }
1244      else
1245        tmp->supported=NULL;
1246      tmp->next=dupElements(cursor->next);
1247    }
1248    return tmp;
1249  }
1250
1251  /**
1252   * Add an elements to another elements.
1253   *
1254   * @see dupElements
1255   * @param m the elements to add the e
1256   * @param e the elements to be added to m
1257   */
1258  static void addToElements(elements** m,elements* e){
1259    elements* tmp=e;
1260    if(*m==NULL){
1261      *m=dupElements(tmp);
1262    }else{
1263      addToElements(&(*m)->next,tmp);
1264    }
1265  }
1266 
1267  /**
1268   * Dump a service on stderr
1269   *
1270   * @param s the service to dump
1271   */
1272  static void dumpService(service* s){
1273    if(s==NULL)
1274      return;
1275    fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
1276    if(s->content!=NULL){
1277      fprintf(stderr,"CONTENT MAP\n");
1278      dumpMap(s->content);
1279      fprintf(stderr,"CONTENT METADATA\n");
1280      dumpMap(s->metadata);
1281    }
1282    if(s->inputs!=NULL){
1283      fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
1284      dumpElements(s->inputs);
1285    }
1286    if(s->outputs!=NULL){
1287      fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
1288      dumpElements(s->outputs);
1289    }
1290    fprintf(stderr,"++++++++++++++++++\n");
1291  }
1292
1293  /**
1294   * Dump a service on stderr using the YAML syntaxe
1295   *
1296   * @param s the service to dump
1297   */
1298  static void dumpServiceAsYAML(service* s){
1299    int i;
1300    fprintf(stderr,"# %s\n\n",s->name);
1301    if(s->content!=NULL){
1302      map* mcurs=s->content;
1303      dumpMap(mcurs);
1304      mcurs=s->metadata;
1305      if(mcurs!=NULL){
1306        fprintf(stderr,"MetaData:\n");
1307        while(mcurs!=NULL){
1308          for(i=0;i<2;i++)
1309            fprintf(stderr," ");
1310          _dumpMap(mcurs);
1311          mcurs=mcurs->next;
1312        }
1313      }
1314    }
1315    if(s->inputs!=NULL){
1316      fprintf(stderr,"\ninputs:\n");
1317      dumpElementsAsYAML(s->inputs);
1318    }
1319    if(s->outputs!=NULL){
1320      fprintf(stderr,"\noutputs:\n");
1321      dumpElementsAsYAML(s->outputs);
1322    }
1323  }
1324
1325  /**
1326   * Duplicate a service
1327   *
1328   * @param s the service to clone
1329   * @return the allocated service containing a copy of the serfvice s
1330   */
1331  static service* dupService(service* s){
1332    service *res=(service*)malloc(SERVICE_SIZE);
1333    res->name=zStrdup(s->name);
1334    res->content=NULL;
1335    addMapToMap(&res->content,s->content);
1336    res->metadata=NULL;
1337    addMapToMap(&res->metadata,s->metadata);
1338    res->inputs=dupElements(s->inputs);
1339    res->outputs=dupElements(s->outputs);
1340    return res;
1341  }
1342
1343  /**
1344   * Print the registry on stderr.
1345   *
1346   * @param r the registry
1347   */
1348  static void dumpRegistry(registry* r){
1349    registry* p=r;
1350    while(p!=NULL){
1351      fprintf(stderr,"%s \n",p->name);
1352      services* s=p->content;
1353      s=p->content;
1354      while(s!=NULL){
1355        dumpService(s->content);
1356        s=s->next;
1357      }
1358      p=p->next;
1359    }
1360  }
1361
1362  /**
1363   * Add a service to the registry
1364   *
1365   * @param reg the resgitry to add the service
1366   * @param name the registry name to update
1367   * @param content the service to add
1368   */
1369  static bool addServiceToRegistry(registry** reg,char* name,service* content){
1370    registry *l=*reg;
1371    int isInitial=-1;
1372    if(l==NULL){
1373      l=(registry*)malloc(REGISTRY_SIZE);
1374      isInitial=1;
1375    }
1376    if(l!=NULL){
1377      int hasLevel=-1;
1378      while(isInitial<0 && l!=NULL){
1379        if(l->name!=NULL && strcasecmp(name,l->name)==0){
1380          hasLevel=1;
1381          break;
1382        }
1383        l=l->next;
1384      }
1385      if(hasLevel<0){
1386        if(isInitial<0)
1387          l=(registry*)malloc(REGISTRY_SIZE);
1388        l->name=zStrdup(name);
1389        l->content=NULL;
1390        l->next=NULL;
1391      }
1392      if(l->content==NULL){
1393        l->content=(services*)malloc(SERVICES_SIZE);
1394        l->content->content=dupService(content);
1395        l->content->next=NULL;
1396      }
1397      else{
1398        services* s=l->content;
1399        while(s->next!=NULL)
1400          s=s->next;
1401        s->next=(services*)malloc(SERVICES_SIZE);
1402        s->next->content=dupService(content);
1403        s->next->next=NULL;
1404      }
1405      l->next=NULL;
1406      if(isInitial>0)
1407        *reg=l;
1408      else{
1409        registry *r=*reg;
1410        while(r->next!=NULL)
1411          r=r->next;
1412        r->next=l;
1413        r->next->next=NULL;
1414      }
1415      return true;
1416    }
1417    else
1418      return false;
1419  }
1420
1421  /**
1422   * Free memory allocated for the registry
1423   *
1424   * @param r the registry
1425   */
1426  static void freeRegistry(registry** r){
1427    registry* lr=*r;
1428    while(lr!=NULL){
1429      services* s=lr->content;
1430      free(lr->name);
1431      while(s!=NULL){
1432        service* s1=s->content;
1433        s=s->next;
1434        if(s1!=NULL){
1435          freeService(&s1);
1436          free(s1);
1437          s1=NULL;
1438        }
1439      }
1440      lr=lr->next;
1441    }   
1442  }
1443
1444  /**
1445   * Access a service in the registry
1446   *
1447   * @param r the registry
1448   * @param level the regitry to search ("concept", "generic" or "implementation")
1449   * @param sname the service name
1450   * @return the service pointer if a corresponding service was found or NULL
1451   */
1452  static service* getServiceFromRegistry(registry* r,char  *level,char* sname){
1453    registry *lr=r;
1454    while(lr!=NULL){
1455      if(strcasecmp(lr->name,level)==0){
1456        services* s=lr->content;
1457        while(s!=NULL){
1458          if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
1459            return s->content;
1460          s=s->next;
1461        }
1462        break;
1463      }
1464      lr=lr->next;
1465    }
1466    return NULL;
1467  }
1468
1469  /**
1470   * Apply inheritance to an out map from a reference in map
1471   *
1472   * @param out the map to update
1473   * @param in the reference map (containing inherited properties)
1474   */
1475  static void inheritMap(map** out,map* in){
1476    map* content=in;
1477    while(content!=NULL && *out!=NULL){
1478      map* cmap=getMap(*out,content->name);
1479      if(cmap==NULL)
1480        addToMap(*out,content->name,content->value);
1481      content=content->next;
1482    }
1483  }
1484
1485  /**
1486   * Apply inheritance to an out iotype from a reference in iotype
1487   *
1488   * @param out the iotype to update
1489   * @param in the reference iotype (containing inherited properties)
1490   */
1491  static void inheritIOType(iotype** out,iotype* in){
1492    iotype* io=in;
1493    iotype* oio=*out;
1494    if(io!=NULL){
1495      if(*out==NULL){
1496        *out=(iotype*)malloc(IOTYPE_SIZE);
1497        (*out)->content=NULL;
1498        addMapToMap(&(*out)->content,io->content);
1499        (*out)->next=NULL;
1500        oio=*out;
1501        inheritIOType(&oio->next,io->next);
1502      }else{
1503        inheritIOType(&oio->next,io->next);
1504      }
1505    }
1506  }
1507
1508  /**
1509   * Apply inheritance to an out elements from a reference in elements
1510   *
1511   * @param out the elements to update
1512   * @param in the reference elements (containing inherited properties)
1513   */
1514  static void inheritElements(elements** out,elements* in){
1515    elements* content=in;
1516    while(content!=NULL && *out!=NULL){
1517      elements* cmap=getElements(*out,content->name);
1518      if(cmap==NULL)
1519        addToElements(out,content);
1520      else{
1521        inheritMap(&cmap->content,content->content);
1522        inheritMap(&cmap->metadata,content->metadata);
1523        if(cmap->format==NULL && content->format!=NULL)
1524          cmap->format=zStrdup(content->format);
1525        inheritIOType(&cmap->defaults,content->defaults);
1526        if(cmap->supported==NULL)
1527          inheritIOType(&cmap->supported,content->supported);
1528        else{
1529          iotype* p=content->supported;
1530          while(p!=NULL){
1531            addMapToIoType(&cmap->supported,p->content);
1532            p=p->next;
1533          }
1534        }
1535      }
1536      content=content->next;
1537    }
1538  }
1539
1540  /**
1541   * Apply inheritance to a service based on a registry
1542   *
1543   * @param r the registry storing profiles hierarchy
1544   * @param s the service to update depending on its inheritance
1545   */
1546  static void inheritance(registry *r,service** s){
1547    if(r==NULL)
1548      return;
1549    service* ls=*s;
1550    if(ls->content==NULL)
1551      return;
1552    map* profile=getMap(ls->content,"extend");
1553    map* level=getMap(ls->content,"level");
1554    if(profile!=NULL&&level!=NULL){
1555      service* s1;
1556      if(strncasecmp(level->value,"profile",7)==0)
1557        s1=getServiceFromRegistry(r,"generic",profile->value);
1558      else
1559        s1=getServiceFromRegistry(r,level->value,profile->value);
1560     
1561      inheritMap(&ls->content,s1->content);
1562      inheritMap(&ls->metadata,s1->metadata);
1563      if(ls->inputs==NULL && s1->inputs!=NULL){
1564        ls->inputs=dupElements(s1->inputs);
1565      }else{
1566        inheritElements(&ls->inputs,s1->inputs);
1567      }
1568      if(ls->outputs==NULL && s1->outputs!=NULL){
1569        ls->outputs=dupElements(s1->outputs);
1570      }else
1571        inheritElements(&ls->outputs,s1->outputs);
1572    }
1573  }
1574
1575  /**
1576   * Convert a maps to a char*** (only used for Fortran support)
1577   *
1578   * @param m the maps to convert
1579   * @param c the resulting array
1580   */
1581  static void mapsToCharXXX(maps* m,char*** c){
1582    maps* tm=m;
1583    int i=0;
1584    int j=0;
1585    char tmp[10][30][1024];
1586    memset(tmp,0,1024*10*10);
1587    while(tm!=NULL){
1588      if(i>=10)
1589        break;
1590      strcpy(tmp[i][j],"name");
1591      j++;
1592      strcpy(tmp[i][j],tm->name);
1593      j++;
1594      map* tc=tm->content;
1595      while(tc!=NULL){
1596        if(j>=30)
1597          break;
1598        strcpy(tmp[i][j],tc->name);
1599        j++;
1600        strcpy(tmp[i][j],tc->value);
1601        j++;
1602        tc=tc->next;
1603      }
1604      tm=tm->next;
1605      j=0;
1606      i++;
1607    }
1608    memcpy(c,tmp,10*10*1024);
1609  }
1610
1611  /**
1612   * Convert a char*** to a maps (only used for Fortran support)
1613   *
1614   * @param c the array to convert
1615   * @param m the resulting maps
1616   */
1617  static void charxxxToMaps(char*** c,maps**m){
1618    maps* trorf=*m;
1619    int i,j;
1620    char tmp[10][30][1024];
1621    memcpy(tmp,c,10*30*1024);
1622    for(i=0;i<10;i++){
1623      if(strlen(tmp[i][1])==0)
1624        break;
1625      trorf->name=tmp[i][1];
1626      trorf->content=NULL;
1627      trorf->next=NULL;
1628      for(j=2;j<29;j+=2){
1629        if(strlen(tmp[i][j+1])==0)
1630          break;
1631        if(trorf->content==NULL)
1632          trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
1633        else
1634          addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
1635      }
1636      trorf=trorf->next;
1637    }
1638    m=&trorf;
1639  }
1640
1641#ifdef WIN32
1642  extern char *url_encode(char *);
1643
1644  static char* getMapsAsKVP(maps* m,int length,int type){
1645    char *dataInputsKVP=(char*) malloc(length*sizeof(char));
1646    char *dataInputsKVPi=NULL;
1647    maps* curs=m;
1648    int i=0;
1649    while(curs!=NULL){
1650      map *inRequest=getMap(curs->content,"inRequest");
1651      map *hasLength=getMap(curs->content,"length");
1652      if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
1653         inRequest==NULL){
1654        if(i==0)
1655          if(type==0){
1656            sprintf(dataInputsKVP,"%s=",curs->name);
1657            if(hasLength!=NULL){
1658              dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
1659              sprintf(dataInputsKVPi,"%s=",curs->name);
1660            }
1661          }
1662          else
1663            sprintf(dataInputsKVP,"%s",curs->name);
1664        else{
1665          char *temp=zStrdup(dataInputsKVP);
1666          if(type==0)
1667            sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
1668          else
1669            sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
1670        }
1671        map* icurs=curs->content;
1672        if(type==0){
1673          char *temp=zStrdup(dataInputsKVP);
1674          if(getMap(curs->content,"xlink:href")!=NULL)
1675            sprintf(dataInputsKVP,"%sReference",temp);
1676          else{
1677            if(hasLength!=NULL){
1678              int j;
1679              for(j=0;j<atoi(hasLength->value);j++){
1680                map* tmp0=getMapArray(curs->content,"value",j);
1681                if(j==0)
1682                  free(temp);
1683                temp=zStrdup(dataInputsKVP);
1684                if(j==0)
1685                  sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
1686                else
1687                  sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
1688              }
1689            }
1690            else
1691              sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
1692          }
1693          free(temp);
1694        }
1695        while(icurs!=NULL){
1696          if(strncasecmp(icurs->name,"value",5)!=0 &&
1697             strncasecmp(icurs->name,"mimeType_",9)!=0 &&
1698             strncasecmp(icurs->name,"dataType_",9)!=0 &&
1699             strncasecmp(icurs->name,"size",4)!=0 &&
1700             strncasecmp(icurs->name,"length",4)!=0 &&
1701             strncasecmp(icurs->name,"isArray",7)!=0 &&
1702             strcasecmp(icurs->name,"Reference")!=0 &&
1703             strcasecmp(icurs->name,"minOccurs")!=0 &&
1704             strcasecmp(icurs->name,"maxOccurs")!=0 &&
1705             strncasecmp(icurs->name,"fmimeType",9)!=0 &&
1706             strcasecmp(icurs->name,"inRequest")!=0){
1707            char *itemp=zStrdup(dataInputsKVP);
1708            if(strcasecmp(icurs->name,"xlink:href")!=0)
1709              sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
1710            else
1711              sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
1712            free(itemp);
1713          }
1714          icurs=icurs->next;
1715        }
1716      }
1717      curs=curs->next;
1718      i++;
1719    }
1720    return dataInputsKVP;
1721  }
1722#endif
1723
1724#ifdef __cplusplus
1725}
1726#endif
1727
1728#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