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

Last change on this file since 633 was 631, checked in by djay, 10 years ago

Add readBase64 function, avoid calling it prior to fork . Add dumpMapsValuesToFiles function used to simplify OTB support.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr
File size: 41.4 KB
RevLine 
[579]1/*
[1]2 * Author : Gérald FENOY
3 *
[576]4 * Copyright (c) 2009-2015 GeoLabs SARL
[1]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
[216]30#ifdef WIN32
[444]31#ifndef USE_MS
[375]32#define strncasecmp _strnicmp
33#define strcasecmp _stricmp
[444]34#endif
[375]35#ifndef snprintf
[216]36#define snprintf sprintf_s
[453]37#endif
38#define zStrdup _strdup
39#define zMkdir _mkdir
40#define zOpen _open
41#define zWrite _write
[507]42#define zSleep Sleep
[514]43#include <sys/timeb.h>
44struct ztimeval {
45  long tv_sec; /* seconds */
46  long tv_usec; /* and microseconds */
47};
[554]48static int zGettimeofday(struct ztimeval* tp, void* tzp)
[514]49{
[554]50  if (tp == 0) {
51    return -1;
52  }
53 
[514]54  struct _timeb theTime;
55  _ftime(&theTime);
56  tp->tv_sec = theTime.time;
57  tp->tv_usec = theTime.millitm * 1000;
[554]58 
59  return 0; // The gettimeofday() function shall return 0 on success
[514]60}
[379]61#else
[579]62/**
63 * The crossplatform strdup alias
64 */
[453]65#define zStrdup strdup
[579]66/**
67 * The crossplatform mkdir alias
68 */
[453]69#define zMkdir mkdir
[579]70/**
71 * The crossplatform open alias
72 */
[454]73#define zOpen open
[579]74/**
75 * The crossplatform write alias
76 */
[454]77#define zWrite write
[579]78/**
79 * The crossplatform sleep alias
80 */
[507]81#define zSleep sleep
[579]82/**
83 * The crossplatform gettimeofday alias
84 */
[514]85#define zGettimeofday gettimeofday
[579]86/**
87 * The crossplatform timeval alias
88 */
[514]89#define ztimeval timeval
[216]90#endif
91
[1]92#ifdef __cplusplus
93extern "C" {
94#endif
95
[444]96#ifdef WIN32
97#ifdef USE_MS
98#include <mapserver.h>
99#endif
100#endif
[1]101#include <stdlib.h>
102#include <ctype.h>
103#include <stdio.h>
104#include <string.h>
[364]105#ifndef WIN32
[618]106#include <ctype.h>
[490]107#ifndef bool
[1]108#define bool int
[490]109#endif
110#ifndef true
[579]111  /**
112   * Local true definition
113   */
[1]114#define true 1
[579]115  /**
116   * Local false definition
117   */
[618]118#define false 0
[490]119#endif
[364]120#endif
[9]121
[579]122/**
123 * The global accepted status for a service
124 */
[1]125#define SERVICE_ACCEPTED 0
[579]126/**
127 * The global started status for a service
128 */
[1]129#define SERVICE_STARTED 1
[579]130/**
131 * The global paused status for a service
132 */
[1]133#define SERVICE_PAUSED 2
[579]134/**
135 * The global succeeded status for a service
136 */
[1]137#define SERVICE_SUCCEEDED 3
[579]138/**
139 * The global failed status for a service
140 */
[1]141#define SERVICE_FAILED 4
[9]142
[579]143/**
144 * The memory size to create an elements
145 */
[1]146#define ELEMENTS_SIZE (sizeof(char*)+(((2*sizeof(char*))+sizeof(maps*))*2)+sizeof(char*)+(((2*sizeof(char*))+sizeof(iotype*))*2)+sizeof(elements*))
[579]147/**
148 * The memory size to create a map
149 */
[9]150#define MAP_SIZE (2*sizeof(char*))+sizeof(NULL)
[579]151/**
152 * The memory size to create an iotype
153 */
[9]154#define IOTYPE_SIZE MAP_SIZE+sizeof(NULL)
[579]155/**
156 * The memory size to create a maps
157 */
[9]158#define MAPS_SIZE (2*sizeof(char*))+sizeof(map*)+MAP_SIZE
[579]159/**
160 * The memory size to create a service
161 */
[9]162#define SERVICE_SIZE (ELEMENTS_SIZE*2)+(MAP_SIZE*2)+sizeof(char*)
[607]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*)
[1]171
[26]172#define SHMSZ     27
[1]173
[465]174#include "version.h"
[1]175
[375]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
[9]183  /**
[579]184   * KVP linked list
[9]185   */
[1]186  typedef struct map{
[607]187    char* name; //!< the key
188    char* value; //!< the value
189    struct map* next; //!< the pointer to the next map if any or NULL
[1]190  } map;
191
192#ifdef WIN32
193#define NULLMAP ((map*) 0)
194#else
195#define NULLMAP NULL
196#endif
197
[114]198  /**
[579]199   * linked list of map pointer
[114]200   *
201   * Small object to store WPS KVP set.
202   */
203  typedef struct maps{
[607]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
[114]207  } maps;
208
209  /**
[579]210   * Dump a map on stderr
211   *
212   * @param t the map to dump
[114]213   */
[9]214  static void _dumpMap(map* t){
[1]215    if(t!=NULL){
[465]216      fprintf(stderr,"%s: %s\n",t->name,t->value);
[1]217      fflush(stderr);
[364]218        }else{
[1]219      fprintf(stderr,"NULL\n");
220      fflush(stderr);
221    }
222  }
223
[579]224  /**
225   * Dump a map on stderr, see _dumpMap()
226   *
227   * @param t the map to dump
228   */
[9]229  static void dumpMap(map* t){
[1]230    map* tmp=t;
231    while(tmp!=NULL){
232      _dumpMap(tmp);
233      tmp=tmp->next;
234    }
235  }
236
[579]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   */
[92]243  static void dumpMapToFile(map* t,FILE* file){
244    map* tmp=t;
245    while(tmp!=NULL){
[364]246#ifdef DEBUG
[254]247      fprintf(stderr,"%s = %s\n",tmp->name,tmp->value);
[364]248#endif
[253]249      fprintf(file,"%s = %s\n",tmp->name,tmp->value);
[92]250      tmp=tmp->next;
251    }
252  }
[601]253 
[579]254  /**
255   * Dump a maps on stderr, see dumpMap().
256   *
257   * @param m the map to dump
258   */
[1]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
[579]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   */
[254]274  static void dumpMapsToFile(maps* m,char* file_path){
275    FILE* file=fopen(file_path,"w");
[92]276    maps* tmp=m;
277    if(tmp!=NULL){
278      fprintf(file,"[%s]\n",tmp->name);
279      dumpMapToFile(tmp->content,file);
[254]280      fflush(file);
[92]281    }
[254]282    fclose(file);
[92]283  }
[601]284 
[579]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   */
[9]292  static map* createMap(const char* name,const char* value){
[1]293    map* tmp=(map *)malloc(MAP_SIZE);
[453]294    tmp->name=zStrdup(name);
295    tmp->value=zStrdup(value);
[1]296    tmp->next=NULL;
297    return tmp;
298  }
299
[579]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   */
[1]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   
[579]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   */
[9]323  static bool hasKey(map* m,const char *key){
[1]324    map* tmp=m;
325    while(tmp!=NULL){
[57]326      if(strcasecmp(tmp->name,key)==0)
[1]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
[579]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   */
[9]343  static maps* getMaps(maps* m,const char *key){
[1]344    maps* tmp=m;
345    while(tmp!=NULL){
[57]346      if(strcasecmp(tmp->name,key)==0){
[1]347        return tmp;
[9]348      }
[1]349      tmp=tmp->next;
350    }
351    return NULL;
352  }
353
[579]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   */
[9]361  static map* getMap(map* m,const char *key){
[1]362    map* tmp=m;
363    while(tmp!=NULL){
[57]364      if(strcasecmp(tmp->name,key)==0){
[1]365        return tmp;
[9]366      }
[1]367      tmp=tmp->next;
368    }
369    return NULL;
370  }
371
[281]372
[579]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   */
[216]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
[579]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   */
[114]398  static map* getMapFromMaps(maps* m,const char* key,const char* subkey){
[1]399    maps* _tmpm=getMaps(m,key);
400    if(_tmpm!=NULL){
[9]401      map* _ztmpm=getMap(_tmpm->content,subkey);
402      return _ztmpm;
[1]403    }
404    else return NULL;
405  }
406
[579]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   */
[9]413  static void freeMap(map** mo){
[1]414    map* _cursor=*mo;
415    if(_cursor!=NULL){
[9]416#ifdef DEBUG
417      fprintf(stderr,"freeMap\n");
418#endif
[1]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
[579]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   */
[9]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  }
[1]451
[114]452  /**
[579]453   * Not named linked list
[114]454   *
455   * Used to store informations about formats, such as mimeType, encoding ...
456   */
[1]457  typedef struct iotype{
[607]458    struct map* content; //!< the content map
459    struct iotype* next; //!< the pointer to the next iotype if any or NULL
[1]460  } iotype;
461
[114]462  /**
[579]463   * Metadata information about input or output.
[114]464   *
465   * The elements are used to store metadata informations defined in the ZCFG.
466   */
[1]467  typedef struct elements{
[607]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)
[1]475  } elements;
476
[579]477  /**
478   * Metadata informations about a full Service.
479   */
[1]480  typedef struct service{
[607]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
[1]486  } service;
487
[579]488  /**
[607]489   * Services chained list.
[579]490   */
[1]491  typedef struct services{
[607]492    struct service* content; //!< the content service pointer
493    struct services* next; //!< the pointer to the next services*
[1]494  } services;
495
[579]496  /**
[607]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  /**
[579]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   */ 
[114]512  static bool hasElement(elements* e,const char* key){
[1]513    elements* tmp=e;
514    while(tmp!=NULL){
[57]515      if(strcasecmp(key,tmp->name)==0)
[1]516        return true;
517      tmp=tmp->next;
518    }
519    return false;
520  }
521
[579]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   */ 
[1]529  static elements* getElements(elements* m,char *key){
530    elements* tmp=m;
531    while(tmp!=NULL){
[57]532      if(strcasecmp(tmp->name,key)==0)
[1]533        return tmp;
534      tmp=tmp->next;
535    }
536    return NULL;
537  }
538
[579]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   */
[9]545  static void freeIOType(iotype** i){
[1]546    iotype* _cursor=*i;
547    if(_cursor!=NULL){
[9]548      if(_cursor->next!=NULL){
549        freeIOType(&_cursor->next);
550        free(_cursor->next);
551      }
[57]552      freeMap(&_cursor->content);
553      free(_cursor->content);
[1]554    }
555  }
556
[579]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   */
[1]563  static void freeElements(elements** e){
564    elements* tmp=*e;
565    if(tmp!=NULL){
[57]566      if(tmp->name!=NULL)
567        free(tmp->name);
[1]568      freeMap(&tmp->content);
[57]569      if(tmp->content!=NULL)
570        free(tmp->content);
[1]571      freeMap(&tmp->metadata);
[57]572      if(tmp->metadata!=NULL)
573        free(tmp->metadata);
574      if(tmp->format!=NULL)
575        free(tmp->format);
[1]576      freeIOType(&tmp->defaults);
577      if(tmp->defaults!=NULL)
578        free(tmp->defaults);
579      freeIOType(&tmp->supported);
[57]580      if(tmp->supported!=NULL){
[1]581        free(tmp->supported);
[57]582      }
[9]583      freeElements(&tmp->next);
[60]584      if(tmp->next!=NULL)
585        free(tmp->next);
[1]586    }
587  }
588
[579]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   */
[9]595  static void freeService(service** s){
[1]596    service* tmp=*s;
597    if(tmp!=NULL){
[9]598      if(tmp->name!=NULL)
599        free(tmp->name);
[1]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
[579]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   */
[9]622  static void addToMap(map* m,const char* n,const char* v){
623    if(hasKey(m,n)==false){
624      map* _cursor=m;
[490]625      while(_cursor->next!=NULL){
626        _cursor=_cursor->next;
627      }
628      _cursor->next=createMap(n,v);
[9]629    }
630    else{
631      map *tmp=getMap(m,n);
632      if(tmp->value!=NULL)
[469]633        free(tmp->value);
[453]634      tmp->value=zStrdup(v);
[9]635    }
636  }
637
[579]638  /**
[627]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  /**
[579]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   */
[508]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    }
[623]680    char sname[10]="size";
681    if(strlen(n)>5)
682      sprintf(sname,"size_%s",n+6);
[508]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];
[576]690    sprintf(sin,"%d",size);
[623]691    addToMap(m,sname,sin);
[508]692  }
693
[579]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   */
[9]700  static void addMapToMap(map** mo,map* mi){
[1]701    map* tmp=mi;
702    map* _cursor=*mo;
703    while(tmp!=NULL){
704      if(_cursor==NULL){
[465]705        *mo=createMap(tmp->name,tmp->value);
706        (*mo)->next=NULL;
[1]707      }
708      else{
[9]709#ifdef DEBUG
710        fprintf(stderr,"_CURSOR\n");
711        dumpMap(_cursor);
712#endif
[465]713        while(_cursor->next!=NULL)
[1]714          _cursor=_cursor->next;
[469]715        map* tmp1=getMap(*mo,tmp->name);
716        if(tmp1==NULL){
[465]717          _cursor->next=createMap(tmp->name,tmp->value);
[469]718        }
[465]719        else{
[471]720          addToMap(*mo,tmp->name,tmp->value);
[465]721        }
[1]722      }
[465]723      _cursor=*mo;
[1]724      tmp=tmp->next;
[9]725#ifdef DEBUG
726      fprintf(stderr,"MO\n");
727      dumpMap(*mo);
728#endif
[1]729    }
730  }
731
[579]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   */
[9]738  static void addMapToIoType(iotype** io,map* mi){
[1]739    iotype* tmp=*io;
[57]740    while(tmp->next!=NULL){
[1]741      tmp=tmp->next;
742    }
[57]743    tmp->next=(iotype*)malloc(IOTYPE_SIZE);
744    tmp->next->content=NULL;
745    addMapToMap(&tmp->next->content,mi);
746    tmp->next->next=NULL;
[1]747  }
748
[579]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   */
[490]757  static map* getMapOrFill(map** m,const char *key,const char* value){
[471]758    map* tmp=*m;
[281]759    map* tmpMap=getMap(tmp,key);
760    if(tmpMap==NULL){
[490]761      if(tmp!=NULL){
762        addToMap((*m),key,value);
763      }
[284]764      else
[471]765        (*m)=createMap(key,value);
766      tmpMap=getMap(*m,key);
[281]767    }
768    return tmpMap;
769  }
770
[579]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   */
[57]778  static bool contains(map* m,map* i){
779    while(i!=NULL){     
780      if(strcasecmp(i->name,"value")!=0 &&
[299]781         strcasecmp(i->name,"xlink:href")!=0 &&
782         strcasecmp(i->name,"useMapServer")!=0 &&
783         strcasecmp(i->name,"asReference")!=0){
[57]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  }
[9]793
[579]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   */
[57]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
[579]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   */
[550]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 
[579]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   */
[550]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
[579]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   */
[9]885  static maps* dupMaps(maps** mo){
886    maps* _cursor=*mo;
887    maps* res=NULL;
888    if(_cursor!=NULL){
889      res=(maps*)malloc(MAPS_SIZE);
[453]890      res->name=zStrdup(_cursor->name);
[9]891      res->content=NULL;
892      res->next=NULL;
893      map* mc=_cursor->content;
894      if(mc!=NULL){
895        addMapToMap(&res->content,mc);
[550]896        loadMapBinaries(&res->content,mc);
[9]897      }
898      res->next=dupMaps(&_cursor->next);
[1]899    }
[9]900    return res;
901  }
902
[579]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   */
[9]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;
[469]920        maps* tmp1=getMaps(*mo,tmp->name);
[465]921        if(tmp1==NULL)
922          _cursor->next=dupMaps(&tmp);
923        else
924          addMapToMap(&tmp1->content,tmp->content);
925        _cursor=*mo;
[9]926      }
927      tmp=tmp->next;
[1]928    }
929  }
930
[579]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   */
[490]939  static map* getMapArray(map* m,const char* key,int index){
[360]940    char tmp[1024];
941    if(index>0)
942      sprintf(tmp,"%s_%d",key,index);
943    else
[379]944      sprintf(tmp,"%s",key);
[360]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  }
[1]955
[360]956
[579]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   */
[576]966  static void setMapArray(map* m,const char* key,int index,const char* value){
[360]967    char tmp[1024];
[576]968    if(index>0){
[360]969      sprintf(tmp,"%s_%d",key,index);
[576]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    }
[360]977    else
[379]978      sprintf(tmp,"%s",key);
[550]979    map* tmpSize=getMapArray(m,"size",index);
[360]980    if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
[364]981#ifdef DEBUG
[360]982      fprintf(stderr,"%s\n",tmpSize->value);
[364]983#endif
[471]984      map* ptr=getMapOrFill(&m,tmp,(char *)"");
[360]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
[579]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   */
[360]1000  static map* getMapType(map* mt){
[465]1001    map* tmap=getMap(mt,(char *)"mimeType");
[360]1002    if(tmap==NULL){
1003      tmap=getMap(mt,"dataType");
1004      if(tmap==NULL){
1005        tmap=getMap(mt,"CRS");
1006      }
1007    }
[364]1008#ifdef DEBUG
1009        dumpMap(tmap);
1010#endif
[360]1011    return tmap;
1012  }
1013
[579]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   */
[360]1023  static int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
[362]1024    maps* tmp=mi;   
1025    maps* _cursor=getMaps(*mo,tmp->name);
[360]1026
[362]1027    if(_cursor==NULL)
[360]1028      return -1;
1029
[362]1030    map* tmpLength=getMap(_cursor->content,"length");
[360]1031    char tmpLen[10];
1032    int len=1;
1033    if(tmpLength!=NULL){
1034      len=atoi(tmpLength->value);
1035    }
1036
[627]1037    char *tmpV[12]={
[465]1038      (char*)"size",
1039      (char*)"value",
1040      (char*)"uom",
1041      (char*)"Reference",
[627]1042      (char*)"Order",
[550]1043      (char*)"cache_file",
1044      (char*)"fmimeType",
[465]1045      (char*)"xlink:href",
[360]1046      typ,
[465]1047      (char*)"schema",
[550]1048      (char*)"encoding",
1049      (char*)"isCached"
[360]1050    };
1051    sprintf(tmpLen,"%d",len+1);
1052    addToMap(_cursor->content,"length",tmpLen);
1053    int i=0;
[627]1054    for(i=0;i<12;i++){
[360]1055      map* tmpVI=getMap(tmp->content,tmpV[i]);
1056      if(tmpVI!=NULL){
[364]1057#ifdef DEBUG
[360]1058        fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
[364]1059#endif
[631]1060        setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
[360]1061      }
1062    }
1063   
1064    addToMap(_cursor->content,"isArray","true");
1065    return 0;
1066  }
1067
[579]1068  /**
1069   * Set a key value pair to a map contained in a Maps
1070   *
1071   * @param m the maps
1072   * @param key the maps name
1073   * @param subkey the map name included in the maps corresponding to key
1074   * @param value the corresponding value to add in the map
1075   */
[114]1076  static void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
[26]1077    maps* _tmpm=getMaps(m,key);
1078    if(_tmpm!=NULL){
1079      map* _ztmpm=getMap(_tmpm->content,subkey);
1080      if(_ztmpm!=NULL){
[216]1081        if(_ztmpm->value!=NULL)
1082          free(_ztmpm->value);
[453]1083        _ztmpm->value=zStrdup(value);
[26]1084      }else{
[469]1085        maps *tmp=(maps*)malloc(MAPS_SIZE);
1086        tmp->name=zStrdup(key);
1087        tmp->content=createMap(subkey,value);
1088        tmp->next=NULL;
1089        addMapsToMaps(&_tmpm,tmp);
1090        freeMaps(&tmp);
1091        free(tmp);
[26]1092      }
[361]1093    }else{
1094      maps *tmp=(maps*)malloc(MAPS_SIZE);
[453]1095      tmp->name=zStrdup(key);
[361]1096      tmp->content=createMap(subkey,value);
1097      tmp->next=NULL;
1098      addMapsToMaps(&m,tmp);
1099      freeMaps(&tmp);
1100      free(tmp);
[26]1101    }
1102  }
1103
[579]1104  /**
1105   * Dump an elements on stderr
1106   *
1107   * @param e the elements to dump
1108   */
[9]1109  static void dumpElements(elements* e){
[1]1110    elements* tmp=e;
1111    while(tmp!=NULL){
1112      fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
1113      fprintf(stderr," > CONTENT [%s]\n",tmp->name);
1114      dumpMap(tmp->content);
1115      fprintf(stderr," > METADATA [%s]\n",tmp->name);
1116      dumpMap(tmp->metadata);
1117      fprintf(stderr," > FORMAT [%s]\n",tmp->format);
1118      iotype* tmpio=tmp->defaults;
1119      int ioc=0;
1120      while(tmpio!=NULL){
1121        fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
1122        dumpMap(tmpio->content);
1123        tmpio=tmpio->next;
1124        ioc++;
1125      }
1126      tmpio=tmp->supported;
1127      ioc=0;
1128      while(tmpio!=NULL){
1129        fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
1130        dumpMap(tmpio->content);
1131        tmpio=tmpio->next;
1132        ioc++;
1133      }
1134      fprintf(stderr,"------------------\n");
1135      tmp=tmp->next;
1136    }
1137  }
1138
[579]1139  /**
1140   * Dump an elements on stderr using the YAML syntaxe
1141   *
1142   * @param e the elements to dump
1143   */
[465]1144  static void dumpElementsAsYAML(elements* e){
1145    elements* tmp=e;
[466]1146    int i;
[465]1147    while(tmp!=NULL){
[466]1148      for(i=0;i<2;i++)
[465]1149        fprintf(stderr," ");
1150      fprintf(stderr,"%s:\n",tmp->name);
1151      map* mcurs=tmp->content;
1152      while(mcurs!=NULL){
[466]1153        for(i=0;i<4;i++)
[465]1154          fprintf(stderr," ");
1155        _dumpMap(mcurs);
1156        mcurs=mcurs->next;
1157      }
1158      mcurs=tmp->metadata;
1159      if(mcurs!=NULL){
[466]1160        for(i=0;i<4;i++)
[465]1161          fprintf(stderr," ");
1162        fprintf(stderr,"MetaData:\n");
1163        while(mcurs!=NULL){
[466]1164          for(i=0;i<6;i++)
[465]1165            fprintf(stderr," ");
1166          _dumpMap(mcurs);
1167          mcurs=mcurs->next;
1168        }
1169      }
[466]1170      for(i=0;i<4;i++)
[465]1171        fprintf(stderr," ");
1172      fprintf(stderr,"%s:\n",tmp->format);
1173      iotype* tmpio=tmp->defaults;
1174      int ioc=0;
1175      while(tmpio!=NULL){
[466]1176        for(i=0;i<6;i++)
[465]1177          fprintf(stderr," ");
1178        fprintf(stderr,"default:\n");
1179        mcurs=tmpio->content;
1180        while(mcurs!=NULL){
[466]1181          for(i=0;i<8;i++)
[465]1182            fprintf(stderr," ");
1183          if(strcasecmp(mcurs->name,"range")==0){
1184            fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1185          }else
1186            _dumpMap(mcurs);
1187          mcurs=mcurs->next;
1188        }
1189        tmpio=tmpio->next;
1190        ioc++;
1191      }
1192      tmpio=tmp->supported;
1193      ioc=0;
1194      while(tmpio!=NULL){
[466]1195        for(i=0;i<6;i++)
[465]1196          fprintf(stderr," ");
1197        fprintf(stderr,"supported:\n");
1198        mcurs=tmpio->content;
1199        while(mcurs!=NULL){
[466]1200          for(i=0;i<8;i++)
[465]1201            fprintf(stderr," ");
1202          if(strcasecmp(mcurs->name,"range")==0){
1203            fprintf(stderr,"range: \"%s\"\n",mcurs->value);
1204          }else
1205            _dumpMap(mcurs);
1206          mcurs=mcurs->next;
1207        }
1208        tmpio=tmpio->next;
1209        ioc++;
1210      }
1211      tmp=tmp->next;
1212    }
1213  }
1214
[579]1215  /**
1216   * Duplicate an elements
1217   *
1218   * @param e the elements to clone
1219   * @return the allocated elements containing a copy of the elements e
1220   */
[1]1221  static elements* dupElements(elements* e){
[9]1222    elements* cursor=e;
1223    elements* tmp=NULL;
1224    if(cursor!=NULL){
[1]1225#ifdef DEBUG
[9]1226      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
[1]1227      dumpElements(e);
[9]1228      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
[1]1229#endif
[9]1230      tmp=(elements*)malloc(ELEMENTS_SIZE);
[453]1231      tmp->name=zStrdup(e->name);
[1]1232      tmp->content=NULL;
1233      addMapToMap(&tmp->content,e->content);
1234      tmp->metadata=NULL;
1235      addMapToMap(&tmp->metadata,e->metadata);
[607]1236      if(e->format!=NULL)
1237        tmp->format=zStrdup(e->format);
1238      else
1239        tmp->format=NULL;
[1]1240      if(e->defaults!=NULL){
[9]1241        tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
[1]1242        tmp->defaults->content=NULL;
[9]1243        addMapToMap(&tmp->defaults->content,e->defaults->content);
[1]1244        tmp->defaults->next=NULL;
[9]1245#ifdef DEBUG
1246        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1247        dumpMap(tmp->defaults->content);
1248#endif
1249      }else
1250        tmp->defaults=NULL;
[1]1251      if(e->supported!=NULL){
[9]1252        tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
[1]1253        tmp->supported->content=NULL;
[57]1254        addMapToMap(&tmp->supported->content,e->supported->content);
[1]1255        tmp->supported->next=NULL;
1256        iotype *tmp2=e->supported->next;
1257        while(tmp2!=NULL){
[57]1258          addMapToIoType(&tmp->supported,tmp2->content);
[9]1259#ifdef DEBUG
1260          fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1261          dumpMap(tmp->defaults->content);
1262#endif
[1]1263          tmp2=tmp2->next;
1264        }
1265      }
[9]1266      else
1267        tmp->supported=NULL;
1268      tmp->next=dupElements(cursor->next);
[1]1269    }
[9]1270    return tmp;
[1]1271  }
1272
[579]1273  /**
1274   * Add an elements to another elements.
1275   *
1276   * @see dupElements
1277   * @param m the elements to add the e
1278   * @param e the elements to be added to m
1279   */
[9]1280  static void addToElements(elements** m,elements* e){
[1]1281    elements* tmp=e;
[60]1282    if(*m==NULL){
[9]1283      *m=dupElements(tmp);
1284    }else{
[57]1285      addToElements(&(*m)->next,tmp);
[1]1286    }
1287  }
[621]1288 
[579]1289  /**
1290   * Dump a service on stderr
1291   *
1292   * @param s the service to dump
1293   */
[9]1294  static void dumpService(service* s){
[618]1295    if(s==NULL)
1296      return;
[1]1297    fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
1298    if(s->content!=NULL){
1299      fprintf(stderr,"CONTENT MAP\n");
1300      dumpMap(s->content);
1301      fprintf(stderr,"CONTENT METADATA\n");
1302      dumpMap(s->metadata);
1303    }
1304    if(s->inputs!=NULL){
1305      fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
1306      dumpElements(s->inputs);
1307    }
1308    if(s->outputs!=NULL){
1309      fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
1310      dumpElements(s->outputs);
1311    }
1312    fprintf(stderr,"++++++++++++++++++\n");
1313  }
1314
[579]1315  /**
1316   * Dump a service on stderr using the YAML syntaxe
1317   *
1318   * @param s the service to dump
1319   */
[465]1320  static void dumpServiceAsYAML(service* s){
[466]1321    int i;
[465]1322    fprintf(stderr,"# %s\n\n",s->name);
1323    if(s->content!=NULL){
1324      map* mcurs=s->content;
1325      dumpMap(mcurs);
1326      mcurs=s->metadata;
1327      if(mcurs!=NULL){
1328        fprintf(stderr,"MetaData:\n");
1329        while(mcurs!=NULL){
[466]1330          for(i=0;i<2;i++)
[465]1331            fprintf(stderr," ");
1332          _dumpMap(mcurs);
1333          mcurs=mcurs->next;
1334        }
1335      }
1336    }
1337    if(s->inputs!=NULL){
[490]1338      fprintf(stderr,"\ninputs:\n");
[465]1339      dumpElementsAsYAML(s->inputs);
1340    }
1341    if(s->outputs!=NULL){
[490]1342      fprintf(stderr,"\noutputs:\n");
[465]1343      dumpElementsAsYAML(s->outputs);
1344    }
1345  }
1346
[579]1347  /**
[607]1348   * Duplicate a service
1349   *
1350   * @param s the service to clone
1351   * @return the allocated service containing a copy of the serfvice s
1352   */
1353  static service* dupService(service* s){
1354    service *res=(service*)malloc(SERVICE_SIZE);
1355    res->name=zStrdup(s->name);
1356    res->content=NULL;
1357    addMapToMap(&res->content,s->content);
1358    res->metadata=NULL;
1359    addMapToMap(&res->metadata,s->metadata);
1360    res->inputs=dupElements(s->inputs);
1361    res->outputs=dupElements(s->outputs);
1362    return res;
1363  }
1364
1365  /**
1366   * Print the registry on stderr.
1367   *
1368   * @param r the registry
1369   */
1370  static void dumpRegistry(registry* r){
1371    registry* p=r;
1372    while(p!=NULL){
1373      fprintf(stderr,"%s \n",p->name);
1374      services* s=p->content;
1375      s=p->content;
1376      while(s!=NULL){
1377        dumpService(s->content);
1378        s=s->next;
1379      }
1380      p=p->next;
1381    }
1382  }
1383
1384  /**
1385   * Add a service to the registry
1386   *
1387   * @param reg the resgitry to add the service
1388   * @param name the registry name to update
1389   * @param content the service to add
1390   */
1391  static bool addServiceToRegistry(registry** reg,char* name,service* content){
1392    registry *l=*reg;
1393    int isInitial=-1;
1394    if(l==NULL){
1395      l=(registry*)malloc(REGISTRY_SIZE);
1396      isInitial=1;
1397    }
1398    if(l!=NULL){
1399      int hasLevel=-1;
1400      while(isInitial<0 && l!=NULL){
1401        if(l->name!=NULL && strcasecmp(name,l->name)==0){
1402          hasLevel=1;
1403          break;
1404        }
1405        l=l->next;
1406      }
1407      if(hasLevel<0){
1408        if(isInitial<0)
1409          l=(registry*)malloc(REGISTRY_SIZE);
1410        l->name=zStrdup(name);
1411        l->content=NULL;
1412        l->next=NULL;
1413      }
1414      if(l->content==NULL){
1415        l->content=(services*)malloc(SERVICES_SIZE);
1416        l->content->content=dupService(content);
1417        l->content->next=NULL;
1418      }
1419      else{
1420        services* s=l->content;
1421        while(s->next!=NULL)
1422          s=s->next;
1423        s->next=(services*)malloc(SERVICES_SIZE);
1424        s->next->content=dupService(content);
1425        s->next->next=NULL;
1426      }
1427      l->next=NULL;
1428      if(isInitial>0)
1429        *reg=l;
1430      else{
1431        registry *r=*reg;
1432        while(r->next!=NULL)
1433          r=r->next;
1434        r->next=l;
1435        r->next->next=NULL;
1436      }
1437      return true;
1438    }
1439    else
1440      return false;
1441  }
1442
1443  /**
1444   * Free memory allocated for the registry
1445   *
1446   * @param r the registry
1447   */
1448  static void freeRegistry(registry** r){
1449    registry* lr=*r;
1450    while(lr!=NULL){
1451      services* s=lr->content;
1452      free(lr->name);
1453      while(s!=NULL){
1454        service* s1=s->content;
1455        s=s->next;
1456        if(s1!=NULL){
1457          freeService(&s1);
1458          free(s1);
1459          s1=NULL;
1460        }
1461      }
1462      lr=lr->next;
1463    }   
1464  }
1465
1466  /**
1467   * Access a service in the registry
1468   *
1469   * @param r the registry
1470   * @param level the regitry to search ("concept", "generic" or "implementation")
1471   * @param sname the service name
1472   * @return the service pointer if a corresponding service was found or NULL
1473   */
1474  static service* getServiceFromRegistry(registry* r,char  *level,char* sname){
1475    registry *lr=r;
1476    while(lr!=NULL){
1477      if(strcasecmp(lr->name,level)==0){
1478        services* s=lr->content;
1479        while(s!=NULL){
1480          if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
1481            return s->content;
1482          s=s->next;
1483        }
1484        break;
1485      }
1486      lr=lr->next;
1487    }
1488    return NULL;
1489  }
1490
1491  /**
1492   * Apply inheritance to an out map from a reference in map
1493   *
1494   * @param out the map to update
1495   * @param in the reference map (containing inherited properties)
1496   */
1497  static void inheritMap(map** out,map* in){
1498    map* content=in;
1499    while(content!=NULL && *out!=NULL){
1500      map* cmap=getMap(*out,content->name);
1501      if(cmap==NULL)
1502        addToMap(*out,content->name,content->value);
1503      content=content->next;
1504    }
1505  }
1506
1507  /**
1508   * Apply inheritance to an out iotype from a reference in iotype
1509   *
1510   * @param out the iotype to update
1511   * @param in the reference iotype (containing inherited properties)
1512   */
1513  static void inheritIOType(iotype** out,iotype* in){
1514    iotype* io=in;
1515    iotype* oio=*out;
1516    if(io!=NULL){
1517      if(*out==NULL){
1518        *out=(iotype*)malloc(IOTYPE_SIZE);
1519        (*out)->content=NULL;
1520        addMapToMap(&(*out)->content,io->content);
1521        (*out)->next=NULL;
1522        oio=*out;
1523        inheritIOType(&oio->next,io->next);
1524      }else{
1525        inheritIOType(&oio->next,io->next);
1526      }
1527    }
1528  }
1529
1530  /**
1531   * Apply inheritance to an out elements from a reference in elements
1532   *
1533   * @param out the elements to update
1534   * @param in the reference elements (containing inherited properties)
1535   */
1536  static void inheritElements(elements** out,elements* in){
1537    elements* content=in;
1538    while(content!=NULL && *out!=NULL){
1539      elements* cmap=getElements(*out,content->name);
1540      if(cmap==NULL)
1541        addToElements(out,content);
1542      else{
1543        inheritMap(&cmap->content,content->content);
1544        inheritMap(&cmap->metadata,content->metadata);
1545        if(cmap->format==NULL && content->format!=NULL)
1546          cmap->format=zStrdup(content->format);
1547        inheritIOType(&cmap->defaults,content->defaults);
1548        if(cmap->supported==NULL)
1549          inheritIOType(&cmap->supported,content->supported);
1550        else{
1551          iotype* p=content->supported;
1552          while(p!=NULL){
1553            addMapToIoType(&cmap->supported,p->content);
1554            p=p->next;
1555          }
1556        }
1557      }
1558      content=content->next;
1559    }
1560  }
1561
1562  /**
1563   * Apply inheritance to a service based on a registry
1564   *
1565   * @param r the registry storing profiles hierarchy
1566   * @param s the service to update depending on its inheritance
1567   */
1568  static void inheritance(registry *r,service** s){
1569    if(r==NULL)
1570      return;
1571    service* ls=*s;
1572    if(ls->content==NULL)
1573      return;
1574    map* profile=getMap(ls->content,"extend");
1575    map* level=getMap(ls->content,"level");
1576    if(profile!=NULL&&level!=NULL){
1577      service* s1;
1578      if(strncasecmp(level->value,"profile",7)==0)
1579        s1=getServiceFromRegistry(r,"generic",profile->value);
1580      else
1581        s1=getServiceFromRegistry(r,level->value,profile->value);
1582     
1583      inheritMap(&ls->content,s1->content);
1584      inheritMap(&ls->metadata,s1->metadata);
1585      if(ls->inputs==NULL && s1->inputs!=NULL){
1586        ls->inputs=dupElements(s1->inputs);
1587      }else{
1588        inheritElements(&ls->inputs,s1->inputs);
1589      }
1590      if(ls->outputs==NULL && s1->outputs!=NULL){
1591        ls->outputs=dupElements(s1->outputs);
1592      }else
1593        inheritElements(&ls->outputs,s1->outputs);
1594    }
1595  }
1596
1597  /**
[579]1598   * Convert a maps to a char*** (only used for Fortran support)
1599   *
1600   * @param m the maps to convert
1601   * @param c the resulting array
1602   */
[9]1603  static void mapsToCharXXX(maps* m,char*** c){
[1]1604    maps* tm=m;
1605    int i=0;
1606    int j=0;
1607    char tmp[10][30][1024];
1608    memset(tmp,0,1024*10*10);
1609    while(tm!=NULL){
1610      if(i>=10)
1611        break;
1612      strcpy(tmp[i][j],"name");
1613      j++;
1614      strcpy(tmp[i][j],tm->name);
1615      j++;
1616      map* tc=tm->content;
1617      while(tc!=NULL){
1618        if(j>=30)
1619          break;
1620        strcpy(tmp[i][j],tc->name);
1621        j++;
1622        strcpy(tmp[i][j],tc->value);
1623        j++;
1624        tc=tc->next;
1625      }
1626      tm=tm->next;
1627      j=0;
1628      i++;
1629    }
1630    memcpy(c,tmp,10*10*1024);
1631  }
1632
[579]1633  /**
1634   * Convert a char*** to a maps (only used for Fortran support)
1635   *
1636   * @param c the array to convert
1637   * @param m the resulting maps
1638   */
[9]1639  static void charxxxToMaps(char*** c,maps**m){
[1]1640    maps* trorf=*m;
1641    int i,j;
1642    char tmp[10][30][1024];
1643    memcpy(tmp,c,10*30*1024);
1644    for(i=0;i<10;i++){
1645      if(strlen(tmp[i][1])==0)
1646        break;
1647      trorf->name=tmp[i][1];
1648      trorf->content=NULL;
1649      trorf->next=NULL;
1650      for(j=2;j<29;j+=2){
1651        if(strlen(tmp[i][j+1])==0)
1652          break;
1653        if(trorf->content==NULL)
1654          trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
1655        else
[9]1656          addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
[1]1657      }
1658      trorf=trorf->next;
1659    }
1660    m=&trorf;
1661  }
1662
[458]1663#ifdef WIN32
1664  extern char *url_encode(char *);
1665
1666  static char* getMapsAsKVP(maps* m,int length,int type){
1667    char *dataInputsKVP=(char*) malloc(length*sizeof(char));
1668    char *dataInputsKVPi=NULL;
1669    maps* curs=m;
1670    int i=0;
1671    while(curs!=NULL){
1672      map *inRequest=getMap(curs->content,"inRequest");
1673      map *hasLength=getMap(curs->content,"length");
1674      if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
1675         inRequest==NULL){
1676        if(i==0)
1677          if(type==0){
1678            sprintf(dataInputsKVP,"%s=",curs->name);
1679            if(hasLength!=NULL){
1680              dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
1681              sprintf(dataInputsKVPi,"%s=",curs->name);
1682            }
1683          }
1684          else
1685            sprintf(dataInputsKVP,"%s",curs->name);
1686        else{
1687          char *temp=zStrdup(dataInputsKVP);
1688          if(type==0)
1689            sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
1690          else
1691            sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
1692        }
1693        map* icurs=curs->content;
1694        if(type==0){
1695          char *temp=zStrdup(dataInputsKVP);
1696          if(getMap(curs->content,"xlink:href")!=NULL)
1697            sprintf(dataInputsKVP,"%sReference",temp);
1698          else{
1699            if(hasLength!=NULL){
[466]1700              int j;
1701              for(j=0;j<atoi(hasLength->value);j++){
[458]1702                map* tmp0=getMapArray(curs->content,"value",j);
1703                if(j==0)
1704                  free(temp);
1705                temp=zStrdup(dataInputsKVP);
1706                if(j==0)
1707                  sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
1708                else
1709                  sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
1710              }
1711            }
1712            else
1713              sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
1714          }
1715          free(temp);
1716        }
1717        while(icurs!=NULL){
1718          if(strncasecmp(icurs->name,"value",5)!=0 &&
1719             strncasecmp(icurs->name,"mimeType_",9)!=0 &&
1720             strncasecmp(icurs->name,"dataType_",9)!=0 &&
1721             strncasecmp(icurs->name,"size",4)!=0 &&
1722             strncasecmp(icurs->name,"length",4)!=0 &&
1723             strncasecmp(icurs->name,"isArray",7)!=0 &&
1724             strcasecmp(icurs->name,"Reference")!=0 &&
1725             strcasecmp(icurs->name,"minOccurs")!=0 &&
1726             strcasecmp(icurs->name,"maxOccurs")!=0 &&
1727             strncasecmp(icurs->name,"fmimeType",9)!=0 &&
1728             strcasecmp(icurs->name,"inRequest")!=0){
1729            char *itemp=zStrdup(dataInputsKVP);
1730            if(strcasecmp(icurs->name,"xlink:href")!=0)
1731              sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
1732            else
1733              sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
1734            free(itemp);
1735          }
1736          icurs=icurs->next;
1737        }
1738      }
1739      curs=curs->next;
1740      i++;
1741    }
1742    return dataInputsKVP;
1743  }
1744#endif
1745
[1]1746#ifdef __cplusplus
1747}
1748#endif
1749
1750#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