source: trunk/zoo-project/zoo-kernel/service.c @ 712

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

Added snprintf for Visual Studio compiler. In readVSIFile(), changed type of file_status variable to VSIStatBufL. Some minor changes neccessary for building on Windows, particularly in service_internal_php.c. Added PHP support in Windows makefile.

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