/* * Author : GĂ©rald FENOY * * Copyright (c) 2009-2015 GeoLabs SARL * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef ZOO_SERVICE_H #define ZOO_SERVICE_H 1 #pragma once #ifdef WIN32 #ifndef USE_MS #define strncasecmp _strnicmp #define strcasecmp _stricmp #endif #ifndef snprintf #define snprintf sprintf_s #endif #define zStrdup _strdup #define zMkdir _mkdir #define zOpen _open #define zWrite _write #define zSleep Sleep #include struct ztimeval { long tv_sec; /* seconds */ long tv_usec; /* and microseconds */ }; static int zGettimeofday(struct ztimeval* tp, void* tzp) { if (tp == 0) { return -1; } struct _timeb theTime; _ftime(&theTime); tp->tv_sec = theTime.time; tp->tv_usec = theTime.millitm * 1000; return 0; // The gettimeofday() function shall return 0 on success } #else /** * The crossplatform strdup alias */ #define zStrdup strdup /** * The crossplatform mkdir alias */ #define zMkdir mkdir /** * The crossplatform open alias */ #define zOpen open /** * The crossplatform write alias */ #define zWrite write /** * The crossplatform sleep alias */ #define zSleep sleep /** * The crossplatform gettimeofday alias */ #define zGettimeofday gettimeofday /** * The crossplatform timeval alias */ #define ztimeval timeval #endif #ifdef __cplusplus extern "C" { #endif #ifdef WIN32 #ifdef USE_MS #include #endif #endif #include #include #include #include #ifndef WIN32 #ifndef bool #define bool int #endif #ifndef true /** * Local true definition */ #define true 1 /** * Local false definition */ #define false -1 #endif #endif /** * The global accepted status for a service */ #define SERVICE_ACCEPTED 0 /** * The global started status for a service */ #define SERVICE_STARTED 1 /** * The global paused status for a service */ #define SERVICE_PAUSED 2 /** * The global succeeded status for a service */ #define SERVICE_SUCCEEDED 3 /** * The global failed status for a service */ #define SERVICE_FAILED 4 /** * The memory size to create an elements */ #define ELEMENTS_SIZE (sizeof(char*)+(((2*sizeof(char*))+sizeof(maps*))*2)+sizeof(char*)+(((2*sizeof(char*))+sizeof(iotype*))*2)+sizeof(elements*)) /** * The memory size to create a map */ #define MAP_SIZE (2*sizeof(char*))+sizeof(NULL) /** * The memory size to create an iotype */ #define IOTYPE_SIZE MAP_SIZE+sizeof(NULL) /** * The memory size to create a maps */ #define MAPS_SIZE (2*sizeof(char*))+sizeof(map*)+MAP_SIZE /** * The memory size to create a service */ #define SERVICE_SIZE (ELEMENTS_SIZE*2)+(MAP_SIZE*2)+sizeof(char*) #define SHMSZ 27 #include "version.h" #ifdef DEBUG_STACK void debugStack(const char* file,const int line){ int stack; fprintf(stderr,"stack %p (%s: %d) \n",&stack,file,line); } #endif /** * KVP linked list * * Deal with WPS KVP (name,value). * A map is defined as: * - name : a key, * - value: a value, * - next : a pointer to the next map if any. */ typedef struct map{ char* name; char* value; struct map* next; } map; #ifdef WIN32 #define NULLMAP ((map*) 0) #else #define NULLMAP NULL #endif /** * linked list of map pointer * * Small object to store WPS KVP set. * Maps is defined as: * - a name, * - a content map, * - a pointer to the next maps if any. */ typedef struct maps{ char* name; struct map* content; struct maps* next; } maps; /** * Dump a map on stderr * * @param t the map to dump */ static void _dumpMap(map* t){ if(t!=NULL){ fprintf(stderr,"%s: %s\n",t->name,t->value); fflush(stderr); }else{ fprintf(stderr,"NULL\n"); fflush(stderr); } } /** * Dump a map on stderr, see _dumpMap() * * @param t the map to dump */ static void dumpMap(map* t){ map* tmp=t; while(tmp!=NULL){ _dumpMap(tmp); tmp=tmp->next; } } /** * Dump a map to a file * * @param t the map to dump to file * @param file the file to store the map */ static void dumpMapToFile(map* t,FILE* file){ map* tmp=t; while(tmp!=NULL){ #ifdef DEBUG fprintf(stderr,"%s = %s\n",tmp->name,tmp->value); #endif fprintf(file,"%s = %s\n",tmp->name,tmp->value); tmp=tmp->next; } } /** * Dump a maps on stderr, see dumpMap(). * * @param m the map to dump */ static void dumpMaps(maps* m){ maps* tmp=m; while(tmp!=NULL){ fprintf(stderr,"MAP => [%s] \n",tmp->name); dumpMap(tmp->content); tmp=tmp->next; } } /** * Dump a maps to a file, see dumpMapToFile(). * * @param m the map to dump * @param file_path the full path to the file name to store the map */ static void dumpMapsToFile(maps* m,char* file_path){ FILE* file=fopen(file_path,"w"); maps* tmp=m; if(tmp!=NULL){ fprintf(file,"[%s]\n",tmp->name); dumpMapToFile(tmp->content,file); fflush(file); } fclose(file); } /** * Create a new map * * @param name the key to add to the map * @param value the corresponding value to add to the map * @return the allocated map */ static map* createMap(const char* name,const char* value){ map* tmp=(map *)malloc(MAP_SIZE); tmp->name=zStrdup(name); tmp->value=zStrdup(value); tmp->next=NULL; return tmp; } /** * Count number of map in a map * * @param m the maps to count * @return number of map in a map */ static int count(map* m){ map* tmp=m; int c=0; while(tmp!=NULL){ c++; tmp=tmp->next; } return c; } /** * Verify if a key exist in a map * * @param m the map to search for the key * @param key the key to search in the map * @return true if the key wwas found, false in other case */ static bool hasKey(map* m,const char *key){ map* tmp=m; while(tmp!=NULL){ if(strcasecmp(tmp->name,key)==0) return true; tmp=tmp->next; } #ifdef DEBUG_MAP fprintf(stderr,"NOT FOUND \n"); #endif return false; } /** * Access a specific maps * * @param m the maps to search for the key * @param key the key to search in the maps * @return a pointer on the maps found or NULL if not found */ static maps* getMaps(maps* m,const char *key){ maps* tmp=m; while(tmp!=NULL){ if(strcasecmp(tmp->name,key)==0){ return tmp; } tmp=tmp->next; } return NULL; } /** * Access a specific map * * @param m the map to search for the key * @param key the key to search in the map * @return a pointer on the map found or NULL if not found */ static map* getMap(map* m,const char *key){ map* tmp=m; while(tmp!=NULL){ if(strcasecmp(tmp->name,key)==0){ return tmp; } tmp=tmp->next; } return NULL; } /** * Access the last map * * @param m the map to search for the lastest map * @return a pointer on the lastest map found or NULL if not found */ static map* getLastMap(map* m){ map* tmp=m; while(tmp!=NULL){ if(tmp->next==NULL){ return tmp; } tmp=tmp->next; } return NULL; } /** * Access a specific map from a maps * * @param m the maps to search for the key * @param key the key to search in the maps * @param subkey the key to search in the map (found for the key, if any) * @return a pointer on the map found or NULL if not found */ static map* getMapFromMaps(maps* m,const char* key,const char* subkey){ maps* _tmpm=getMaps(m,key); if(_tmpm!=NULL){ map* _ztmpm=getMap(_tmpm->content,subkey); return _ztmpm; } else return NULL; } /** * Free allocated memory of a map. * Require to call free on mo after calling this function. * * @param mo the map to free */ static void freeMap(map** mo){ map* _cursor=*mo; if(_cursor!=NULL){ #ifdef DEBUG fprintf(stderr,"freeMap\n"); #endif free(_cursor->name); free(_cursor->value); if(_cursor->next!=NULL){ freeMap(&_cursor->next); free(_cursor->next); } } } /** * Free allocated memory of a maps. * Require to call free on mo after calling this function. * * @param mo the maps to free */ static void freeMaps(maps** mo){ maps* _cursor=*mo; if(_cursor && _cursor!=NULL){ #ifdef DEBUG fprintf(stderr,"freeMaps\n"); #endif free(_cursor->name); if(_cursor->content!=NULL){ freeMap(&_cursor->content); free(_cursor->content); } if(_cursor->next!=NULL){ freeMaps(&_cursor->next); free(_cursor->next); } } } /** * Not named linked list * * Used to store informations about formats, such as mimeType, encoding ... * * An iotype is defined as : * - a content map, * - a pointer to the next iotype if any. */ typedef struct iotype{ struct map* content; struct iotype* next; } iotype; /** * Metadata information about input or output. * * The elements are used to store metadata informations defined in the ZCFG. * * An elements is defined as: * - a name, * - a content map, * - a metadata map, * - a format (possible values are LiteralData, ComplexData or * BoundingBoxData), * - a default iotype, * - a pointer to the next elements id any. */ typedef struct elements{ char* name; struct map* content; struct map* metadata; char* format; struct iotype* defaults; struct iotype* supported; struct elements* next; } elements; /** * Metadata informations about a full Service. * * An element is defined as: * - a name, * - a content map, * - a metadata map, * - an inputs elements * - an outputs elements */ typedef struct service{ char* name; struct map* content; struct map* metadata; struct elements* inputs; struct elements* outputs; } service; /** * Multiple services chained list. */ typedef struct services{ struct service* content; struct services* next; } services; /** * Verify if an elements contains a name equal to the given key. * * @param e the elements to search for the key * @param key the elements name to search * @return true if the elements contains the name, false in other cases. */ static bool hasElement(elements* e,const char* key){ elements* tmp=e; while(tmp!=NULL){ if(strcasecmp(key,tmp->name)==0) return true; tmp=tmp->next; } return false; } /** * Access a specific elements named key. * * @param m the elements to search * @param key the elements name to search * @return a pointer to the specific element if found, NULL in other case. */ static elements* getElements(elements* m,char *key){ elements* tmp=m; while(tmp!=NULL){ if(strcasecmp(tmp->name,key)==0) return tmp; tmp=tmp->next; } return NULL; } /** * Free allocated memory of an iotype. * Require to call free on i after calling this function. * * @param i the iotype to free */ static void freeIOType(iotype** i){ iotype* _cursor=*i; if(_cursor!=NULL){ if(_cursor->next!=NULL){ freeIOType(&_cursor->next); free(_cursor->next); } freeMap(&_cursor->content); free(_cursor->content); } } /** * Free allocated memory of an elements. * Require to call free on e after calling this function. * * @param e the iotype to free */ static void freeElements(elements** e){ elements* tmp=*e; if(tmp!=NULL){ if(tmp->name!=NULL) free(tmp->name); freeMap(&tmp->content); if(tmp->content!=NULL) free(tmp->content); freeMap(&tmp->metadata); if(tmp->metadata!=NULL) free(tmp->metadata); if(tmp->format!=NULL) free(tmp->format); freeIOType(&tmp->defaults); if(tmp->defaults!=NULL) free(tmp->defaults); freeIOType(&tmp->supported); if(tmp->supported!=NULL){ free(tmp->supported); } freeElements(&tmp->next); if(tmp->next!=NULL) free(tmp->next); } } /** * Free allocated memory of a service. * Require to call free on e after calling this function. * * @param s the service to free */ static void freeService(service** s){ service* tmp=*s; if(tmp!=NULL){ if(tmp->name!=NULL) free(tmp->name); freeMap(&tmp->content); if(tmp->content!=NULL) free(tmp->content); freeMap(&tmp->metadata); if(tmp->metadata!=NULL) free(tmp->metadata); freeElements(&tmp->inputs); if(tmp->inputs!=NULL) free(tmp->inputs); freeElements(&tmp->outputs); if(tmp->outputs!=NULL) free(tmp->outputs); } } /** * Add key value pair to an existing map. * * @param m the map to add the KVP * @param n the key to add * @param v the corresponding value to add */ static void addToMap(map* m,const char* n,const char* v){ if(hasKey(m,n)==false){ map* _cursor=m; while(_cursor->next!=NULL){ _cursor=_cursor->next; } _cursor->next=createMap(n,v); } else{ map *tmp=getMap(m,n); if(tmp->value!=NULL) free(tmp->value); tmp->value=zStrdup(v); } } /** * Add a key and a binary value to an existing map. * * @param m the map to add the KVP * @param n the key to add * @param v the corresponding value to add * @param size the size of the given value */ static void addToMapWithSize(map* m,const char* n,const char* v,int size){ if(hasKey(m,n)==false){ map* _cursor=m; if(_cursor!=NULL){ addToMap(m,n,""); }else{ m=createMap(n,""); } } map *tmp=getMap(m,n); if(tmp->value!=NULL) free(tmp->value); tmp->value=(char*)malloc((size+1)*sizeof(char)); memmove(tmp->value,v,size*sizeof(char)); tmp->value[size]=0; char sin[128]; sprintf(sin,"%d",size); addToMap(m,"size",sin); } /** * Add a map at the end of another map. * * @param mo the map to add mi * @param mi the map to add to mo */ static void addMapToMap(map** mo,map* mi){ map* tmp=mi; map* _cursor=*mo; while(tmp!=NULL){ if(_cursor==NULL){ *mo=createMap(tmp->name,tmp->value); (*mo)->next=NULL; } else{ #ifdef DEBUG fprintf(stderr,"_CURSOR\n"); dumpMap(_cursor); #endif while(_cursor->next!=NULL) _cursor=_cursor->next; map* tmp1=getMap(*mo,tmp->name); if(tmp1==NULL){ _cursor->next=createMap(tmp->name,tmp->value); } else{ addToMap(*mo,tmp->name,tmp->value); } } _cursor=*mo; tmp=tmp->next; #ifdef DEBUG fprintf(stderr,"MO\n"); dumpMap(*mo); #endif } } /** * Add a map to iotype. * * @param io the iotype to add the map * @param mi the map to add to io */ static void addMapToIoType(iotype** io,map* mi){ iotype* tmp=*io; while(tmp->next!=NULL){ tmp=tmp->next; } tmp->next=(iotype*)malloc(IOTYPE_SIZE); tmp->next->content=NULL; addMapToMap(&tmp->next->content,mi); tmp->next->next=NULL; } /** * Access a specific map or set its value. * * @param m the map to search for the key * @param key the key to search/add in the map * @param value the value to add if the key does not exist * @return a pointer on the map found or NULL if not found */ static map* getMapOrFill(map** m,const char *key,const char* value){ map* tmp=*m; map* tmpMap=getMap(tmp,key); if(tmpMap==NULL){ if(tmp!=NULL){ addToMap((*m),key,value); } else (*m)=createMap(key,value); tmpMap=getMap(*m,key); } return tmpMap; } /** * Verify if a map is contained in another map. * * @param m the map to search for i * @param i the map to search in m * @return true if i was found in m, false in other case */ static bool contains(map* m,map* i){ while(i!=NULL){ if(strcasecmp(i->name,"value")!=0 && strcasecmp(i->name,"xlink:href")!=0 && strcasecmp(i->name,"useMapServer")!=0 && strcasecmp(i->name,"asReference")!=0){ map *tmp; if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL && strcasecmp(i->value,tmp->value)!=0) return false; } i=i->next; } return true; } /** * Access a specific iotype from an elements. * * @param e the elements to search for the name * @param name the name to search in the elements e * @param values the map to verify it was contained in the defaults or * supported content of the elements e * @return a pointer on the iotype found or NULL if not found */ static iotype* getIoTypeFromElement(elements* e,char *name, map* values){ elements* cursor=e; while(cursor!=NULL){ if(strcasecmp(cursor->name,name)==0){ if(contains(cursor->defaults->content,values)==true) return cursor->defaults; else{ iotype* tmp=cursor->supported; while(tmp!=NULL){ if(contains(tmp->content,values)==true) return tmp; tmp=tmp->next; } } } cursor=cursor->next; } return NULL; } /** * Load binary values from a map (in) and add them to another map (out) * * @param out the map to add binaries values * @param in the map containing the binary values to add ti out * @param pos index of the binary in an array (in case of "MapArray") */ static void loadMapBinary(map** out,map* in,int pos){ map* size=getMap(in,"size"); map *lout=*out; if(size!=NULL && pos>0){ char tmp[11]; sprintf(tmp,"size_%d",pos); size=getMap(in,tmp); sprintf(tmp,"value_%d",pos); map* tmpVin=getMap(in,tmp); map* tmpVout=getMap(lout,tmp); free(tmpVout->value); tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char)); memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char)); tmpVout->value[atoi(size->value)]=0; }else{ if(size!=NULL){ map* tmpVin=getMap(in,"value"); map* tmpVout=getMap(lout,"value"); free(tmpVout->value); tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char)); memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char)); tmpVout->value[atoi(size->value)]=0; } } } /** * Load binary values from a map (in) and add them to another map (out). * This function will take care of MapArray. * @see loadMapBinary * * @param out the map to add binaries values * @param in the map containing the binary values to add ti out */ static void loadMapBinaries(map** out,map* in){ map* size=getMap(in,"size"); map* length=getMap(in,"length"); if(length!=NULL){ int len=atoi(length->value); int i=0; for(i=0;iname=zStrdup(_cursor->name); res->content=NULL; res->next=NULL; map* mc=_cursor->content; if(mc!=NULL){ addMapToMap(&res->content,mc); loadMapBinaries(&res->content,mc); } res->next=dupMaps(&_cursor->next); } return res; } /** * Add a maps at the end of another maps. * * @see addMapToMap, dupMaps, getMaps * @param mo the maps to add mi * @param mi the maps to add to mo */ static void addMapsToMaps(maps** mo,maps* mi){ maps* tmp=mi; maps* _cursor=*mo; while(tmp!=NULL){ if(_cursor==NULL){ *mo=dupMaps(&mi); } else{ while(_cursor->next!=NULL) _cursor=_cursor->next; maps* tmp1=getMaps(*mo,tmp->name); if(tmp1==NULL) _cursor->next=dupMaps(&tmp); else addMapToMap(&tmp1->content,tmp->content); _cursor=*mo; } tmp=tmp->next; } } /** * Access a specific map array element * * @param m the map to search for the key * @param key the key to search in the map * @param index of the MapArray * @return a pointer on the map found or NULL if not found */ static map* getMapArray(map* m,const char* key,int index){ char tmp[1024]; if(index>0) sprintf(tmp,"%s_%d",key,index); else sprintf(tmp,"%s",key); #ifdef DEBUG fprintf(stderr,"** KEY %s\n",tmp); #endif map* tmpMap=getMap(m,tmp); #ifdef DEBUG if(tmpMap!=NULL) dumpMap(tmpMap); #endif return tmpMap; } /** * Add a key value in a MapArray for a specific index * * @param m the map to search for the key * @param key the key to search in the map * @param index the index of the MapArray * @param value the value to set in the MapArray * @return a pointer on the map found or NULL if not found */ static void setMapArray(map* m,const char* key,int index,const char* value){ char tmp[1024]; if(index>0){ sprintf(tmp,"%s_%d",key,index); map* len=getMap(m,"length"); if((len!=NULL && atoi(len->value)value); #endif map* ptr=getMapOrFill(&m,tmp,(char *)""); free(ptr->value); ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char)); memcpy(ptr->value,value,atoi(tmpSize->value)); } else addToMap(m,tmp,value); } /** * Access the map "type" * * @param mt the map * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in * other case */ static map* getMapType(map* mt){ map* tmap=getMap(mt,(char *)"mimeType"); if(tmap==NULL){ tmap=getMap(mt,"dataType"); if(tmap==NULL){ tmap=getMap(mt,"CRS"); } } #ifdef DEBUG dumpMap(tmap); #endif return tmap; } /** * Add a Maps containing a MapArray to a Maps * * @see getMapType * @param mo the maps * @param mi the maps * @param typ the map "type" * @return */ static int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){ maps* tmp=mi; maps* _cursor=getMaps(*mo,tmp->name); if(_cursor==NULL) return -1; map* tmpLength=getMap(_cursor->content,"length"); char tmpLen[10]; int len=1; if(tmpLength!=NULL){ len=atoi(tmpLength->value); } char *tmpV[11]={ (char*)"size", (char*)"value", (char*)"uom", (char*)"Reference", (char*)"cache_file", (char*)"fmimeType", (char*)"xlink:href", typ, (char*)"schema", (char*)"encoding", (char*)"isCached" }; sprintf(tmpLen,"%d",len+1); addToMap(_cursor->content,"length",tmpLen); int i=0; for(i=0;i<11;i++){ map* tmpVI=getMap(tmp->content,tmpV[i]); if(tmpVI!=NULL){ #ifdef DEBUG fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value); #endif if(i<7) setMapArray(_cursor->content,tmpV[i],len,tmpVI->value); else if(strncasecmp(tmpV[7],"mimeType",8)==0) setMapArray(_cursor->content,tmpV[i],len,tmpVI->value); } } addToMap(_cursor->content,"isArray","true"); return 0; } /** * Set a key value pair to a map contained in a Maps * * @param m the maps * @param key the maps name * @param subkey the map name included in the maps corresponding to key * @param value the corresponding value to add in the map */ static void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){ maps* _tmpm=getMaps(m,key); if(_tmpm!=NULL){ map* _ztmpm=getMap(_tmpm->content,subkey); if(_ztmpm!=NULL){ if(_ztmpm->value!=NULL) free(_ztmpm->value); _ztmpm->value=zStrdup(value); }else{ maps *tmp=(maps*)malloc(MAPS_SIZE); tmp->name=zStrdup(key); tmp->content=createMap(subkey,value); tmp->next=NULL; addMapsToMaps(&_tmpm,tmp); freeMaps(&tmp); free(tmp); } }else{ maps *tmp=(maps*)malloc(MAPS_SIZE); tmp->name=zStrdup(key); tmp->content=createMap(subkey,value); tmp->next=NULL; addMapsToMaps(&m,tmp); freeMaps(&tmp); free(tmp); } } /** * Dump an elements on stderr * * @param e the elements to dump */ static void dumpElements(elements* e){ elements* tmp=e; while(tmp!=NULL){ fprintf(stderr,"ELEMENT [%s]\n",tmp->name); fprintf(stderr," > CONTENT [%s]\n",tmp->name); dumpMap(tmp->content); fprintf(stderr," > METADATA [%s]\n",tmp->name); dumpMap(tmp->metadata); fprintf(stderr," > FORMAT [%s]\n",tmp->format); iotype* tmpio=tmp->defaults; int ioc=0; while(tmpio!=NULL){ fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc); dumpMap(tmpio->content); tmpio=tmpio->next; ioc++; } tmpio=tmp->supported; ioc=0; while(tmpio!=NULL){ fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc); dumpMap(tmpio->content); tmpio=tmpio->next; ioc++; } fprintf(stderr,"------------------\n"); tmp=tmp->next; } } /** * Dump an elements on stderr using the YAML syntaxe * * @param e the elements to dump */ static void dumpElementsAsYAML(elements* e){ elements* tmp=e; int i; while(tmp!=NULL){ for(i=0;i<2;i++) fprintf(stderr," "); fprintf(stderr,"%s:\n",tmp->name); map* mcurs=tmp->content; while(mcurs!=NULL){ for(i=0;i<4;i++) fprintf(stderr," "); _dumpMap(mcurs); mcurs=mcurs->next; } mcurs=tmp->metadata; if(mcurs!=NULL){ for(i=0;i<4;i++) fprintf(stderr," "); fprintf(stderr,"MetaData:\n"); while(mcurs!=NULL){ for(i=0;i<6;i++) fprintf(stderr," "); _dumpMap(mcurs); mcurs=mcurs->next; } } for(i=0;i<4;i++) fprintf(stderr," "); fprintf(stderr,"%s:\n",tmp->format); iotype* tmpio=tmp->defaults; int ioc=0; while(tmpio!=NULL){ for(i=0;i<6;i++) fprintf(stderr," "); fprintf(stderr,"default:\n"); mcurs=tmpio->content; while(mcurs!=NULL){ for(i=0;i<8;i++) fprintf(stderr," "); if(strcasecmp(mcurs->name,"range")==0){ fprintf(stderr,"range: \"%s\"\n",mcurs->value); }else _dumpMap(mcurs); mcurs=mcurs->next; } tmpio=tmpio->next; ioc++; } tmpio=tmp->supported; ioc=0; while(tmpio!=NULL){ for(i=0;i<6;i++) fprintf(stderr," "); fprintf(stderr,"supported:\n"); mcurs=tmpio->content; while(mcurs!=NULL){ for(i=0;i<8;i++) fprintf(stderr," "); if(strcasecmp(mcurs->name,"range")==0){ fprintf(stderr,"range: \"%s\"\n",mcurs->value); }else _dumpMap(mcurs); mcurs=mcurs->next; } tmpio=tmpio->next; ioc++; } tmp=tmp->next; } } /** * Duplicate an elements * * @param e the elements to clone * @return the allocated elements containing a copy of the elements e */ static elements* dupElements(elements* e){ elements* cursor=e; elements* tmp=NULL; if(cursor!=NULL){ #ifdef DEBUG fprintf(stderr,">> %s %i\n",__FILE__,__LINE__); dumpElements(e); fprintf(stderr,">> %s %i\n",__FILE__,__LINE__); #endif tmp=(elements*)malloc(ELEMENTS_SIZE); tmp->name=zStrdup(e->name); tmp->content=NULL; addMapToMap(&tmp->content,e->content); tmp->metadata=NULL; addMapToMap(&tmp->metadata,e->metadata); tmp->format=zStrdup(e->format); if(e->defaults!=NULL){ tmp->defaults=(iotype*)malloc(IOTYPE_SIZE); tmp->defaults->content=NULL; addMapToMap(&tmp->defaults->content,e->defaults->content); tmp->defaults->next=NULL; #ifdef DEBUG fprintf(stderr,">> %s %i\n",__FILE__,__LINE__); dumpMap(tmp->defaults->content); #endif }else tmp->defaults=NULL; if(e->supported!=NULL){ tmp->supported=(iotype*)malloc(IOTYPE_SIZE); tmp->supported->content=NULL; addMapToMap(&tmp->supported->content,e->supported->content); tmp->supported->next=NULL; iotype *tmp2=e->supported->next; while(tmp2!=NULL){ addMapToIoType(&tmp->supported,tmp2->content); #ifdef DEBUG fprintf(stderr,">> %s %i\n",__FILE__,__LINE__); dumpMap(tmp->defaults->content); #endif tmp2=tmp2->next; } } else tmp->supported=NULL; tmp->next=dupElements(cursor->next); } return tmp; } /** * Add an elements to another elements. * * @see dupElements * @param m the elements to add the e * @param e the elements to be added to m */ static void addToElements(elements** m,elements* e){ elements* tmp=e; if(*m==NULL){ *m=dupElements(tmp); }else{ addToElements(&(*m)->next,tmp); } } /** * Dump a service on stderr * * @param s the service to dump */ static void dumpService(service* s){ fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name); if(s->content!=NULL){ fprintf(stderr,"CONTENT MAP\n"); dumpMap(s->content); fprintf(stderr,"CONTENT METADATA\n"); dumpMap(s->metadata); } if(s->inputs!=NULL){ fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name); dumpElements(s->inputs); } if(s->outputs!=NULL){ fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name); dumpElements(s->outputs); } fprintf(stderr,"++++++++++++++++++\n"); } /** * Dump a service on stderr using the YAML syntaxe * * @param s the service to dump */ static void dumpServiceAsYAML(service* s){ int i; fprintf(stderr,"# %s\n\n",s->name); if(s->content!=NULL){ map* mcurs=s->content; dumpMap(mcurs); mcurs=s->metadata; if(mcurs!=NULL){ fprintf(stderr,"MetaData:\n"); while(mcurs!=NULL){ for(i=0;i<2;i++) fprintf(stderr," "); _dumpMap(mcurs); mcurs=mcurs->next; } } } if(s->inputs!=NULL){ fprintf(stderr,"\ninputs:\n"); dumpElementsAsYAML(s->inputs); } if(s->outputs!=NULL){ fprintf(stderr,"\noutputs:\n"); dumpElementsAsYAML(s->outputs); } } /** * Convert a maps to a char*** (only used for Fortran support) * * @param m the maps to convert * @param c the resulting array */ static void mapsToCharXXX(maps* m,char*** c){ maps* tm=m; int i=0; int j=0; char tmp[10][30][1024]; memset(tmp,0,1024*10*10); while(tm!=NULL){ if(i>=10) break; strcpy(tmp[i][j],"name"); j++; strcpy(tmp[i][j],tm->name); j++; map* tc=tm->content; while(tc!=NULL){ if(j>=30) break; strcpy(tmp[i][j],tc->name); j++; strcpy(tmp[i][j],tc->value); j++; tc=tc->next; } tm=tm->next; j=0; i++; } memcpy(c,tmp,10*10*1024); } /** * Convert a char*** to a maps (only used for Fortran support) * * @param c the array to convert * @param m the resulting maps */ static void charxxxToMaps(char*** c,maps**m){ maps* trorf=*m; int i,j; char tmp[10][30][1024]; memcpy(tmp,c,10*30*1024); for(i=0;i<10;i++){ if(strlen(tmp[i][1])==0) break; trorf->name=tmp[i][1]; trorf->content=NULL; trorf->next=NULL; for(j=2;j<29;j+=2){ if(strlen(tmp[i][j+1])==0) break; if(trorf->content==NULL) trorf->content=createMap(tmp[i][j],tmp[i][j+1]); else addToMap(trorf->content,tmp[i][j],tmp[i][j+1]); } trorf=trorf->next; } m=&trorf; } #ifdef WIN32 extern char *url_encode(char *); static char* getMapsAsKVP(maps* m,int length,int type){ char *dataInputsKVP=(char*) malloc(length*sizeof(char)); char *dataInputsKVPi=NULL; maps* curs=m; int i=0; while(curs!=NULL){ map *inRequest=getMap(curs->content,"inRequest"); map *hasLength=getMap(curs->content,"length"); if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) || inRequest==NULL){ if(i==0) if(type==0){ sprintf(dataInputsKVP,"%s=",curs->name); if(hasLength!=NULL){ dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char)); sprintf(dataInputsKVPi,"%s=",curs->name); } } else sprintf(dataInputsKVP,"%s",curs->name); else{ char *temp=zStrdup(dataInputsKVP); if(type==0) sprintf(dataInputsKVP,"%s;%s=",temp,curs->name); else sprintf(dataInputsKVP,"%s;%s",temp,curs->name); } map* icurs=curs->content; if(type==0){ char *temp=zStrdup(dataInputsKVP); if(getMap(curs->content,"xlink:href")!=NULL) sprintf(dataInputsKVP,"%sReference",temp); else{ if(hasLength!=NULL){ int j; for(j=0;jvalue);j++){ map* tmp0=getMapArray(curs->content,"value",j); if(j==0) free(temp); temp=zStrdup(dataInputsKVP); if(j==0) sprintf(dataInputsKVP,"%s%s",temp,tmp0->value); else sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value); } } else sprintf(dataInputsKVP,"%s%s",temp,icurs->value); } free(temp); } while(icurs!=NULL){ if(strncasecmp(icurs->name,"value",5)!=0 && strncasecmp(icurs->name,"mimeType_",9)!=0 && strncasecmp(icurs->name,"dataType_",9)!=0 && strncasecmp(icurs->name,"size",4)!=0 && strncasecmp(icurs->name,"length",4)!=0 && strncasecmp(icurs->name,"isArray",7)!=0 && strcasecmp(icurs->name,"Reference")!=0 && strcasecmp(icurs->name,"minOccurs")!=0 && strcasecmp(icurs->name,"maxOccurs")!=0 && strncasecmp(icurs->name,"fmimeType",9)!=0 && strcasecmp(icurs->name,"inRequest")!=0){ char *itemp=zStrdup(dataInputsKVP); if(strcasecmp(icurs->name,"xlink:href")!=0) sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value); else sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value)); free(itemp); } icurs=icurs->next; } } curs=curs->next; i++; } return dataInputsKVP; } #endif #ifdef __cplusplus } #endif #endif