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

Last change on this file was 984, checked in by djay, 3 years ago

Take into account building ZOO-Project on ubuntu focal (cf. https://trac.osgeo.org/osgeolive/ticket/2282). Add the OTB and SAGA support to the Dockerfile to make the corresponding demos using docker WPS server. Add OGC API - Processes demo to the demos list.

  • Property svn:keywords set to Id
File size: 47.5 KB
RevLine 
[645]1/*
2 * Author : Gérald FENOY
3 *
[917]4 * Copyright (c) 2015-2019 GeoLabs SARL
[645]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
[889]27// knut: time utilities required for new log function (logMessage)
28#include <ctime>
29#include <chrono>
[917]30#ifdef WIN32
[889]31#include <process.h>
[917]32#endif
[757]33
34#if defined(_MSC_VER) && _MSC_VER < 1800
[712]35#include <stdarg.h>
[645]36/**
[712]37 * snprintf for Visual Studio compiler.
38 *
39 * See https://dxr.mozilla.org/mozilla-central/source/media/mtransport/third_party/nrappkit/src/util/util.c
40 */
[967]41int snprintf(char *pcBuffer, size_t n, const char *pccFormat, ...)
[712]42{
43  va_list argp;
44  int ret;
[967]45  va_start(argp, pccFormat);
46  ret = _vscprintf(pccFormat, argp);
47  vsnprintf_s(pcBuffer, n, _TRUNCATE, pccFormat, argp);
[712]48  va_end(argp);
49  return ret;
50}
51#endif
52
53/**
[645]54 * Dump a map on stderr
55 *
[967]56 * @param pmMap the map to dump
[645]57 */
[967]58void _dumpMap(map* pmMap){
59  if(pmMap!=NULL){
60    fprintf(stderr,"%s: %s\n",pmMap->name,pmMap->value);
[645]61    fflush(stderr);
62  }else{
63    fprintf(stderr,"NULL\n");
64    fflush(stderr);
65  }
66}
67
68/**
69 * Dump a map on stderr, see _dumpMap()
70 *
[967]71 * @param pmMap the map to dump
[645]72 */
[967]73void dumpMap(map* pmMap){
74  map* pmTmp=pmMap;
75  while(pmTmp!=NULL){
76    _dumpMap(pmTmp);
77    pmTmp=pmTmp->next;
[645]78  }
79}
80
81/**
[790]82 * Dump a map to a file
[645]83 *
[967]84 * @param pmMap the map to dump to file
85 * @param pfFile the file pointer to store the map
[645]86 */
[967]87void dumpMapToFile(map* pmMap,FILE* pfFile){
88  map* pmTmp=pmMap;
89  while(pmTmp!=NULL){
90    fprintf(pfFile,"%s = %s\n",pmTmp->name,pmTmp->value);
91    pmTmp=pmTmp->next;
[645]92  }
93}
94
95/**
96 * Dump a maps on stderr, see dumpMap().
97 *
[967]98 * @param pmMap the map to dump
[645]99 */
[967]100void dumpMaps(maps* pmMap){
101  maps* pmTmp=pmMap;
102  while(pmTmp!=NULL){
103    fprintf(stderr,"MAP => [%s] \n",pmTmp->name);
104    fprintf(stderr," * CONTENT [%s] \n",pmTmp->name);
105    dumpMap(pmTmp->content);
106    if(pmTmp->child!=NULL){
107      fprintf(stderr," * CHILD [%s] \n",pmTmp->name);
108      dumpMaps(pmTmp->child);
109      fprintf(stderr," * /CHILD [%s] \n",pmTmp->name);
[917]110    }
[967]111    pmTmp=pmTmp->next;
[645]112  }
113}
114
115/**
116 * Dump a maps to a file, see dumpMapToFile().
117 *
[967]118 * @param pmsMaps the map to dump
119 * @param psFile the the file pointer to store the map
120 * @param iLimit the number of maps to print (0 for no limit)
[645]121 */
[967]122void _dumpMapsToFile(maps* pmsMaps,FILE* psFile,int iLimit){
123  maps* tmp=pmsMaps;
[682]124  int cnt=0;
[652]125  while(tmp!=NULL){
[967]126    fprintf(psFile,"[%s]\n",tmp->name);
[790]127    if(tmp->child!=NULL){
[967]128      _dumpMapsToFile(tmp->child,psFile,iLimit);
[790]129    }else
[967]130      dumpMapToFile(tmp->content,psFile);
131    fflush(psFile);
[652]132    tmp=tmp->next;
[955]133    cnt++;
[967]134    if(iLimit>=0 && cnt==iLimit)
[682]135      tmp=NULL;
[645]136  }
[967]137  fflush(psFile);
[790]138}
139
140/**
141 * Dump a maps to a file, see _dumpMapsToFile().
142 *
[967]143 * @param pmsMaps the map to dump
144 * @param pcaFilePath the the file pointer to store the map
145 * @param iLimit the number of maps to print (0 for no limit)
[790]146 */
[967]147void dumpMapsToFile(maps* pmsMaps,char* pcaFilePath,int iLimit){
148  FILE* psFile=fopen(pcaFilePath,"w+");
149  _dumpMapsToFile(pmsMaps,psFile,iLimit);
150  fflush(psFile);
151  fclose(psFile);
[652]152}
[680]153
[645]154/**
[917]155 * Create a new iotype*
156 *
157 * @return a pointer to the allocated iotype
158 */
159iotype* createIoType(){
[967]160  iotype* pioIO=(iotype*)malloc(IOTYPE_SIZE);
161  pioIO->content=NULL;
162  pioIO->next=NULL;
163  return pioIO;
[917]164}
165
166/**
[645]167 * Create a new map
168 *
[967]169 * @param pccName the key to add to the map
170 * @param pccValue the corresponding value to add to the map
[790]171 * @return a pointer to the allocated map
[645]172 */
[967]173map* createMap(const char* pccName,const char* pccValue){
174  map* pmTtmp=(map *)malloc(MAP_SIZE);
175  pmTtmp->name=zStrdup(pccName);
176  pmTtmp->value=zStrdup(pccValue);
177  pmTtmp->next=NULL;
178  return pmTtmp;
[645]179}
180
181/**
[790]182 * Create a new maps with the given name
183 *
[967]184 * @param pccName of the maps
[790]185 * @return the allocated map
186 */
[967]187maps* createMaps(const char* pccName){
188  maps* pmTmp = (maps *) malloc (MAPS_SIZE);
189  pmTmp->name = zStrdup (pccName);
190  pmTmp->content = NULL;
191  pmTmp->child = NULL;
192  pmTmp->next = NULL;
193  return pmTmp;
[790]194}
195
196/**
[645]197 * Count number of map in a map
198 *
[967]199 * @param pmMap the map to count
[645]200 * @return number of map in a map
201 */
[967]202int count(map* pmMap){
203  map* pmTmp=pmMap;
[645]204  int c=0;
[967]205  while(pmTmp!=NULL){
[645]206    c++;
[967]207    pmTmp=pmTmp->next;
[645]208  }
209  return c;
210}
211
212/**
[917]213 * Count number of maps in a maps
214 *
[967]215 * @param pmMap the maps to count
[917]216 * @return number of maps in a maps
217 */
[967]218int maps_length(maps* pmMap){
219  maps* pmTmp=pmMap;
[917]220  int c=0;
[967]221  while(pmTmp!=NULL){
[917]222    c++;
[967]223    pmTmp=pmTmp->next;
[917]224  }
225  return c;
226}
227
228/**
[645]229 * Verify if a key exist in a map
230 *
[967]231 * @param pmMap the map to search for the key
232 * @param pccKey the key to search in the map
[645]233 * @return true if the key wwas found, false in other case
234 */
[967]235bool hasKey(map* pmMap,const char *pccKey){
236  map* pmTmp=pmMap;
237  while(pmTmp!=NULL){
238    if(strcasecmp(pmTmp->name,pccKey)==0)
[645]239      return true;
[967]240    pmTmp=pmTmp->next;
[645]241  }
242#ifdef DEBUG_MAP
243  fprintf(stderr,"NOT FOUND \n");
244#endif
245  return false;
246}
247
248/**
249 * Access a specific maps
250 *
[967]251 * @param pmMap the maps to search for the key
252 * @param pccKey the key to search in the maps
[645]253 * @return a pointer on the maps found or NULL if not found
254 */
[967]255maps* getMaps(maps* pmsMaps,const char *pccKey){
256  maps* pmTmp=pmsMaps;
257  while(pmTmp!=NULL){
258    if(strcasecmp(pmTmp->name,pccKey)==0){
259      return pmTmp;
[645]260    }
[967]261    pmTmp=pmTmp->next;
[645]262  }
263  return NULL;
264}
265
266/**
267 * Access a specific map
268 *
[967]269 * @param pmMap the map to search for the key
270 * @param pccKey the key to search in the map
[645]271 * @return a pointer on the map found or NULL if not found
272 */
[967]273map* getMap(map* pmMap,const char *pccKey){
274  map* pmTmp=pmMap;
275  while(pmTmp!=NULL){
276    if(strcasecmp(pmTmp->name,pccKey)==0){
277      return pmTmp;
[645]278    }
[967]279    pmTmp=pmTmp->next;
[645]280  }
281  return NULL;
282}
283
284
285/**
286 * Access the last map
287 *
[967]288 * @param pmMap the map to search for the lastest map
[645]289 * @return a pointer on the lastest map found or NULL if not found
290 */
[967]291map* getLastMap(map* pmMap){
292  map* pmTmp=pmMap;
293  while(pmTmp!=NULL){
294    if(pmTmp->next==NULL){
295      return pmTmp;
[645]296    }
[967]297    pmTmp=pmTmp->next;
[645]298  }
299  return NULL;
300}
301
302/**
303 * Access a specific map from a maps
304 *
[967]305 * @param pmMap the maps to search for the key
306 * @param pccKey the key to search in the maps
307 * @param pccSubkey the key to search in the map (found for the key, if any)
[645]308 * @return a pointer on the map found or NULL if not found
309 */
[967]310map* getMapFromMaps(maps* pmMap,const char* pccKey,const char* pccSubkey){
311  maps* pmTmp=getMaps(pmMap,pccKey);
312  if(pmTmp!=NULL){
313    map* pmTmp1=getMap(pmTmp->content,pccSubkey);
314    return pmTmp1;
[645]315  }
316  else return NULL;
317}
318
319/**
320 * Free allocated memory of a map.
321 * Require to call free on mo after calling this function.
322 *
[967]323 * @param pmMap the map to free
[645]324 */
[967]325void freeMap(map** pmMap){
326  map* pmCursor=*pmMap;
327  if(pmCursor!=NULL){
[645]328#ifdef DEBUG
329    fprintf(stderr,"freeMap\n");
330#endif
[967]331    if(pmCursor->name!=NULL)
332      free(pmCursor->name);
333    if(pmCursor->value!=NULL)
334      free(pmCursor->value);
335    if(pmCursor->next!=NULL){
336      freeMap(&pmCursor->next);
337      if(pmCursor->next!=NULL)
338        free(pmCursor->next);
[645]339    }
340  }
341}
342
343/**
344 * Free allocated memory of a maps.
345 * Require to call free on mo after calling this function.
346 *
[967]347 * @param pmMap the maps to free
[645]348 */
[967]349void freeMaps(maps** pmMap){
350  maps* pmCursor=*pmMap;
351  if(pmCursor && pmCursor!=NULL){
[645]352#ifdef DEBUG
353    fprintf(stderr,"freeMaps\n");
354#endif
[967]355    free(pmCursor->name);
356    if(pmCursor->content!=NULL){
357      freeMap(&pmCursor->content);
358      free(pmCursor->content);
[645]359    }
[967]360    if(pmCursor->child!=NULL){
361      freeMaps(&pmCursor->child);
362      free(pmCursor->child);
[790]363    }
[967]364    if(pmCursor->next!=NULL){
365      freeMaps(&pmCursor->next);
366      free(pmCursor->next);
[645]367    }
368  }
369}
370
371/**
372 * Verify if an elements contains a name equal to the given key.
373 *
[967]374 * @param peElem the elements to search for the key
375 * @param pccKey the elements name to search
[645]376 * @return true if the elements contains the name, false in other cases.
377 */ 
[967]378bool hasElement(elements* peElem,const char* pccKey){
379  elements* peTmp=peElem;
380  while(peTmp!=NULL){
381    if(strcasecmp(pccKey,peTmp->name)==0)
[645]382      return true;
[967]383    peTmp=peTmp->next;
[645]384  }
385  return false;
386}
387
388/**
389 * Access a specific elements named key.
390 *
[967]391 * @param peElem the elements to search
392 * @param pccKey the elements name to search
[645]393 * @return a pointer to the specific element if found, NULL in other case.
394 */ 
[967]395elements* getElements(elements* peElem,const char *pccKey){
396  elements* peTmp=peElem;
397  while(peTmp!=NULL){
398    if(strcasecmp(peTmp->name,pccKey)==0)
399      return peTmp;
400    peTmp=peTmp->next;
[645]401  }
402  return NULL;
403}
404
405/**
406 * Free allocated memory of an iotype.
407 * Require to call free on i after calling this function.
408 *
[967]409 * @param piotIO the iotype to free
[645]410 */
[967]411void freeIOType(iotype** piotIO){
412  iotype* piotCursor=*piotIO;
413  if(piotCursor!=NULL){
414    if(piotCursor->next!=NULL){
415      freeIOType(&piotCursor->next);
416      free(piotCursor->next);
[645]417    }
[967]418    freeMap(&piotCursor->content);
419    free(piotCursor->content);
[645]420  }
421}
422
423/**
424 * Free allocated memory of an elements.
425 * Require to call free on e after calling this function.
426 *
[967]427 * @param peElem the iotype to free
[645]428 */
[967]429void freeElements(elements** peElem){
430  elements* peTmp=*peElem;
431  if(peTmp!=NULL){
432    if(peTmp->name!=NULL)
433      free(peTmp->name);
434    freeMap(&peTmp->content);
435    if(peTmp->content!=NULL)
436      free(peTmp->content);
437    freeMap(&peTmp->metadata);
438    if(peTmp->metadata!=NULL)
439      free(peTmp->metadata);
440    freeMap(&peTmp->additional_parameters);
441    if(peTmp->additional_parameters!=NULL)
442      free(peTmp->additional_parameters);
443    if(peTmp->format!=NULL)
444      free(peTmp->format);
445    freeElements(&peTmp->child);
446    if(peTmp->child!=NULL){
447      free(peTmp->child);
[790]448    }
[967]449    if(peTmp->defaults!=NULL){
450      freeIOType(&peTmp->defaults);
451      free(peTmp->defaults);
[917]452    }
[967]453    if(peTmp->supported!=NULL){
454      freeIOType(&peTmp->supported);
455      free(peTmp->supported);
[645]456    }
[967]457    if(peTmp->next!=NULL){
458      freeElements(&peTmp->next);
459      free(peTmp->next);
[917]460    }
[645]461  }
462}
463
[917]464
[645]465/**
[917]466 * Allocate memory for a service.
467 * Require to call free after calling this function.
468 *
469 * @return the service
470 */
471service* createService(){
[967]472  service *psService = (service *) malloc (SERVICE_SIZE);
473  psService->name=NULL;
474  psService->content=NULL;
475  psService->metadata=NULL;
476  psService->additional_parameters=NULL;
477  psService->inputs=NULL;
478  psService->outputs=NULL;
479  return psService;
[917]480}
481
482/**
[645]483 * Free allocated memory of a service.
[917]484 * Require to be invoked for every createService call.
[645]485 *
[967]486 * @param psService the service to free
[645]487 */
[967]488void freeService(service** psService){
489  service* psTmp=*psService;
490  if(psTmp!=NULL){
491    if(psTmp->name!=NULL)
492      free(psTmp->name);
493    freeMap(&psTmp->content);
494    if(psTmp->content!=NULL)
495      free(psTmp->content);
496    freeMap(&psTmp->metadata);
497    if(psTmp->metadata!=NULL)
498      free(psTmp->metadata);
499    freeMap(&psTmp->additional_parameters);
500    if(psTmp->additional_parameters!=NULL)
501      free(psTmp->additional_parameters);
502    freeElements(&psTmp->inputs);
503    if(psTmp->inputs!=NULL)
504      free(psTmp->inputs);
505    freeElements(&psTmp->outputs);
506    if(psTmp->outputs!=NULL)
507      free(psTmp->outputs);
[645]508  }
509}
510
511/**
512 * Add key value pair to an existing map.
513 *
[967]514 * @param pMap the map to add the KVP
515 * @param pccName the key to add
516 * @param pccValue the corresponding value to add
[645]517 */
[967]518void addToMap(map* pMap,const char* pccName,const char* pccValue){
519  if (pMap != NULL) { // knut: add NULL-pointer check
520    if (hasKey(pMap, pccName) == false) {
521      map* pmCursor = pMap;
522      while (pmCursor->next != NULL) {
523        pmCursor = pmCursor->next;
524      }
525      pmCursor->next = createMap(pccName, pccValue);
[645]526    }
[967]527    else {
528      map *tmp = getMap(pMap, pccName);
529      if (tmp->value != NULL)
530        free(tmp->value);
531      tmp->value = zStrdup(pccValue);
532    }
533  }
[645]534}
535
536/**
537 * Add a key and an integer value to an existing map.
538 *
[967]539 * @param pMap the map to add the KVP
540 * @param pccName the key to add
541 * @param iValue the corresponding value to add
[645]542 */
[967]543void addIntToMap(map* pMap,const char* pccName,const int iValue){
544  char acValue[10];
545  sprintf(acValue,"%d",iValue);
546  if(hasKey(pMap,pccName)==false){
547    map* pmCursor=pMap;
548    while(pmCursor->next!=NULL){
549      pmCursor=pmCursor->next;
[645]550    }
[967]551    pmCursor->next=createMap(pccName,acValue);
[645]552  }
553  else{
[967]554    map *pmTmp=getMap(pMap,pccName);
555    if(pmTmp->value!=NULL)
556      free(pmTmp->value);
557    pmTmp->value=zStrdup(acValue);
[645]558  }
559}
560
561/**
562 * Add a key and a binary value to an existing map.
563 *
[967]564 * @param pMap the map to add the KVP
565 * @param pccName the key to add
566 * @param pccValue the corresponding value to add
567 * @param iSize the size of the given value
[738]568 * @return a pointer to the updated map m
[645]569 */
[967]570map* addToMapWithSize(map* pMap,const char* pccName,const char* pccValue,int iSize){
571  char acIn[128];
572  char acName[10]="size";
573  map *pmTmp;
574  if(hasKey(pMap,pccName)==false){
575    map* _cursor=pMap;
[645]576    if(_cursor!=NULL){
[967]577      addToMap(pMap,pccName,"");
[645]578    }else{
[967]579      pMap=createMap(pccName,"");
[645]580    }
581  }
[967]582  if(strlen(pccName)>5)
583    sprintf(acName,"size_%s",pccName+6);
584  pmTmp=getMap(pMap,pccName);
585  if(pmTmp->value!=NULL)
586    free(pmTmp->value);
587  pmTmp->value=(char*)malloc((iSize+1)*sizeof(char));
588  if(pccValue!=NULL)
589    memmove(pmTmp->value,pccValue,iSize*sizeof(char));
590  pmTmp->value[iSize]=0;
591  sprintf(acIn,"%d",iSize);
592  addToMap(pMap,acName,acIn);
593  return pMap;
[645]594}
595
596/**
597 * Add a map at the end of another map.
598 *
[967]599 * @param pmMapOut the map to add pmMapIn to
600 * @param pmMapIn the map to add to pmMapOut
[645]601 */
[967]602void addMapToMap(map** pmMapOut,map* pmMapIn){
603  map* pmTmp=pmMapIn;
604  map* pmCursor=*pmMapOut;
605  while(pmTmp!=NULL){
606    if(pmCursor==NULL){
607      *pmMapOut=createMap(pmTmp->name,pmTmp->value);
608      (*pmMapOut)->next=NULL;
[645]609    }
610    else{
[967]611      map* pmTmp1=getMap(*pmMapOut,pmTmp->name);
612      if(pmTmp1==NULL){
613        while(pmCursor->next!=NULL)
614          pmCursor=pmCursor->next;
615        pmCursor->next=createMap(pmTmp->name,pmTmp->value);
[645]616      }
617      else{
[967]618        addToMap(*pmMapOut,pmTmp->name,pmTmp->value);
[645]619      }
620    }
[967]621    pmCursor=*pmMapOut;
622    pmTmp=pmTmp->next;
[645]623  }
624}
625
626/**
627 * Add a map to iotype.
628 *
[967]629 * @param piotType the iotype to add the map
630 * @param pmMap the map to add to io
[645]631 */
[967]632void addMapToIoType(iotype** piotType,map* pmMap){
633  iotype* piotTmp=*piotType;
634  while(piotTmp->next!=NULL){
635    piotTmp=piotTmp->next;
[645]636  }
[967]637  piotTmp->next=(iotype*)malloc(IOTYPE_SIZE);
638  piotTmp->next->content=NULL;
639  addMapToMap(&piotTmp->next->content,pmMap);
640  piotTmp->next->next=NULL;
[645]641}
642
643/**
644 * Access a specific map or set its value.
645 *
[967]646 * @param ppmMap the map to search for the key
647 * @param pccKey the key to search/add in the map
648 * @param pccValue the value to add if the key does not exist
[645]649 * @return a pointer on the map found or NULL if not found
650 */
[967]651map* getMapOrFill(map** ppmMap,const char *pccKey,const char* pccValue){
652  map* pmTmp=*ppmMap;
653  map* pmTmp1=getMap(pmTmp,pccKey);
654  if(pmTmp1==NULL){
655    if(pmTmp!=NULL){
656      addToMap((*ppmMap),pccKey,pccValue);
[645]657    }
658    else
[967]659      (*ppmMap)=createMap(pccKey,pccValue);
660    pmTmp1=getMap(*ppmMap,pccKey);
[645]661  }
[967]662  return pmTmp1;
[645]663}
664
665/**
666 * Verify if a map is contained in another map.
667 *
[967]668 * @param pmMap the map to search for i
669 * @param pmSearch the map to search in m
[645]670 * @return true if i was found in m, false in other case
671 */
[967]672bool contains(map* pmMap,map* pmSearch){
673  while(pmSearch!=NULL){     
674    if(strcasecmp(pmSearch->name,"value")!=0 &&
675       strcasecmp(pmSearch->name,"xlink:href")!=0 &&
676       strcasecmp(pmSearch->name,"useMapServer")!=0 &&
677       strcasecmp(pmSearch->name,"asReference")!=0){
[645]678      map *tmp;
[967]679      if(hasKey(pmMap,pmSearch->name) &&
680         (tmp=getMap(pmMap,pmSearch->name))!=NULL && 
681         strcasecmp(pmSearch->value,tmp->value)!=0)
[645]682        return false;
683    }
[967]684    pmSearch=pmSearch->next;
[645]685  }
686  return true;
687}
688
689/**
690 * Access a specific iotype from an elements.
691 *
[967]692 * @param peElem the elements to search for the name
693 * @param pcName the name to search in the elements e
694 * @param pcValues the map to verify it was contained in the defaults or
[645]695 *  supported content of the elements e
696 * @return a pointer on the iotype found or NULL if not found
697 */
[967]698iotype* getIoTypeFromElement(elements* peElem,char *pcName, map* pcValues){
699  elements* peCursor=peElem;
700  if(pcValues!=NULL){
701    while(peCursor!=NULL){
702      if(strcasecmp(peCursor->name,pcName)==0 && (peCursor->defaults!=NULL || peCursor->supported!=NULL)){
703        if(contains(peCursor->defaults->content,pcValues)==true)
704          return peCursor->defaults;
[790]705        else{
[967]706          iotype* tmp=peCursor->supported;
[790]707          while(tmp!=NULL){
[967]708            if(contains(tmp->content,pcValues)==true)
[790]709              return tmp;           
710            tmp=tmp->next;
711          }
[645]712        }
713      }
[967]714      peCursor=peCursor->next;
[645]715    }
[805]716  }else{
[967]717    while(peCursor!=NULL){
718      if(strcasecmp(peCursor->name,pcName)==0 && peCursor->defaults!=NULL){
719        return peCursor->defaults;
[805]720      }
[967]721      peCursor=peCursor->next;
[805]722    }
723  }
[645]724  return NULL;
725}
726
727/**
728 * Load binary values from a map (in) and add them to another map (out)
729 *
[967]730 * @param pmOut the map to add binaries values
731 * @param pmIn the map containing the binary values to add ti out
732 * @param iPos index of the binary in an array (in case of "MapArray")
[645]733 */
[967]734void loadMapBinary(map** ppmOut,map* pmIn,int iPos){
735  map* pmSize=getMap(pmIn,"size");
736  map *pmOut=*ppmOut;
737  map *pmTmpVin,*pmTmpVout;
738  if(pmSize!=NULL && iPos>0){
[645]739    char tmp[11];
[967]740    sprintf(tmp,"size_%d",iPos);
741    pmSize=getMap(pmIn,tmp);
742    sprintf(tmp,"value_%d",iPos);
743    pmTmpVin=getMap(pmIn,tmp);
744    pmTmpVout=getMap(pmOut,tmp);
745    free(pmTmpVout->value);
746    pmTmpVout->value=(char*)malloc((atoi(pmSize->value)+1)*sizeof(char));
747    memmove(pmTmpVout->value,pmTmpVin->value,atoi(pmSize->value)*sizeof(char));
748    pmTmpVout->value[atoi(pmSize->value)]=0;
[645]749  }else{
[967]750    if(pmSize!=NULL){
751      pmTmpVin=getMap(pmIn,"value");
752      pmTmpVout=getMap(pmOut,"value");
753      free(pmTmpVout->value);
754      pmTmpVout->value=(char*)malloc((atoi(pmSize->value)+1)*sizeof(char));
755      memmove(pmTmpVout->value,pmTmpVin->value,atoi(pmSize->value)*sizeof(char));
756      pmTmpVout->value[atoi(pmSize->value)]=0;
[645]757    }
758  }
759}
[967]760
[645]761/**
762 * Load binary values from a map (in) and add them to another map (out).
763 * This function will take care of MapArray.
764 * @see loadMapBinary
765 *
[967]766 * @param ppmOut the map to add binaries values
767 * @param pmIn the map containing the binary values to add ti out
[645]768 */
[967]769void loadMapBinaries(map** ppmOut,map* pmIn){
770  map* pmSize=getMap(pmIn,"size");
771  map* pmLength=getMap(pmIn,"length");
772  map* pmToload=getMap(pmIn,"to_load");
773  if(pmToload!=NULL && strcasecmp(pmToload->value,"false")==0){
[917]774#ifdef DEBUG
775    fprintf(stderr,"NO LOAD %s %d \n",__FILE__,__LINE__);
776#endif
777    return ;
778  }
[967]779  if(pmLength!=NULL){
780    int len=atoi(pmLength->value);
[645]781    int i=0;
782    for(i=0;i<len;i++){
[967]783      loadMapBinary(ppmOut,pmIn,i);
[645]784    }
785  }
786  else
[967]787    if(pmSize!=NULL)
788      loadMapBinary(ppmOut,pmIn,-1);
[645]789}
790
791/**
792 * Duplicate a Maps
793 *
[967]794 * @param ppmsOut the maps to clone
[645]795 * @return the allocated maps containing a copy of the mo maps
796 */
[967]797maps* dupMaps(maps** ppmsOut){
798  maps* pmsCursor=*ppmsOut;
799  maps* pmRes=NULL;
800  if(pmsCursor!=NULL){
801    map* pmContent=pmsCursor->content;
802    maps* pmsChild=pmsCursor->child;
803    pmRes=createMaps(pmsCursor->name);
804    if(pmContent!=NULL){
805      addMapToMap(&pmRes->content,pmContent);
806      loadMapBinaries(&pmRes->content,pmContent);
[645]807    }
[967]808    if(pmsChild!=NULL){
809      pmRes->child=dupMaps(&pmsChild);
[790]810    }
[967]811    pmRes->next=dupMaps(&pmsCursor->next);
[645]812  }
[967]813  return pmRes;
[645]814}
815
816/**
817 * Add a maps at the end of another maps.
818 *
819 * @see addMapToMap, dupMaps, getMaps
[967]820 * @param ppmsOut the maps to add mi
821 * @param pmIn the maps to add to mo
[645]822 */
[967]823void addMapsToMaps(maps** ppmsOut,maps* pmIn){
824  maps* pmsTmp=pmIn;
825  maps* pmsCursor=*ppmsOut;
826  while(pmsTmp!=NULL){
827    if(pmsCursor==NULL){
828      *ppmsOut=dupMaps(&pmIn);
[645]829    }
830    else{
[967]831      maps* pmsTmp1=getMaps(*ppmsOut,pmsTmp->name);
832      if(pmsTmp1==NULL){
833        while(pmsCursor->next!=NULL)
834          pmsCursor=pmsCursor->next;
835        pmsCursor->next=dupMaps(&pmsTmp);
836        if(pmsTmp->child!=NULL)
837          pmsCursor->next->child=dupMaps(&pmsTmp->child);
[790]838        else
[967]839          pmsCursor->next->child=NULL;
[984]840        return;
[790]841      }
842      else{
[967]843        addMapToMap(&pmsTmp1->content,pmsTmp->content);
844        if(pmsTmp->child!=NULL)
845          pmsTmp1->child=dupMaps(&pmsTmp->child);
[790]846        else
[967]847          pmsTmp1->child=NULL;
[790]848      }
[967]849      pmsCursor=*ppmsOut;
[645]850    }
[967]851    pmsTmp=pmsTmp->next;
[645]852  }
853}
854
855/**
856 * Access a specific map array element
857 *
[967]858 * @param pmMap the map to search for the key
859 * @param pccKey the key to search in the map
860 * @param iIndex of the MapArray
[645]861 * @return a pointer on the map found or NULL if not found
862 */
[967]863map* getMapArray(map* pmMap,const char* pccKey,int iIndex){
864  char acTmp[1024];
865  map* pmTmp;
866  if(iIndex>0)
867    sprintf(acTmp,"%s_%d",pccKey,iIndex);
[645]868  else
[967]869    sprintf(acTmp,"%s",pccKey);
[645]870#ifdef DEBUG
[967]871  fprintf(stderr,"** KEY %s\n",acTmp);
[645]872#endif
[967]873  pmTmp=getMap(pmMap,acTmp);
[645]874#ifdef DEBUG
[967]875  if(pmTmp!=NULL)
876    dumpMap(pmTmp);
[645]877#endif
[967]878  return pmTmp;
[645]879}
880
881/**
882 * Add a key value in a MapArray for a specific index
883 *
[967]884 * @param pmMap the map to search for the key
885 * @param pccKey the key to search in the map
886 * @param iIndex the index of the MapArray
887 * @param pccValue the value to set in the MapArray
[645]888 * @return a pointer on the map found or NULL if not found
889 */
[967]890void setMapArray(map* pmMap,const char* pccKey,int iIndex,const char* pccValue){
891  char acTmp[1024];
892  map* pmSize;
893  if(iIndex>0){
894    map* pmLen=getMap(pmMap,"length");
895    sprintf(acTmp,"%s_%d",pccKey,iIndex);
896    if((pmLen!=NULL && atoi(pmLen->value)<iIndex+1) || pmLen==NULL){
897      char acTmp0[5];
898      sprintf(acTmp0,"%d",iIndex+1);
899      addToMap(pmMap,"length",acTmp0);
[645]900    }
901  }
[917]902  else{
[967]903    sprintf(acTmp,"%s",pccKey);
904    addToMap(pmMap,"length","1");
[917]905  }
[967]906  pmSize=getMapArray(pmMap,"size",iIndex);
907  if(pmSize!=NULL && strncasecmp(pccKey,"value",5)==0){
908    map* pmPtr=getMapOrFill(&pmMap,acTmp,(char *)"");
[645]909#ifdef DEBUG
[967]910    fprintf(stderr,"%s\n",pmSize->value);
[645]911#endif
[967]912    free(pmPtr->value);
913    pmPtr->value=(char*)malloc((atoi(pmSize->value)+1)*sizeof(char));
914    memcpy(pmPtr->value,pccValue,atoi(pmSize->value)); 
[645]915  }
916  else
[967]917    addToMap(pmMap,acTmp,pccValue);
[645]918}
919
920/**
[917]921 * Add a key and an integer value to an existing map array.
922 *
[967]923 * @param pmMap the map to add the KVP
924 * @param pccName the key to add
925 * @param iIndex the index of the MapArray
926 * @param icValue the corresponding value to add
[917]927 */
[967]928void addIntToMapArray(map* pmMap,const char* pccName,int iIndex,const int icValue){
929  char acValue[10];
930  sprintf(acValue,"%d",icValue);
931  setMapArray(pmMap,pccName,iIndex,acValue);
[917]932}
933
934/**
[645]935 * Access the map "type"
936 *
[967]937 * @param pmMap the map
[645]938 * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
939 *  other case
940 */
[967]941map* getMapType(map* pmMap){
942  map* pmMime=getMap(pmMap,(char *)"mimeType");
943  if(pmMime==NULL){
944    pmMime=getMap(pmMap,"dataType");
945    if(pmMime==NULL){
946      pmMime=getMap(pmMap,"CRS");
[645]947    }
948  }
949#ifdef DEBUG
[967]950  dumpMap(pmMime);
[645]951#endif
[967]952  return pmMime;
[645]953}
954
955/**
956 * Add a Maps containing a MapArray to a Maps
957 *
958 * @see getMapType
[967]959 * @param pmsOut the maps
960 * @param pmsIn the maps
961 * @param pcType the map "type"
[645]962 * @return
963 */
[967]964int addMapsArrayToMaps(maps** pmsOut,maps* pmsIn,char* pcType){
965  maps* pmsTmp=pmsIn;
966  maps* pmsCursor=getMaps(*pmsOut,pmsTmp->name);
967  char acLen[10];
968  int iLen=1;
969  char *acV[14]={
[645]970    (char*)"size",
971    (char*)"value",
972    (char*)"uom",
973    (char*)"Reference",
974    (char*)"Order",
975    (char*)"cache_file",
976    (char*)"fmimeType",
977    (char*)"xlink:href",
[967]978    pcType,
[645]979    (char*)"schema",
980    (char*)"encoding",
[868]981    (char*)"isCached",
982    (char*)"LowerCorner",
[917]983    (char*)"UpperCorner"
[645]984  };
[967]985  int iCounter=0;
986  map* pmLength;
[917]987 
[967]988  if(pmsCursor==NULL)
[917]989    return -1;
990
[967]991  pmLength=getMap(pmsCursor->content,"length");
992  if(pmLength!=NULL){
993    iLen=atoi(pmLength->value);
[917]994  }
995
[967]996  sprintf(acLen,"%d",iLen+1);
997  addToMap(pmsCursor->content,"length",acLen);
998  for(iCounter=0;iCounter<14;iCounter++){
999    map* pmTmp=getMap(pmsTmp->content,acV[iCounter]);
1000    if(pmTmp!=NULL){
[645]1001#ifdef DEBUG
[967]1002      fprintf(stderr,"%s = %s\n",pmTmp[iCounter],pmTmp->value);
[645]1003#endif
[967]1004      setMapArray(pmsCursor->content,acV[iCounter],iLen,pmTmp->value);
[645]1005    }
1006  }
1007   
[967]1008  addToMap(pmsCursor->content,"isArray","true");
[645]1009  return 0;
1010}
1011
1012/**
1013 * Set a key value pair to a map contained in a Maps
1014 *
[967]1015 * @param pmsMaps the maps
1016 * @param pccKey the maps name
1017 * @param pccSubkey the map name included in the maps corresponding to key
1018 * @param pccValue the corresponding value to add in the map
[645]1019 */
[967]1020void setMapInMaps(maps* pmsMaps,const char* pccKey,const char* pccSubkey,const char *pccValue){
1021  maps* pmsTmp=getMaps(pmsMaps,pccKey);
1022  if(pmsTmp!=NULL){
1023    map* pmTmpSub=getMap(pmsTmp->content,pccSubkey);
1024    if(pmTmpSub!=NULL){
1025      if(pmTmpSub->value!=NULL)
1026        free(pmTmpSub->value);
1027      pmTmpSub->value=zStrdup(pccValue);
[645]1028    }else{
[967]1029      maps *pmsToAdd=createMaps(pccKey);
1030      pmsToAdd->content=createMap(pccSubkey,pccValue);
1031      addMapsToMaps(&pmsTmp,pmsToAdd);
1032      freeMaps(&pmsToAdd);
1033      free(pmsToAdd);
[645]1034    }
1035  }else{
[967]1036    maps *pmsToAdd=createMaps(pccKey);
1037    pmsToAdd->content=createMap(pccSubkey,pccValue);
1038    addMapsToMaps(&pmsMaps,pmsToAdd);
1039    freeMaps(&pmsToAdd);
1040    free(pmsToAdd);
[645]1041  }
1042}
1043
1044/**
[790]1045 * Create an empty elements
1046 *
1047 * @return a pointer to the allocated elements
1048 */
1049elements* createEmptyElements(){
[967]1050  elements* peRes=(elements*)malloc(ELEMENTS_SIZE);
1051  peRes->name=NULL;
1052  peRes->content=NULL;
1053  peRes->metadata=NULL;
1054  peRes->additional_parameters=NULL; 
1055  peRes->format=NULL;
1056  peRes->defaults=NULL;
1057  peRes->supported=NULL;
1058  peRes->child=NULL;
1059  peRes->next=NULL;
1060  return peRes;
[790]1061}
1062
1063/**
1064 * Create a named elements
1065 *
[967]1066 * @param pcName the elements name
[790]1067 * @return a pointer to the allocated elements
1068 */
[967]1069elements* createElements(const char* pcName){
1070  elements* peRes=(elements*)malloc(ELEMENTS_SIZE);
1071  peRes->name=zStrdup(pcName);
1072  peRes->content=NULL;
1073  peRes->metadata=NULL;
1074  peRes->additional_parameters=NULL;
1075  peRes->format=NULL;
1076  peRes->defaults=NULL;
1077  peRes->supported=NULL;
1078  peRes->child=NULL;
1079  peRes->next=NULL;
1080  return peRes;
[790]1081}
1082
1083/**
1084 * Set the name of an elements
1085 *
[967]1086 * @param peElem the elements to modify
1087 * @param pcName the elements name
[790]1088 * @return a pointer to the allocated elements
1089 */
[967]1090void setElementsName(elements** ppeElem,char* pcName){
1091  elements* peRes=*ppeElem;
1092  peRes->name=zStrdup(pcName);
1093  peRes->content=NULL;
1094  peRes->metadata=NULL;
1095  peRes->format=NULL;
1096  peRes->defaults=NULL;
1097  peRes->supported=NULL;
1098  peRes->child=NULL;
1099  peRes->next=NULL;
[790]1100}
1101
1102/**
[645]1103 * Dump an elements on stderr
1104 *
[967]1105 * @param peElem the elements to dump
[645]1106 */
[967]1107void dumpElements(elements* peElem){
1108  elements* peTmp=peElem;
1109  while(peTmp!=NULL){
1110    iotype* piotTmp=peTmp->defaults;
[917]1111    int ioc=0;
[967]1112    fprintf(stderr,"ELEMENT [%s]\n",peTmp->name);
1113    fprintf(stderr," > CONTENT [%s]\n",peTmp->name);
1114    dumpMap(peTmp->content);
1115    fprintf(stderr," > METADATA [%s]\n",peTmp->name);
1116    dumpMap(peTmp->metadata);
1117    fprintf(stderr," > ADDITIONAL PARAMETERS [%s]\n",peTmp->name);
1118    dumpMap(peTmp->additional_parameters);
1119    fprintf(stderr," > FORMAT [%s]\n",peTmp->format);
1120    while(piotTmp!=NULL){
1121      fprintf(stderr," > DEFAULTS [%s] (%i)\n",peTmp->name,ioc);
1122      dumpMap(piotTmp->content);
1123      piotTmp=piotTmp->next;
[645]1124      ioc++;
1125    }
[967]1126    piotTmp=peTmp->supported;
[645]1127    ioc=0;
[967]1128    while(piotTmp!=NULL){
1129      fprintf(stderr," > SUPPORTED [%s] (%i)\n",peTmp->name,ioc);
1130      dumpMap(piotTmp->content);
1131      piotTmp=piotTmp->next;
[645]1132      ioc++;
1133    }
[967]1134    if(peTmp->child!=NULL){
[790]1135      fprintf(stderr," > CHILD \n");
[967]1136      dumpElements(peTmp->child);
[790]1137    }
[645]1138    fprintf(stderr,"------------------\n");
[967]1139    peTmp=peTmp->next;
[645]1140  }
1141}
1142
1143/**
1144 * Dump an elements on stderr using the YAML syntaxe
1145 *
[967]1146 * @param peElem the elements to dump
1147 * @param iLevel the current level
[645]1148 */
[967]1149void dumpElementsAsYAML(elements* peElem,int iLevel){
1150  elements* peTmp=peElem;
[645]1151  int i;
[967]1152  while(peTmp!=NULL){
1153    map* pmCurs=peTmp->content;
[917]1154    int ioc=0;
[967]1155    iotype* piotTmp;
1156    for(i=0;i<2+(4*iLevel);i++)
[645]1157      fprintf(stderr," ");
[967]1158    fprintf(stderr,"%s:\n",peTmp->name);
1159    while(pmCurs!=NULL){
1160      for(i=0;i<4+(4*iLevel);i++)
[645]1161        fprintf(stderr," ");
[967]1162      _dumpMap(pmCurs);
1163      pmCurs=pmCurs->next;
[645]1164    }
[967]1165    pmCurs=peTmp->metadata;
1166    if(pmCurs!=NULL){
1167      for(i=0;i<4+(4*iLevel);i++)
[645]1168        fprintf(stderr," ");
1169      fprintf(stderr,"MetaData:\n");
[967]1170      while(pmCurs!=NULL){
1171        for(i=0;i<6+(4*iLevel);i++)
[645]1172          fprintf(stderr," ");
[967]1173        _dumpMap(pmCurs);
1174        pmCurs=pmCurs->next;
[645]1175      }
1176    }
[967]1177    for(i=0;i<4+(4*iLevel);i++)
[645]1178      fprintf(stderr," ");
[967]1179    if(peTmp->format!=NULL)
1180      fprintf(stderr,"%s:\n",peTmp->format);
[790]1181    else{
1182      fprintf(stderr,"Child:\n");
[967]1183      if(peTmp->child!=NULL)
1184        dumpElementsAsYAML(peTmp->child,iLevel+1);
[790]1185    }
[967]1186    piotTmp=peTmp->defaults;
1187    while(piotTmp!=NULL){
1188      for(i=0;i<6+(4*iLevel);i++)
[645]1189        fprintf(stderr," ");
1190      fprintf(stderr,"default:\n");
[967]1191      pmCurs=piotTmp->content;
1192      while(pmCurs!=NULL){
1193        for(i=0;i<8+(4*iLevel);i++)
[645]1194          fprintf(stderr," ");
[967]1195        if(strcasecmp(pmCurs->name,"range")==0){
1196          fprintf(stderr,"range: \"%s\"\n",pmCurs->value);
[645]1197        }else
[967]1198          _dumpMap(pmCurs);
1199        pmCurs=pmCurs->next;
[645]1200      }
[967]1201      piotTmp=piotTmp->next;
[645]1202      ioc++;
1203    }
[967]1204    piotTmp=peTmp->supported;
[645]1205    ioc=0;
[967]1206    while(piotTmp!=NULL){
1207      for(i=0;i<6+(4*iLevel);i++)
[645]1208        fprintf(stderr," ");
1209      fprintf(stderr,"supported:\n");
[967]1210      pmCurs=piotTmp->content;
1211      while(pmCurs!=NULL){
1212        for(i=0;i<8+(4*iLevel);i++)
[645]1213          fprintf(stderr," ");
[967]1214        if(strcasecmp(pmCurs->name,"range")==0){
1215          fprintf(stderr,"range: \"%s\"\n",pmCurs->value);
[645]1216        }else
[967]1217          _dumpMap(pmCurs);
1218        pmCurs=pmCurs->next;
[645]1219      }
[967]1220      piotTmp=piotTmp->next;
[645]1221      ioc++;
1222    }
[967]1223    peTmp=peTmp->next;
[645]1224  }
1225}
1226
1227/**
1228 * Duplicate an elements
1229 *
[967]1230 * @param peElem the elements to clone
[645]1231 * @return the allocated elements containing a copy of the elements e
1232 */
[967]1233elements* dupElements(elements* peElem){
1234  elements* peCursor=peElem;
1235  elements* peTmp=NULL;
1236  if(peCursor!=NULL && peCursor->name!=NULL){
[645]1237#ifdef DEBUG
1238    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1239    dumpElements(e);
1240    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
1241#endif
[967]1242    peTmp=(elements*)malloc(ELEMENTS_SIZE);
1243    peTmp->name=zStrdup(peCursor->name);
1244    peTmp->content=NULL;
1245    addMapToMap(&peTmp->content,peCursor->content);
1246    peTmp->metadata=NULL;
1247    addMapToMap(&peTmp->metadata,peCursor->metadata);
1248    peTmp->additional_parameters=NULL;
1249    addMapToMap(&peTmp->additional_parameters,peCursor->additional_parameters);
1250    if(peCursor->format!=NULL)
1251      peTmp->format=zStrdup(peCursor->format);
[645]1252    else
[967]1253      peTmp->format=NULL;
1254    if(peCursor->defaults!=NULL){
1255      peTmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
1256      peTmp->defaults->content=NULL;
1257      addMapToMap(&peTmp->defaults->content,peCursor->defaults->content);
1258      peTmp->defaults->next=NULL;
[645]1259#ifdef DEBUG
1260      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
[967]1261      dumpMap(peTmp->defaults->content);
[645]1262#endif
1263    }else
[967]1264      peTmp->defaults=NULL;
1265    if(peCursor->supported!=NULL && peCursor->supported->content!=NULL){
1266      iotype *piotTmp=peCursor->supported->next;
1267      peTmp->supported=(iotype*)malloc(IOTYPE_SIZE);
1268      peTmp->supported->content=NULL;
1269      addMapToMap(&peTmp->supported->content,peCursor->supported->content);
1270      peTmp->supported->next=NULL;
1271            while(piotTmp!=NULL){
1272        addMapToIoType(&peTmp->supported,piotTmp->content);
[645]1273#ifdef DEBUG
1274        fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
[967]1275        dumpMap(peTmp->defaults->content);
[645]1276#endif
[967]1277        piotTmp=piotTmp->next;
[645]1278      }
1279    }
1280    else
[967]1281      peTmp->supported=NULL;
1282    if(peCursor->child!=NULL)
1283      peTmp->child=dupElements(peCursor->child);
[790]1284    else
[967]1285      peTmp->child=NULL;
1286    if(peCursor->next!=NULL)
1287      peTmp->next=dupElements(peCursor->next);
[917]1288    else
[967]1289      peTmp->next=NULL;
[645]1290  }
[967]1291  return peTmp;
[645]1292}
1293
1294/**
1295 * Add an elements to another elements.
1296 *
1297 * @see dupElements
[967]1298 * @param ppeElem the elements to add the e
1299 * @param peELem the elements to be added to m
[645]1300 */
[967]1301void addToElements(elements** ppeElem,elements* peELem){
1302  elements* peTmp=peELem;
1303  if(*ppeElem==NULL){
1304    (*ppeElem)=dupElements(peTmp);
[645]1305  }else{
[967]1306    addToElements(&(*ppeElem)->next,peTmp);
[645]1307  }
1308}
[790]1309
[645]1310/**
[790]1311 * Set the name of a service
1312 *
[967]1313 * @param ppsServ the service
1314 * @param pcName the service name
[790]1315 */
[967]1316void setServiceName(service** ppsServ,char* pcName){
1317  service* psRes=*ppsServ;
1318  psRes->name=zStrdup(pcName);
1319  psRes->content=NULL;
1320  psRes->metadata=NULL;
1321  psRes->inputs=NULL;
1322  psRes->outputs=NULL;
[790]1323}
1324
1325/**
[645]1326 * Dump a service on stderr
1327 *
[967]1328 * @param psServ the service to dump
[645]1329 */
[967]1330void dumpService(service* psServ){
1331  if(psServ==NULL)
[645]1332    return;
[967]1333  fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",psServ->name);
1334  if(psServ->content!=NULL){
[645]1335    fprintf(stderr,"CONTENT MAP\n");
[967]1336    dumpMap(psServ->content);
1337    if(psServ->metadata!=NULL)
[917]1338      fprintf(stderr,"CONTENT METADATA\n");
[967]1339    dumpMap(psServ->metadata);
1340    if(psServ->additional_parameters!=NULL)
[917]1341      fprintf(stderr,"CONTENT AdditionalParameters\n");
[967]1342    dumpMap(psServ->additional_parameters);
[645]1343  }
[967]1344  if(psServ->inputs!=NULL){
1345    fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",psServ->name);
1346    dumpElements(psServ->inputs);
[645]1347  }
[967]1348  if(psServ->outputs!=NULL){
1349    fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",psServ->name);
1350    dumpElements(psServ->outputs);
[645]1351  }
1352  fprintf(stderr,"++++++++++++++++++\n");
1353}
1354
1355/**
1356 * Dump a service on stderr using the YAML syntaxe
1357 *
[967]1358 * @param psServ the service to dump
[645]1359 */
[967]1360void dumpServiceAsYAML(service* psServ){
[645]1361  int i;
[967]1362  fprintf(stderr,"# %s\n\n",psServ->name);
1363  if(psServ->content!=NULL){
1364    map* pmCurs=psServ->content;
1365    dumpMap(pmCurs);
1366    pmCurs=psServ->metadata;
1367    if(pmCurs!=NULL){
[645]1368      fprintf(stderr,"MetaData:\n");
[967]1369      while(pmCurs!=NULL){
[645]1370        for(i=0;i<2;i++)
1371          fprintf(stderr," ");
[967]1372        _dumpMap(pmCurs);
1373        pmCurs=pmCurs->next;
[645]1374      }
1375    }
1376  }
[967]1377  if(psServ->inputs!=NULL){
[645]1378    fprintf(stderr,"\ninputs:\n");
[967]1379    dumpElementsAsYAML(psServ->inputs,0);
[645]1380  }
[967]1381  if(psServ->outputs!=NULL){
[645]1382    fprintf(stderr,"\noutputs:\n");
[967]1383    dumpElementsAsYAML(psServ->outputs,0);
[645]1384  }
1385}
1386
1387/**
1388 * Duplicate a service
1389 *
[967]1390 * @param psServ the service to clone
[645]1391 * @return the allocated service containing a copy of the serfvice s
1392 */
[967]1393service* dupService(service* psServ){
1394  service *psRes=(service*)malloc(SERVICE_SIZE);
1395  psRes->name=zStrdup(psServ->name);
1396  psRes->content=NULL;
1397  addMapToMap(&psRes->content,psServ->content);
1398  psRes->metadata=NULL;
1399  addMapToMap(&psRes->metadata,psServ->metadata);
1400  psRes->additional_parameters=NULL;
1401  addMapToMap(&psRes->additional_parameters,psServ->additional_parameters);
1402  psRes->inputs=dupElements(psServ->inputs);
1403  psRes->outputs=dupElements(psServ->outputs);
1404  return psRes;
[645]1405}
1406
1407/**
1408 * Print the registry on stderr.
1409 *
[967]1410 * @param prReg the registry
[645]1411 */
[967]1412void dumpRegistry(registry* prReg){
1413  registry* prCurs=prReg;
1414  while(prCurs!=NULL){
1415    services* psServ=prCurs->content;
1416    fprintf(stderr,"%s \n",prCurs->name);
1417    psServ=prCurs->content;
1418    while(psServ!=NULL){
1419      dumpService(psServ->content);
1420      psServ=psServ->next;
[645]1421    }
[967]1422    prCurs=prCurs->next;
[645]1423  }
1424}
1425
1426/**
1427 * Add a service to the registry
1428 *
[967]1429 * @param prReg the resgitry to add the service
1430 * @param pcName the registry name to update
1431 * @param psContent the service to add
[645]1432 */
[967]1433bool addServiceToRegistry(registry** prReg,char* pcName,service* psContent){
1434  registry *l=*prReg;
[645]1435  int isInitial=-1;
1436  if(l==NULL){
1437    l=(registry*)malloc(REGISTRY_SIZE);
1438    isInitial=1;
1439  }
1440  if(l!=NULL){
1441    int hasLevel=-1;
1442    while(isInitial<0 && l!=NULL){
[967]1443      if(l->name!=NULL && strcasecmp(pcName,l->name)==0){
[645]1444        hasLevel=1;
1445        break;
1446      }
1447      l=l->next;
1448    }
1449    if(hasLevel<0){
1450      if(isInitial<0)
1451        l=(registry*)malloc(REGISTRY_SIZE);
[967]1452      l->name=zStrdup(pcName);
[645]1453      l->content=NULL;
1454      l->next=NULL;
1455    }
1456    if(l->content==NULL){
1457      l->content=(services*)malloc(SERVICES_SIZE);
[967]1458      l->content->content=dupService(psContent);
[645]1459      l->content->next=NULL;
1460    }
1461    else{
[967]1462      services* psServ=l->content;
1463      while(psServ->next!=NULL)
1464        psServ=psServ->next;
1465      psServ->next=(services*)malloc(SERVICES_SIZE);
1466      psServ->next->content=dupService(psContent);
1467      psServ->next->next=NULL;
[645]1468    }
1469    l->next=NULL;
1470    if(isInitial>0)
[967]1471      *prReg=l;
[645]1472    else{
[967]1473      registry *prCurs=*prReg;
1474      while(prCurs->next!=NULL)
1475        prCurs=prCurs->next;
1476      prCurs->next=l;
1477      prCurs->next->next=NULL;
[645]1478    }
1479    return true;
1480  }
1481  else
1482    return false;
1483}
1484
1485/**
1486 * Free memory allocated for the registry
1487 *
[967]1488 * @param prReg the registry
[645]1489 */
[967]1490void freeRegistry(registry** prReg){
1491  registry* prLocalRef=*prReg;
1492  while(prLocalRef!=NULL){
1493    services* psServ=prLocalRef->content;
1494    free(prLocalRef->name);
1495    while(psServ!=NULL){
1496      service* psServ1=psServ->content;
1497      psServ=psServ->next;
1498      if(psServ1!=NULL){
1499        freeService(&psServ1);
1500        free(psServ1);
1501        psServ1=NULL;
[645]1502      }
1503    }
[967]1504    prLocalRef=prLocalRef->next;
[645]1505  }   
1506}
1507
1508/**
1509 * Access a service in the registry
1510 *
[967]1511 * @param prReg the registry
1512 * @param pcLevel the regitry to search ("concept", "generic" or "implementation")
1513 * @param pcName the service name
[645]1514 * @return the service pointer if a corresponding service was found or NULL
1515 */
[967]1516service* getServiceFromRegistry(registry* prReg,char  *pcLevel,char* pcName){
1517  registry *prLocalRef=prReg;
1518  while(prLocalRef!=NULL){
1519    if(strcasecmp(prLocalRef->name,pcLevel)==0){
1520      services* psServ=prLocalRef->content;
1521      while(psServ!=NULL){
1522        if(psServ->content!=NULL && strcasecmp(psServ->content->name,pcName)==0)
1523          return psServ->content;
1524        psServ=psServ->next;
[645]1525      }
1526      break;
1527    }
[967]1528    prLocalRef=prLocalRef->next;
[645]1529  }
1530  return NULL;
1531}
1532
1533/**
1534 * Apply inheritance to an out map from a reference in map
1535 *
[967]1536 * @param ppmOut the map to update
1537 * @param pmIn the reference map (containing inherited properties)
[645]1538 */
[967]1539void inheritMap(map** ppmOut,map* pmIn){
1540  map* pmContent=pmIn;
1541  if((*ppmOut)==NULL){
1542    addMapToMap(ppmOut,pmIn);
[676]1543    return;
1544  }
[967]1545  while(pmContent!=NULL){
1546    map* pmCurrent=getMap(*ppmOut,pmContent->name);
1547    if(pmCurrent==NULL)
1548      addToMap(*ppmOut,pmCurrent->name,pmCurrent->value);
1549    pmCurrent=pmCurrent->next;
[645]1550  }
1551}
1552
1553/**
1554 * Apply inheritance to an out iotype from a reference in iotype
1555 *
[967]1556 * @param ppiotOut the iotype to update
1557 * @param piotIn the reference iotype (containing inherited properties)
[645]1558 */
[967]1559void inheritIOType(iotype** ppiotOut,iotype* piotIn){
1560  iotype* piotInCurosor=piotIn;
1561  iotype* ppiotOutCursor=*ppiotOut;
1562  if(piotInCurosor!=NULL){
1563    if(*ppiotOut==NULL){
1564      *ppiotOut=(iotype*)malloc(IOTYPE_SIZE);
1565      (*ppiotOut)->content=NULL;
1566      addMapToMap(&(*ppiotOut)->content,piotInCurosor->content);
1567      (*ppiotOut)->next=NULL;
1568      ppiotOutCursor=*ppiotOut;
1569      inheritIOType(&ppiotOutCursor->next,piotInCurosor->next);
[645]1570    }else{
[967]1571      inheritIOType(&ppiotOutCursor->next,piotInCurosor->next);
[645]1572    }
1573  }
1574}
1575
1576/**
1577 * Apply inheritance to an out elements from a reference in elements
1578 *
[967]1579 * @param ppeOut the elements to update
1580 * @param peIn the reference elements (containing inherited properties)
[645]1581 */
[967]1582void inheritElements(elements** ppeOut,elements* peIn){
1583  elements* peContent=peIn;
1584  while(peContent!=NULL && *ppeOut!=NULL){
1585    elements* peCurrent=getElements(*ppeOut,peContent->name);
1586    if(peCurrent==NULL)
1587      addToElements(ppeOut,peContent);
[645]1588    else{
[967]1589      inheritMap(&peCurrent->content,peContent->content);
1590      inheritMap(&peCurrent->metadata,peContent->metadata);
1591      if(peCurrent->format==NULL && peContent->format!=NULL)
1592        peCurrent->format=zStrdup(peContent->format);
1593      inheritIOType(&peCurrent->defaults,peContent->defaults);
1594      if(peCurrent->supported==NULL)
1595        inheritIOType(&peCurrent->supported,peContent->supported);
[645]1596      else{
[967]1597        iotype* piotTmp=peContent->supported;
1598        while(piotTmp!=NULL){
1599          addMapToIoType(&peCurrent->supported,piotTmp->content);
1600          piotTmp=piotTmp->next;
[645]1601        }
1602      }
1603    }
[967]1604    peContent=peContent->next;
[645]1605  }
1606}
1607
1608/**
1609 * Apply inheritance to a service based on a registry
1610 *
[967]1611 * @param prReg the registry storing profiles hierarchy
1612 * @param psServ the service to update depending on its inheritance
[645]1613 */
[967]1614void inheritance(registry *prReg,service** psServ){
1615  service* psCursor=*psServ;
[917]1616  map *profile,*level;
[967]1617  if(prReg==NULL)
[645]1618    return;
[967]1619  if(psCursor==NULL || psCursor->content==NULL)
[645]1620    return;
[967]1621  profile=getMap(psCursor->content,"extend");
1622  level=getMap(psCursor->content,"level");
[645]1623  if(profile!=NULL&&level!=NULL){
1624    service* s1;
1625    if(strncasecmp(level->value,"profile",7)==0)
[967]1626      s1=getServiceFromRegistry(prReg,(char*)"generic",profile->value);
[645]1627    else
[967]1628      s1=getServiceFromRegistry(prReg,level->value,profile->value);
[645]1629     
[967]1630    inheritMap(&psCursor->content,s1->content);
1631    inheritMap(&psCursor->metadata,s1->metadata);
1632    if(psCursor->inputs==NULL && s1->inputs!=NULL){
1633      psCursor->inputs=dupElements(s1->inputs);
[645]1634    }else{
[967]1635      inheritElements(&psCursor->inputs,s1->inputs);
[645]1636    }
[967]1637    if(psCursor->outputs==NULL && s1->outputs!=NULL){
1638      psCursor->outputs=dupElements(s1->outputs);
[645]1639    }else
[967]1640      inheritElements(&psCursor->outputs,s1->outputs);
[645]1641  }
1642}
1643
1644/**
1645 * Convert a maps to a char*** (only used for Fortran support)
1646 *
[967]1647 * @param pmsMap the maps to convert
1648 * @param pppcValues the resulting array
[645]1649 */
[967]1650void mapsToCharXXX(maps* pmsMap,char*** pppcValues){
1651  maps* pmsCursor=pmsMap;
[645]1652  int i=0;
1653  int j=0;
[967]1654  char aaacTmp[10][30][1024];
1655  memset(aaacTmp,0,1024*10*10);
1656  while(pmsCursor!=NULL){
1657    map* pmContent=pmsCursor->content;
[645]1658    if(i>=10)
1659      break;
[967]1660    strcpy(aaacTmp[i][j],"name");
[645]1661    j++;
[967]1662    strcpy(aaacTmp[i][j],pmsCursor->name);
[645]1663    j++;
[967]1664    while(pmContent!=NULL){
[645]1665      if(j>=30)
1666        break;
[967]1667      strcpy(aaacTmp[i][j],pmContent->name);
[645]1668      j++;
[967]1669      strcpy(aaacTmp[i][j],pmContent->value);
[645]1670      j++;
[967]1671      pmContent=pmContent->next;
[645]1672    }
[967]1673    pmsCursor=pmsCursor->next;
[645]1674    j=0;
1675    i++;
1676  }
[967]1677  memcpy(pppcValues,aaacTmp,10*10*1024);
[645]1678}
1679
1680/**
1681 * Convert a char*** to a maps (only used for Fortran support)
1682 *
[967]1683 * @param pppcValues the array to convert
1684 * @param ppmsMaps the resulting maps
[645]1685 */
[967]1686void charxxxToMaps(char*** pppcValues,maps** ppmsMaps){
1687  maps* pmsCursor=*ppmsMaps;
[645]1688  int i,j;
[967]1689  char aaaTmp[10][30][1024];
1690  memcpy(aaaTmp,pppcValues,10*30*1024);
[645]1691  for(i=0;i<10;i++){
[967]1692    if(strlen(aaaTmp[i][1])==0)
[645]1693      break;
[967]1694    pmsCursor->name=aaaTmp[i][1];
1695    pmsCursor->content=NULL;
1696    pmsCursor->next=NULL;
[645]1697    for(j=2;j<29;j+=2){
[967]1698      if(strlen(aaaTmp[i][j+1])==0)
[645]1699        break;
[967]1700      if(pmsCursor->content==NULL)
1701        pmsCursor->content=createMap(aaaTmp[i][j],aaaTmp[i][j+1]);
[645]1702      else
[967]1703        addToMap(pmsCursor->content,aaaTmp[i][j],aaaTmp[i][j+1]);
[645]1704    }
[967]1705    pmsCursor=pmsCursor->next;
[645]1706  }
[967]1707  ppmsMaps=&pmsCursor;
[645]1708}
[843]1709
[889]1710/**
1711 * Verify that a map has a value
1712 *
[967]1713 * @param pmMap pointer to map that should be checked
[889]1714 * @return true if map has a value or false if value is missing/empty/NULL
1715 */
[967]1716bool nonempty(map* pmMap) {
1717  return (pmMap != NULL && pmMap->value != NULL && strlen(pmMap->value) > 0 && strcmp(pmMap->value, "NULL") != 0);
[889]1718}
1719
1720/**
[917]1721 * Verify that a particular map value exists in a maps
[889]1722 * data structure, and obtain that value
1723 *
[967]1724 * @param pmsSource pointer to maps structure
1725 * @param pccNode name of maps node to search
1726 * @param pccKey name of map node to find
1727 * @param ppmKvp address to the map* if it exists, otherwise NULL
[889]1728 * @return true if map has a value or false if value is missing/NULL
[917]1729 *
1730 * @note The map assigned to kvp is owned by the source maps
[889]1731 */
[967]1732bool hasvalue(maps* pmsSource, const char* pccNode, const char* pccKey, map** ppmKvp) {
1733  *ppmKvp = getMapFromMaps(pmsSource, pccNode, pccKey);
1734  return (*ppmKvp != NULL && (*ppmKvp)->value != NULL &&
1735          strlen((*ppmKvp)->value) > 0 && strcmp((*ppmKvp)->value, "NULL") != 0);
[889]1736}
1737
1738/*
1739 * Set error message in configuration maps
1740 *
[967]1741 * @param pmsaConf reference to configuration maps
1742 * @param pccService name of service
1743 * @param weExc WPSException code
1744 * @param pccMessage exception text (default: exception text in WPS specification)
[889]1745 */
[967]1746void setErrorMessage(maps*& pmsaConf, const char* pccService, WPSException weExc, const char* pccMessage) {
1747  if (pccMessage == NULL) {
1748    pccMessage = WPSExceptionText[weExc];
1749  }
1750  size_t len = strlen(pccService) + strlen(": ") + strlen(pccMessage) + strlen(": ") + strlen(WPSExceptionCode[weExc]) + 16;
1751  char* pcMsg = (char*)malloc(len * sizeof(char));
1752  if (pcMsg != NULL) {
1753    snprintf(pcMsg, len * sizeof(char), "\n%s: %s: %s\n", pccService, pccMessage, WPSExceptionCode[weExc]);
1754    setMapInMaps(pmsaConf, "lenv", "message", pcMsg);
1755    free(pcMsg);
1756  }
[889]1757}
1758
[967]1759/**
1760 * Print debug message
1761 *
1762 * @param pccSource the file invoking the function
1763 * @param pccFunction the function calling for logMessage
1764 * @param iLine the line number
1765 * @param pccFile the file to log informations
1766 * @param pccMessage the message to be print
1767 */
1768void logMessage(const char* pccSource, const char* pccFunction, int iLne, const char* pccFile, const char* pccMessage) { //, const char* source, const char* function, int line) {
[917]1769
[967]1770  size_t msglen = 512;
1771  const char empty[] = "";
[917]1772
[967]1773  FILE* pfLog;
[917]1774
[967]1775  // system time, process time [nanoseconds]   
1776  unsigned long long sys_t, proc_t;
[917]1777
[967]1778  // processor time consumed by the program:
1779  clock_t t = clock();
[917]1780
[967]1781  // system time:
1782  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
[917]1783
[967]1784  std::time_t now_t = std::chrono::system_clock::to_time_t(now);
1785  std::tm* tm = localtime(&now_t);
1786  char* pcStr = asctime(tm);
1787  pcStr[strlen(pcStr) - 1] = '\0'; // remove newline
[917]1788
[967]1789  sys_t = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
1790  //proc_t = (unsigned long long)(1.0e9*t/CLOCKS_PER_SEC);
1791  proc_t = t;
[917]1792
[967]1793  if (pccMessage != NULL) {
1794    msglen += strlen(pccMessage);
1795  }
1796  else {
1797    pccMessage = empty;
1798  }
1799  //getLastErrorMessage(); // cgiScriptName 
1800  char* pcText = (char*)malloc(sizeof(char)*msglen);
[917]1801
[967]1802  snprintf(pcText, msglen, "pid: %d %s line %d %s() %s systime: %lld ns ticks: %lld %s\n",
1803           zGetpid(), pccSource, iLne, pccFunction, pcStr, sys_t, proc_t, pccMessage); // __FILE__ __LINE__ __func__ //
[917]1804
[967]1805  if (pccFile != NULL && (pfLog = fopen(pccFile, "a+")) != NULL) {
1806    fputs(pcText, pfLog);
1807    fclose(pfLog);
1808  }
1809  else {
[917]1810#ifdef MSG_LOG_FILE
[967]1811    if ((pfLog = fopen(MSG_LOG_FILE, "a+")) != NULL) {
1812      fputs(pcText, pfLog);
1813      fclose(pfLog);
1814    }
[917]1815#endif
[967]1816  }
[917]1817
[967]1818  if (pcText != NULL) free(pcText);
[889]1819}
1820
1821// knut:
1822// Example:
1823// zooLog;
1824// zooLogMsg(NULL, getLastErrorMessage());
[917]1825// zooLogMsg("log.txt", getLastErrorMessage());
[943]1826
1827#ifdef WIN32
1828#ifndef USE_MS
[967]1829char *strcasestr (char const *pccA, char const *pccB)
[943]1830  {
[967]1831    char *pcX = zStrdup (pccA);
1832    char *pcY = zStrdup (pccB);
[943]1833 
[967]1834      pcX = _strlwr (pcX);
1835      pcY = _strlwr (pcY);
1836    char *pos = strstr (pcX, pcY);
1837    char *ret = pos == NULL ? NULL : (char *) (pccA + (pos - pcX));
1838      free (pcX);
1839      free (pcY);
[943]1840      return ret;
1841  };
1842#else
1843   ;
1844#endif
1845#endif
[957]1846
1847/*
1848 * Dynamically allocate memory for a map value
1849 *
1850 * @param node the map for which the value buffer should be allocated
1851 * @param num_bytes the number of bytes to allocate
1852 * @return pointer to the allocated memory buffer
1853 *
1854 * This function will free, and hence delete, any existing value in the map.
1855 * The memory should be deallocated by calling freeMap.
1856 */
[967]1857char* allocateMapValue(map* pmNode, size_t sNumBytes)
[957]1858{
[967]1859  if (pmNode == NULL) {
1860    return NULL;
1861  }
[957]1862
[967]1863  if (pmNode->value != NULL) {
1864    free(pmNode->value);
1865  }
1866  pmNode->value = (char*) malloc(sNumBytes);
[957]1867               
[967]1868  return pmNode->value;
[957]1869}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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