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

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

Add initial doxygen comments in some C files, for future documentation generation.

  • 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