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

Last change on this file since 601 was 601, checked in by knut, 9 years ago

Implemented default result file extensions for many MIME types, based on Apache's mime.types list. Added file mimetypes.h. Made function printIOType more general with respect to media content. Rewrote the XML parsing of the <ResponseDocument?> block in Execute requests to fix problem caused by one output variable inheriting properties from another. Minor memory allocation modification in zoo_loader.c.

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