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

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

Redefined the API function addToMapWithSize to fix problem with Python/PHP support. Added some variable initializations and NULL pointer checks.

  • 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 * @return a pointer to the updated map m
458 */
459map* addToMapWithSize(map* m,const char* n,const char* v,int size){
460  if(hasKey(m,n)==false){
461    map* _cursor=m;
462    if(_cursor!=NULL){
463      addToMap(m,n,"");
464    }else{
465      m=createMap(n,"");
466    }
467  }
468  char sname[10]="size";
469  if(strlen(n)>5)
470    sprintf(sname,"size_%s",n+6);
471  map *tmp=getMap(m,n);
472  if(tmp->value!=NULL)
473    free(tmp->value);
474  tmp->value=(char*)malloc((size+1)*sizeof(char));
475  memmove(tmp->value,v,size*sizeof(char));
476  tmp->value[size]=0;
477  char sin[128];
478  sprintf(sin,"%d",size);
479  addToMap(m,sname,sin);
480  return m;
481}
482
483/**
484 * Add a map at the end of another map.
485 *
486 * @param mo the map to add mi
487 * @param mi the map to add to mo
488 */
489void addMapToMap(map** mo,map* mi){
490  map* tmp=mi;
491  map* _cursor=*mo;
492  while(tmp!=NULL){
493    if(_cursor==NULL){
494      *mo=createMap(tmp->name,tmp->value);
495      (*mo)->next=NULL;
496    }
497    else{
498#ifdef DEBUG
499      fprintf(stderr,"_CURSOR\n");
500      dumpMap(_cursor);
501#endif
502      while(_cursor->next!=NULL)
503        _cursor=_cursor->next;
504      map* tmp1=getMap(*mo,tmp->name);
505      if(tmp1==NULL){
506        _cursor->next=createMap(tmp->name,tmp->value);
507      }
508      else{
509        addToMap(*mo,tmp->name,tmp->value);
510      }
511    }
512    _cursor=*mo;
513    tmp=tmp->next;
514#ifdef DEBUG
515    fprintf(stderr,"MO\n");
516    dumpMap(*mo);
517#endif
518  }
519}
520
521/**
522 * Add a map to iotype.
523 *
524 * @param io the iotype to add the map
525 * @param mi the map to add to io
526 */
527void addMapToIoType(iotype** io,map* mi){
528  iotype* tmp=*io;
529  while(tmp->next!=NULL){
530    tmp=tmp->next;
531  }
532  tmp->next=(iotype*)malloc(IOTYPE_SIZE);
533  tmp->next->content=NULL;
534  addMapToMap(&tmp->next->content,mi);
535  tmp->next->next=NULL;
536}
537
538/**
539 * Access a specific map or set its value.
540 *
541 * @param m the map to search for the key
542 * @param key the key to search/add in the map
543 * @param value the value to add if the key does not exist
544 * @return a pointer on the map found or NULL if not found
545 */
546map* getMapOrFill(map** m,const char *key,const char* value){
547  map* tmp=*m;
548  map* tmpMap=getMap(tmp,key);
549  if(tmpMap==NULL){
550    if(tmp!=NULL){
551      addToMap((*m),key,value);
552    }
553    else
554      (*m)=createMap(key,value);
555    tmpMap=getMap(*m,key);
556  }
557  return tmpMap;
558}
559
560/**
561 * Verify if a map is contained in another map.
562 *
563 * @param m the map to search for i
564 * @param i the map to search in m
565 * @return true if i was found in m, false in other case
566 */
567bool contains(map* m,map* i){
568  while(i!=NULL){     
569    if(strcasecmp(i->name,"value")!=0 &&
570       strcasecmp(i->name,"xlink:href")!=0 &&
571       strcasecmp(i->name,"useMapServer")!=0 &&
572       strcasecmp(i->name,"asReference")!=0){
573      map *tmp;
574      if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL && 
575         strcasecmp(i->value,tmp->value)!=0)
576        return false;
577    }
578    i=i->next;
579  }
580  return true;
581}
582
583/**
584 * Access a specific iotype from an elements.
585 *
586 * @param e the elements to search for the name
587 * @param name the name to search in the elements e
588 * @param values the map to verify it was contained in the defaults or
589 *  supported content of the elements e
590 * @return a pointer on the iotype found or NULL if not found
591 */
592iotype* getIoTypeFromElement(elements* e,char *name, map* values){
593  elements* cursor=e;
594  while(cursor!=NULL){
595    if(strcasecmp(cursor->name,name)==0){
596      if(contains(cursor->defaults->content,values)==true)
597        return cursor->defaults;
598      else{
599        iotype* tmp=cursor->supported;
600        while(tmp!=NULL){
601          if(contains(tmp->content,values)==true)
602            return tmp;     
603          tmp=tmp->next;
604        }
605      }
606    }
607    cursor=cursor->next;
608  }
609  return NULL;
610}
611
612/**
613 * Load binary values from a map (in) and add them to another map (out)
614 *
615 * @param out the map to add binaries values
616 * @param in the map containing the binary values to add ti out
617 * @param pos index of the binary in an array (in case of "MapArray")
618 */
619void loadMapBinary(map** out,map* in,int pos){
620  map* size=getMap(in,"size");
621  map *lout=*out;
622  if(size!=NULL && pos>0){
623    char tmp[11];
624    sprintf(tmp,"size_%d",pos);
625    size=getMap(in,tmp);
626    sprintf(tmp,"value_%d",pos);
627    map* tmpVin=getMap(in,tmp);
628    map* tmpVout=getMap(lout,tmp);
629    free(tmpVout->value);
630    tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
631    memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
632    tmpVout->value[atoi(size->value)]=0;
633  }else{
634    if(size!=NULL){
635      map* tmpVin=getMap(in,"value");
636      map* tmpVout=getMap(lout,"value");
637      free(tmpVout->value);
638      tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
639      memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
640      tmpVout->value[atoi(size->value)]=0;
641    }
642  }
643}
644 
645/**
646 * Load binary values from a map (in) and add them to another map (out).
647 * This function will take care of MapArray.
648 * @see loadMapBinary
649 *
650 * @param out the map to add binaries values
651 * @param in the map containing the binary values to add ti out
652 */
653void loadMapBinaries(map** out,map* in){
654  map* size=getMap(in,"size");
655  map* length=getMap(in,"length");
656  if(length!=NULL){
657    int len=atoi(length->value);
658    int i=0;
659    for(i=0;i<len;i++){
660      loadMapBinary(out,in,i);
661    }
662  }
663  else
664    if(size!=NULL)
665      loadMapBinary(out,in,-1);
666}
667
668/**
669 * Duplicate a Maps
670 *
671 * @param mo the maps to clone
672 * @return the allocated maps containing a copy of the mo maps
673 */
674maps* dupMaps(maps** mo){
675  maps* _cursor=*mo;
676  maps* res=NULL;
677  if(_cursor!=NULL){
678    res=(maps*)malloc(MAPS_SIZE);
679    res->name=zStrdup(_cursor->name);
680    res->content=NULL;
681    res->next=NULL;
682    map* mc=_cursor->content;
683    if(mc!=NULL){
684      addMapToMap(&res->content,mc);
685      loadMapBinaries(&res->content,mc);
686    }
687    res->next=dupMaps(&_cursor->next);
688  }
689  return res;
690}
691
692/**
693 * Add a maps at the end of another maps.
694 *
695 * @see addMapToMap, dupMaps, getMaps
696 * @param mo the maps to add mi
697 * @param mi the maps to add to mo
698 */
699void addMapsToMaps(maps** mo,maps* mi){
700  maps* tmp=mi;
701  maps* _cursor=*mo;
702  while(tmp!=NULL){
703    if(_cursor==NULL){
704      *mo=dupMaps(&mi);
705    }
706    else{
707      while(_cursor->next!=NULL)
708        _cursor=_cursor->next;
709      maps* tmp1=getMaps(*mo,tmp->name);
710      if(tmp1==NULL)
711        _cursor->next=dupMaps(&tmp);
712      else
713        addMapToMap(&tmp1->content,tmp->content);
714      _cursor=*mo;
715    }
716    tmp=tmp->next;
717  }
718}
719
720/**
721 * Access a specific map array element
722 *
723 * @param m the map to search for the key
724 * @param key the key to search in the map
725 * @param index of the MapArray
726 * @return a pointer on the map found or NULL if not found
727 */
728map* getMapArray(map* m,const char* key,int index){
729  char tmp[1024];
730  if(index>0)
731    sprintf(tmp,"%s_%d",key,index);
732  else
733    sprintf(tmp,"%s",key);
734#ifdef DEBUG
735  fprintf(stderr,"** KEY %s\n",tmp);
736#endif
737  map* tmpMap=getMap(m,tmp);
738#ifdef DEBUG
739  if(tmpMap!=NULL)
740    dumpMap(tmpMap);
741#endif
742  return tmpMap;
743}
744
745/**
746 * Add a key value in a MapArray for a specific index
747 *
748 * @param m the map to search for the key
749 * @param key the key to search in the map
750 * @param index the index of the MapArray
751 * @param value the value to set in the MapArray
752 * @return a pointer on the map found or NULL if not found
753 */
754void setMapArray(map* m,const char* key,int index,const char* value){
755  char tmp[1024];
756  if(index>0){
757    sprintf(tmp,"%s_%d",key,index);
758    map* len=getMap(m,"length");
759    if((len!=NULL && atoi(len->value)<index+1) || len==NULL){
760      char tmp0[5];
761      sprintf(tmp0,"%d",index+1);
762      addToMap(m,"length",tmp0);
763    }
764  }
765  else
766    sprintf(tmp,"%s",key);
767  map* tmpSize=getMapArray(m,"size",index);
768  if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
769#ifdef DEBUG
770    fprintf(stderr,"%s\n",tmpSize->value);
771#endif
772    map* ptr=getMapOrFill(&m,tmp,(char *)"");
773    free(ptr->value);
774    ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
775    memcpy(ptr->value,value,atoi(tmpSize->value)); 
776  }
777  else
778    addToMap(m,tmp,value);
779}
780
781/**
782 * Access the map "type"
783 *
784 * @param mt the map
785 * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
786 *  other case
787 */
788map* getMapType(map* mt){
789  map* tmap=getMap(mt,(char *)"mimeType");
790  if(tmap==NULL){
791    tmap=getMap(mt,"dataType");
792    if(tmap==NULL){
793      tmap=getMap(mt,"CRS");
794    }
795  }
796#ifdef DEBUG
797  dumpMap(tmap);
798#endif
799  return tmap;
800}
801
802/**
803 * Add a Maps containing a MapArray to a Maps
804 *
805 * @see getMapType
806 * @param mo the maps
807 * @param mi the maps
808 * @param typ the map "type"
809 * @return
810 */
811int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
812  maps* tmp=mi;   
813  maps* _cursor=getMaps(*mo,tmp->name);
814
815  if(_cursor==NULL)
816    return -1;
817
818  map* tmpLength=getMap(_cursor->content,"length");
819  char tmpLen[10];
820  int len=1;
821  if(tmpLength!=NULL){
822    len=atoi(tmpLength->value);
823  }
824
825  char *tmpV[12]={
826    (char*)"size",
827    (char*)"value",
828    (char*)"uom",
829    (char*)"Reference",
830    (char*)"Order",
831    (char*)"cache_file",
832    (char*)"fmimeType",
833    (char*)"xlink:href",
834    typ,
835    (char*)"schema",
836    (char*)"encoding",
837    (char*)"isCached"
838  };
839  sprintf(tmpLen,"%d",len+1);
840  addToMap(_cursor->content,"length",tmpLen);
841  int i=0;
842  for(i=0;i<12;i++){
843    map* tmpVI=getMap(tmp->content,tmpV[i]);
844    if(tmpVI!=NULL){
845#ifdef DEBUG
846      fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
847#endif
848      setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
849    }
850  }
851   
852  addToMap(_cursor->content,"isArray","true");
853  return 0;
854}
855
856/**
857 * Set a key value pair to a map contained in a Maps
858 *
859 * @param m the maps
860 * @param key the maps name
861 * @param subkey the map name included in the maps corresponding to key
862 * @param value the corresponding value to add in the map
863 */
864void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
865  maps* _tmpm=getMaps(m,key);
866  if(_tmpm!=NULL){
867    map* _ztmpm=getMap(_tmpm->content,subkey);
868    if(_ztmpm!=NULL){
869      if(_ztmpm->value!=NULL)
870        free(_ztmpm->value);
871      _ztmpm->value=zStrdup(value);
872    }else{
873      maps *tmp=(maps*)malloc(MAPS_SIZE);
874      tmp->name=zStrdup(key);
875      tmp->content=createMap(subkey,value);
876      tmp->next=NULL;
877      addMapsToMaps(&_tmpm,tmp);
878      freeMaps(&tmp);
879      free(tmp);
880    }
881  }else{
882    maps *tmp=(maps*)malloc(MAPS_SIZE);
883    tmp->name=zStrdup(key);
884    tmp->content=createMap(subkey,value);
885    tmp->next=NULL;
886    addMapsToMaps(&m,tmp);
887    freeMaps(&tmp);
888    free(tmp);
889  }
890}
891
892/**
893 * Dump an elements on stderr
894 *
895 * @param e the elements to dump
896 */
897void dumpElements(elements* e){
898  elements* tmp=e;
899  while(tmp!=NULL){
900    fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
901    fprintf(stderr," > CONTENT [%s]\n",tmp->name);
902    dumpMap(tmp->content);
903    fprintf(stderr," > METADATA [%s]\n",tmp->name);
904    dumpMap(tmp->metadata);
905    fprintf(stderr," > FORMAT [%s]\n",tmp->format);
906    iotype* tmpio=tmp->defaults;
907    int ioc=0;
908    while(tmpio!=NULL){
909      fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
910      dumpMap(tmpio->content);
911      tmpio=tmpio->next;
912      ioc++;
913    }
914    tmpio=tmp->supported;
915    ioc=0;
916    while(tmpio!=NULL){
917      fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
918      dumpMap(tmpio->content);
919      tmpio=tmpio->next;
920      ioc++;
921    }
922    fprintf(stderr,"------------------\n");
923    tmp=tmp->next;
924  }
925}
926
927/**
928 * Dump an elements on stderr using the YAML syntaxe
929 *
930 * @param e the elements to dump
931 */
932void dumpElementsAsYAML(elements* e){
933  elements* tmp=e;
934  int i;
935  while(tmp!=NULL){
936    for(i=0;i<2;i++)
937      fprintf(stderr," ");
938    fprintf(stderr,"%s:\n",tmp->name);
939    map* mcurs=tmp->content;
940    while(mcurs!=NULL){
941      for(i=0;i<4;i++)
942        fprintf(stderr," ");
943      _dumpMap(mcurs);
944      mcurs=mcurs->next;
945    }
946    mcurs=tmp->metadata;
947    if(mcurs!=NULL){
948      for(i=0;i<4;i++)
949        fprintf(stderr," ");
950      fprintf(stderr,"MetaData:\n");
951      while(mcurs!=NULL){
952        for(i=0;i<6;i++)
953          fprintf(stderr," ");
954        _dumpMap(mcurs);
955        mcurs=mcurs->next;
956      }
957    }
958    for(i=0;i<4;i++)
959      fprintf(stderr," ");
960    fprintf(stderr,"%s:\n",tmp->format);
961    iotype* tmpio=tmp->defaults;
962    int ioc=0;
963    while(tmpio!=NULL){
964      for(i=0;i<6;i++)
965        fprintf(stderr," ");
966      fprintf(stderr,"default:\n");
967      mcurs=tmpio->content;
968      while(mcurs!=NULL){
969        for(i=0;i<8;i++)
970          fprintf(stderr," ");
971        if(strcasecmp(mcurs->name,"range")==0){
972          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
973        }else
974          _dumpMap(mcurs);
975        mcurs=mcurs->next;
976      }
977      tmpio=tmpio->next;
978      ioc++;
979    }
980    tmpio=tmp->supported;
981    ioc=0;
982    while(tmpio!=NULL){
983      for(i=0;i<6;i++)
984        fprintf(stderr," ");
985      fprintf(stderr,"supported:\n");
986      mcurs=tmpio->content;
987      while(mcurs!=NULL){
988        for(i=0;i<8;i++)
989          fprintf(stderr," ");
990        if(strcasecmp(mcurs->name,"range")==0){
991          fprintf(stderr,"range: \"%s\"\n",mcurs->value);
992        }else
993          _dumpMap(mcurs);
994        mcurs=mcurs->next;
995      }
996      tmpio=tmpio->next;
997      ioc++;
998    }
999    tmp=tmp->next;
1000  }
1001}
1002
1003/**
1004 * Duplicate an elements
1005 *
1006 * @param e the elements to clone
1007 * @return the allocated elements containing a copy of the elements e
1008 */
1009elements* dupElements(elements* e){
1010  elements* cursor=e;
1011  elements* tmp=NULL;
1012  if(cursor!=NULL){
1013#ifdef DEBUG
1014    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1015    dumpElements(e);
1016    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1017#endif
1018    tmp=(elements*)malloc(ELEMENTS_SIZE);
1019    tmp->name=zStrdup(e->name);
1020    tmp->content=NULL;
1021    addMapToMap(&tmp->content,e->content);
1022    tmp->metadata=NULL;
1023    addMapToMap(&tmp->metadata,e->metadata);
1024    if(e->format!=NULL)
1025      tmp->format=zStrdup(e->format);
1026    else
1027      tmp->format=NULL;
1028    if(e->defaults!=NULL){
1029      tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
1030      tmp->defaults->content=NULL;
1031      addMapToMap(&tmp->defaults->content,e->defaults->content);
1032      tmp->defaults->next=NULL;
1033#ifdef DEBUG
1034      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1035      dumpMap(tmp->defaults->content);
1036#endif
1037    }else
1038      tmp->defaults=NULL;
1039    if(e->supported!=NULL){
1040      tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
1041      tmp->supported->content=NULL;
1042      addMapToMap(&tmp->supported->content,e->supported->content);
1043      tmp->supported->next=NULL;
1044      iotype *tmp2=e->supported->next;
1045      while(tmp2!=NULL){
1046        addMapToIoType(&tmp->supported,tmp2->content);
1047#ifdef DEBUG
1048        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1049        dumpMap(tmp->defaults->content);
1050#endif
1051        tmp2=tmp2->next;
1052      }
1053    }
1054    else
1055      tmp->supported=NULL;
1056    tmp->next=dupElements(cursor->next);
1057  }
1058  return tmp;
1059}
1060
1061/**
1062 * Add an elements to another elements.
1063 *
1064 * @see dupElements
1065 * @param m the elements to add the e
1066 * @param e the elements to be added to m
1067 */
1068void addToElements(elements** m,elements* e){
1069  elements* tmp=e;
1070  if(*m==NULL){
1071    *m=dupElements(tmp);
1072  }else{
1073    addToElements(&(*m)->next,tmp);
1074  }
1075}
1076 
1077/**
1078 * Dump a service on stderr
1079 *
1080 * @param s the service to dump
1081 */
1082void dumpService(service* s){
1083  if(s==NULL)
1084    return;
1085  fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
1086  if(s->content!=NULL){
1087    fprintf(stderr,"CONTENT MAP\n");
1088    dumpMap(s->content);
1089    fprintf(stderr,"CONTENT METADATA\n");
1090    dumpMap(s->metadata);
1091  }
1092  if(s->inputs!=NULL){
1093    fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
1094    dumpElements(s->inputs);
1095  }
1096  if(s->outputs!=NULL){
1097    fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
1098    dumpElements(s->outputs);
1099  }
1100  fprintf(stderr,"++++++++++++++++++\n");
1101}
1102
1103/**
1104 * Dump a service on stderr using the YAML syntaxe
1105 *
1106 * @param s the service to dump
1107 */
1108void dumpServiceAsYAML(service* s){
1109  int i;
1110  fprintf(stderr,"# %s\n\n",s->name);
1111  if(s->content!=NULL){
1112    map* mcurs=s->content;
1113    dumpMap(mcurs);
1114    mcurs=s->metadata;
1115    if(mcurs!=NULL){
1116      fprintf(stderr,"MetaData:\n");
1117      while(mcurs!=NULL){
1118        for(i=0;i<2;i++)
1119          fprintf(stderr," ");
1120        _dumpMap(mcurs);
1121        mcurs=mcurs->next;
1122      }
1123    }
1124  }
1125  if(s->inputs!=NULL){
1126    fprintf(stderr,"\ninputs:\n");
1127    dumpElementsAsYAML(s->inputs);
1128  }
1129  if(s->outputs!=NULL){
1130    fprintf(stderr,"\noutputs:\n");
1131    dumpElementsAsYAML(s->outputs);
1132  }
1133}
1134
1135/**
1136 * Duplicate a service
1137 *
1138 * @param s the service to clone
1139 * @return the allocated service containing a copy of the serfvice s
1140 */
1141service* dupService(service* s){
1142  service *res=(service*)malloc(SERVICE_SIZE);
1143  res->name=zStrdup(s->name);
1144  res->content=NULL;
1145  addMapToMap(&res->content,s->content);
1146  res->metadata=NULL;
1147  addMapToMap(&res->metadata,s->metadata);
1148  res->inputs=dupElements(s->inputs);
1149  res->outputs=dupElements(s->outputs);
1150  return res;
1151}
1152
1153/**
1154 * Print the registry on stderr.
1155 *
1156 * @param r the registry
1157 */
1158void dumpRegistry(registry* r){
1159  registry* p=r;
1160  while(p!=NULL){
1161    fprintf(stderr,"%s \n",p->name);
1162    services* s=p->content;
1163    s=p->content;
1164    while(s!=NULL){
1165      dumpService(s->content);
1166      s=s->next;
1167    }
1168    p=p->next;
1169  }
1170}
1171
1172/**
1173 * Add a service to the registry
1174 *
1175 * @param reg the resgitry to add the service
1176 * @param name the registry name to update
1177 * @param content the service to add
1178 */
1179bool addServiceToRegistry(registry** reg,char* name,service* content){
1180  registry *l=*reg;
1181  int isInitial=-1;
1182  if(l==NULL){
1183    l=(registry*)malloc(REGISTRY_SIZE);
1184    isInitial=1;
1185  }
1186  if(l!=NULL){
1187    int hasLevel=-1;
1188    while(isInitial<0 && l!=NULL){
1189      if(l->name!=NULL && strcasecmp(name,l->name)==0){
1190        hasLevel=1;
1191        break;
1192      }
1193      l=l->next;
1194    }
1195    if(hasLevel<0){
1196      if(isInitial<0)
1197        l=(registry*)malloc(REGISTRY_SIZE);
1198      l->name=zStrdup(name);
1199      l->content=NULL;
1200      l->next=NULL;
1201    }
1202    if(l->content==NULL){
1203      l->content=(services*)malloc(SERVICES_SIZE);
1204      l->content->content=dupService(content);
1205      l->content->next=NULL;
1206    }
1207    else{
1208      services* s=l->content;
1209      while(s->next!=NULL)
1210        s=s->next;
1211      s->next=(services*)malloc(SERVICES_SIZE);
1212      s->next->content=dupService(content);
1213      s->next->next=NULL;
1214    }
1215    l->next=NULL;
1216    if(isInitial>0)
1217      *reg=l;
1218    else{
1219      registry *r=*reg;
1220      while(r->next!=NULL)
1221        r=r->next;
1222      r->next=l;
1223      r->next->next=NULL;
1224    }
1225    return true;
1226  }
1227  else
1228    return false;
1229}
1230
1231/**
1232 * Free memory allocated for the registry
1233 *
1234 * @param r the registry
1235 */
1236void freeRegistry(registry** r){
1237  registry* lr=*r;
1238  while(lr!=NULL){
1239    services* s=lr->content;
1240    free(lr->name);
1241    while(s!=NULL){
1242      service* s1=s->content;
1243      s=s->next;
1244      if(s1!=NULL){
1245        freeService(&s1);
1246        free(s1);
1247        s1=NULL;
1248      }
1249    }
1250    lr=lr->next;
1251  }   
1252}
1253
1254/**
1255 * Access a service in the registry
1256 *
1257 * @param r the registry
1258 * @param level the regitry to search ("concept", "generic" or "implementation")
1259 * @param sname the service name
1260 * @return the service pointer if a corresponding service was found or NULL
1261 */
1262service* getServiceFromRegistry(registry* r,char  *level,char* sname){
1263  registry *lr=r;
1264  while(lr!=NULL){
1265    if(strcasecmp(lr->name,level)==0){
1266      services* s=lr->content;
1267      while(s!=NULL){
1268        if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
1269          return s->content;
1270        s=s->next;
1271      }
1272      break;
1273    }
1274    lr=lr->next;
1275  }
1276  return NULL;
1277}
1278
1279/**
1280 * Apply inheritance to an out map from a reference in map
1281 *
1282 * @param out the map to update
1283 * @param in the reference map (containing inherited properties)
1284 */
1285void inheritMap(map** out,map* in){
1286  map* content=in;
1287  if((*out)==NULL){
1288    addMapToMap(out,in);
1289    return;
1290  }
1291  while(content!=NULL){
1292    map* cmap=getMap(*out,content->name);
1293    if(cmap==NULL)
1294      addToMap(*out,content->name,content->value);
1295    content=content->next;
1296  }
1297}
1298
1299/**
1300 * Apply inheritance to an out iotype from a reference in iotype
1301 *
1302 * @param out the iotype to update
1303 * @param in the reference iotype (containing inherited properties)
1304 */
1305void inheritIOType(iotype** out,iotype* in){
1306  iotype* io=in;
1307  iotype* oio=*out;
1308  if(io!=NULL){
1309    if(*out==NULL){
1310      *out=(iotype*)malloc(IOTYPE_SIZE);
1311      (*out)->content=NULL;
1312      addMapToMap(&(*out)->content,io->content);
1313      (*out)->next=NULL;
1314      oio=*out;
1315      inheritIOType(&oio->next,io->next);
1316    }else{
1317      inheritIOType(&oio->next,io->next);
1318    }
1319  }
1320}
1321
1322/**
1323 * Apply inheritance to an out elements from a reference in elements
1324 *
1325 * @param out the elements to update
1326 * @param in the reference elements (containing inherited properties)
1327 */
1328void inheritElements(elements** out,elements* in){
1329  elements* content=in;
1330  while(content!=NULL && *out!=NULL){
1331    elements* cmap=getElements(*out,content->name);
1332    if(cmap==NULL)
1333      addToElements(out,content);
1334    else{
1335      inheritMap(&cmap->content,content->content);
1336      inheritMap(&cmap->metadata,content->metadata);
1337      if(cmap->format==NULL && content->format!=NULL)
1338        cmap->format=zStrdup(content->format);
1339      inheritIOType(&cmap->defaults,content->defaults);
1340      if(cmap->supported==NULL)
1341        inheritIOType(&cmap->supported,content->supported);
1342      else{
1343        iotype* p=content->supported;
1344        while(p!=NULL){
1345          addMapToIoType(&cmap->supported,p->content);
1346          p=p->next;
1347        }
1348      }
1349    }
1350    content=content->next;
1351  }
1352}
1353
1354/**
1355 * Apply inheritance to a service based on a registry
1356 *
1357 * @param r the registry storing profiles hierarchy
1358 * @param s the service to update depending on its inheritance
1359 */
1360void inheritance(registry *r,service** s){
1361  if(r==NULL)
1362    return;
1363  service* ls=*s;
1364  if(ls->content==NULL)
1365    return;
1366  map* profile=getMap(ls->content,"extend");
1367  map* level=getMap(ls->content,"level");
1368  if(profile!=NULL&&level!=NULL){
1369    service* s1;
1370    if(strncasecmp(level->value,"profile",7)==0)
1371      s1=getServiceFromRegistry(r,(char*)"generic",profile->value);
1372    else
1373      s1=getServiceFromRegistry(r,level->value,profile->value);
1374     
1375    inheritMap(&ls->content,s1->content);
1376    inheritMap(&ls->metadata,s1->metadata);
1377    if(ls->inputs==NULL && s1->inputs!=NULL){
1378      ls->inputs=dupElements(s1->inputs);
1379    }else{
1380      inheritElements(&ls->inputs,s1->inputs);
1381    }
1382    if(ls->outputs==NULL && s1->outputs!=NULL){
1383      ls->outputs=dupElements(s1->outputs);
1384    }else
1385      inheritElements(&ls->outputs,s1->outputs);
1386  }
1387}
1388
1389/**
1390 * Convert a maps to a char*** (only used for Fortran support)
1391 *
1392 * @param m the maps to convert
1393 * @param c the resulting array
1394 */
1395void mapsToCharXXX(maps* m,char*** c){
1396  maps* tm=m;
1397  int i=0;
1398  int j=0;
1399  char tmp[10][30][1024];
1400  memset(tmp,0,1024*10*10);
1401  while(tm!=NULL){
1402    if(i>=10)
1403      break;
1404    strcpy(tmp[i][j],"name");
1405    j++;
1406    strcpy(tmp[i][j],tm->name);
1407    j++;
1408    map* tc=tm->content;
1409    while(tc!=NULL){
1410      if(j>=30)
1411        break;
1412      strcpy(tmp[i][j],tc->name);
1413      j++;
1414      strcpy(tmp[i][j],tc->value);
1415      j++;
1416      tc=tc->next;
1417    }
1418    tm=tm->next;
1419    j=0;
1420    i++;
1421  }
1422  memcpy(c,tmp,10*10*1024);
1423}
1424
1425/**
1426 * Convert a char*** to a maps (only used for Fortran support)
1427 *
1428 * @param c the array to convert
1429 * @param m the resulting maps
1430 */
1431void charxxxToMaps(char*** c,maps**m){
1432  maps* trorf=*m;
1433  int i,j;
1434  char tmp[10][30][1024];
1435  memcpy(tmp,c,10*30*1024);
1436  for(i=0;i<10;i++){
1437    if(strlen(tmp[i][1])==0)
1438      break;
1439    trorf->name=tmp[i][1];
1440    trorf->content=NULL;
1441    trorf->next=NULL;
1442    for(j=2;j<29;j+=2){
1443      if(strlen(tmp[i][j+1])==0)
1444        break;
1445      if(trorf->content==NULL)
1446        trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
1447      else
1448        addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
1449    }
1450    trorf=trorf->next;
1451  }
1452  m=&trorf;
1453}
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