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

Last change on this file since 627 was 627, checked in by djay, 7 years ago

Fix issue for downloaded inputs which support multiple values.

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