source: branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c @ 839

Last change on this file since 839 was 839, checked in by djay, 7 years ago

Update the source code for HPC support. Automatically adding nested outputs for the HPC support (should this be available for every support?). Add capability to store the metadata in the Collection DataBase?. Addition of the zcfg2sql to import any existing ZCFG file into the Collection DB. Add the support to invoke a callback (for history purpose) in case a [callback] section contains at least one parameter defined (url). Add support to convert maps and map to JSON (for callback use only by now). Fix some memory leaks (some are still there).

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 18.6 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2015 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#define _LARGEFILE64_SOURCE 1
26#ifdef USE_MS
27#include "service_internal_ms.h"
28#else
29#include "cpl_vsi.h"
30#endif
31#include "service_internal.h"
32
33#ifndef TRUE
34#define TRUE 1
35#endif
36#ifndef FALSE
37#define FALSE -1
38#endif
39
40#define ERROR_MSG_MAX_LENGTH 1024
41#ifndef RELY_ON_DB
42#include <dirent.h>
43
44/**
45 * Read the sid file attached of a service if any
46 *
47 * @param conf the maps containing the setting of the main.cfg file
48 * @param pid the service identifier (usid key from the [lenv] section)
49 * @return the reported status char* (temporary/final result)
50 */
51char* getStatusId(maps* conf,char* pid){
52  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
53  char* fbkpid =
54    (char *)
55    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
56  sprintf (fbkpid, "%s/%s.sid", r_inputs->value, pid);
57  FILE* f0 = fopen (fbkpid, "r");
58  if(f0!=NULL){
59    long flen;
60    char *fcontent;
61    fseek (f0, 0, SEEK_END);
62    flen = ftell (f0);
63    fseek (f0, 0, SEEK_SET);
64    fcontent = (char *) malloc ((flen + 1) * sizeof (char));
65    fread(fcontent,flen,1,f0);
66    fcontent[flen]=0;
67    fclose(f0);
68    return fcontent;
69  }else
70    return NULL;
71}
72
73/**
74 * Acquire the global lock
75 *
76 * @param conf the maps containing the setting of the main.cfg file
77 * @return a semid
78 */
79semid acquireLock(maps* conf){
80  semid lockid;
81  int itn=0;
82 toRetry1:
83  lockid=getShmLockId(conf,1);
84  if(
85#ifdef WIN32
86     lockid==NULL
87#else
88     lockid<0
89#endif
90     ){
91#ifdef WIN32
92    return NULL;
93#else
94    return -1;
95#endif
96  }
97  if(lockShm(lockid)<0){
98#ifdef WIN32
99      return NULL;
100#else
101    if(itn<ZOO_LOCK_MAX_RETRY){
102      itn++;
103      goto toRetry1;
104    }else
105      return -1;
106#endif
107  }else
108    return lockid;
109}
110
111/**
112 * Read the cache file of a running service
113 *
114 * @param conf the maps containing the setting of the main.cfg file
115 * @param pid the service identifier (usid key from the [lenv] section)
116 * @return the reported status char* (temporary/final result)
117 */
118char* _getStatusFile(maps* conf,char* pid){
119  map* tmpTmap = getMapFromMaps (conf, "main", "tmpPath");
120
121  struct dirent *dp;
122  DIR *dirp = opendir(tmpTmap->value);
123  char fileName[1024];
124  int hasFile=-1;
125  if(dirp!=NULL){
126    char tmp[128];
127    sprintf(tmp,"_%s.xml",pid);
128    while ((dp = readdir(dirp)) != NULL){
129#ifdef DEBUG
130      fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
131#endif
132      if(strstr(dp->d_name,"final_")==0 && strstr(dp->d_name,tmp)!=0){
133        sprintf(fileName,"%s/%s",tmpTmap->value,dp->d_name);
134        hasFile=1;
135        break;
136      }
137    }
138  }
139  if(hasFile>0){
140    semid lockid;
141    char* stat=getStatusId(conf,pid);
142    if(stat!=NULL){
143      setMapInMaps(conf,"lenv","lid",stat);
144      lockid=acquireLock(conf);
145      if(lockid<0)
146        return NULL;
147    }
148
149    //FILE* f0 = fopen (fileName, "r");
150    // knut: open file in binary mode to avoid conversion of line endings (yielding extra bytes) on Windows platforms
151    FILE* f0 = fopen(fileName, "rb"); 
152    if(f0!=NULL){
153      fseek (f0, 0, SEEK_END);
154      long flen = ftell (f0);
155      fseek (f0, 0, SEEK_SET);
156      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
157      fread(tmps1,flen,1,f0);
158      tmps1[flen]=0;
159      fclose(f0);
160      if(stat!=NULL){
161        unlockShm(lockid);
162        free(stat);
163      }
164      return tmps1;
165    }
166    else{
167      if(stat!=NULL){
168        unlockShm(lockid);
169        free(stat);
170      }
171      return NULL;
172    }
173  }
174  else
175    return NULL;
176}
177
178/**
179 * Get the ongoing status of a running service
180 *
181 * @param conf the maps containing the setting of the main.cfg file
182 * @param pid the service identifier (usid key from the [lenv] section)
183 * @return the reported status char* (MESSAGE|POURCENTAGE)
184 */
185char* _getStatus(maps* conf,char* lid){
186  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
187  char* fbkpid =
188    (char *)
189    malloc ((strlen (r_inputs->value) + strlen (lid) + 9) * sizeof (char));
190  sprintf (fbkpid, "%s/%s.status", r_inputs->value, lid);
191  FILE* f0 = fopen (fbkpid, "r");
192  if(f0!=NULL){   
193    semid lockid = NULL;
194    char* stat;
195    long flen;
196    stat=getStatusId(conf,lid);
197    if(stat!=NULL){
198      setMapInMaps(conf,"lenv","lid",stat);
199      lockid=acquireLock(conf);
200      if(lockid<0)
201        return NULL;
202    }
203    fseek (f0, 0, SEEK_END);
204    flen = ftell (f0);
205    if(flen>0){
206      char *fcontent;
207      fseek (f0, 0, SEEK_SET);
208      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
209      fread(fcontent,flen,1,f0);
210      fcontent[flen]=0;
211      fclose(f0);
212      free(fbkpid);
213      if(stat!=NULL){
214#ifndef WIN32
215        removeShmLock(conf,1);
216#else
217        unlockShm(lockid);
218#endif
219        free(stat);
220      }
221      return fcontent;
222    }
223    fclose(f0);
224    free(fbkpid);
225    if(stat!=NULL){
226      removeShmLock(conf,1);
227      free(stat);
228    }
229    return NULL;
230  }else{
231    free(fbkpid);
232    char* stat=getStatusId(conf,lid);
233    setMapInMaps(conf,"lenv","lid",stat);
234    removeShmLock(conf,1);
235    return NULL;
236  }
237}
238
239/**
240 * Stop handling status repport.
241 *
242 * @param conf the map containing the setting of the main.cfg file
243 */
244void unhandleStatus(maps *conf){
245  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
246  map* usid = getMapFromMaps (conf, "lenv", "usid");
247  char* fbkpid =
248    (char *) malloc ((strlen (r_inputs->value) + strlen (usid->value) + 9) 
249                     * sizeof (char));
250  sprintf (fbkpid, "%s/%s.status", r_inputs->value, usid->value);
251  unlink(fbkpid);
252  free(fbkpid);
253}
254
255/**
256 * Update the current status of the running service.
257 *
258 * @see acquireLock, lockShm
259 * @param conf the map containing the setting of the main.cfg file
260 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
261 */
262int _updateStatus(maps *conf){
263       
264  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
265  map* sid = getMapFromMaps (conf, "lenv", "usid");
266 
267  char* fbkpid =
268    (char *)
269    malloc ((strlen (r_inputs->value) + strlen (sid->value) + 9) * sizeof (char));
270  sprintf (fbkpid, "%s/%s.status", r_inputs->value, sid->value);
271  map* status=getMapFromMaps(conf,"lenv","status");
272  map* msg=getMapFromMaps(conf,"lenv","message");
273  if(status!=NULL && msg!=NULL &&
274     status->value!=NULL && msg->value!=NULL && 
275     strlen(status->value)>0 && strlen(msg->value)>1){   
276    semid lockid = NULL;
277       
278    char* stat=getStatusId(conf,sid->value);
279    if(stat!=NULL){
280      lockid=acquireLock(conf);
281      if(lockid<0){
282        dumpMap(status);
283        return ZOO_LOCK_ACQUIRE_FAILED;
284      }
285    }
286    FILE* fstatus=fopen(fbkpid,"w");
287    if(fstatus!=NULL){
288      fprintf(fstatus,"%s|%s",status->value,msg->value);
289      fflush(fstatus);
290      fclose(fstatus);
291    }
292    if(stat!=NULL){
293      unlockShm(lockid);
294      free(stat);
295    }
296  }
297
298  return 0;
299}
300
301#endif
302
303#ifdef WIN32
304
305#define SHMEMSIZE 4096
306
307size_t getKeyValue(maps* conf, char* key, size_t length){
308  if(conf==NULL) {
309    strncpy(key, "700666", length);
310    return strlen(key);
311  }
312 
313  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
314  if(tmpMap==NULL)
315    tmpMap=getMapFromMaps(conf,"lenv","osid");
316
317  if(tmpMap!=NULL){
318    snprintf(key, length, "zoo_sem_%s", tmpMap->value);     
319  }
320  else {
321    strncpy(key, "-1", length);
322  }
323  return strlen(key);
324}
325
326
327semid getShmLockId(maps* conf, int nsems){
328  semid sem_id;
329  char key[MAX_PATH];
330  getKeyValue(conf, key, MAX_PATH);
331 
332  sem_id = CreateSemaphore( NULL, nsems, nsems+1, key);
333  if(sem_id==NULL){
334#ifdef DEBUG
335    fprintf(stderr,"Semaphore failed to create: %s\n", getLastErrorMessage());
336#endif
337    return NULL;
338  }
339#ifdef DEBUG
340  fprintf(stderr,"%s Accessed !\n",key);
341#endif
342  return sem_id;
343}
344
345int removeShmLock(maps* conf, int nsems){
346  semid sem_id=getShmLockId(conf,1);
347  if (CloseHandle(sem_id) == 0) {
348#ifdef DEBUG
349    fprintf(stderr,"Unable to remove semaphore: %s\n", getLastErrorMessage());
350#endif
351    return -1;
352  }
353#ifdef DEBUG
354  fprintf(stderr,"%d Removed !\n",sem_id);
355#endif
356  return 0;
357}
358
359int lockShm(semid id){
360  DWORD dwWaitResult=WaitForSingleObject(id,INFINITE);
361  switch (dwWaitResult){
362    case WAIT_OBJECT_0:
363      return 0;
364      break;
365    case WAIT_TIMEOUT:
366      return -1;
367      break;
368    default:
369      return -2;
370      break;
371  }
372  return 0;
373}
374
375int unlockShm(semid id){
376  if(!ReleaseSemaphore(id,1,NULL)){
377    return -1;
378  }
379  return 0;
380}
381
382static LPVOID lpvMemG = NULL;      // pointer to shared memory
383static HANDLE hMapObjectG = NULL;  // handle to file mapping
384
385
386char* getStatus(int pid){
387  char *lpszBuf=(char*) malloc(SHMEMSIZE*sizeof(char));
388  int i=0;
389  LPWSTR lpszTmp=NULL;
390  LPVOID lpvMem = NULL;
391  HANDLE hMapObject = NULL;
392  BOOL fIgnore,fInit;
393  char tmp[1024];
394  sprintf(tmp,"%d",pid);
395  if(hMapObject==NULL)
396    hMapObject = CreateFileMapping( 
397                                   INVALID_HANDLE_VALUE,   // use paging file
398                                   NULL,                   // default security attributes
399                                   PAGE_READWRITE,         // read/write access
400                                   0,                      // size: high 32-bits
401                                   4096,                   // size: low 32-bits
402                                   TEXT(tmp));   // name of map object
403  if (hMapObject == NULL){
404#ifdef DEBUG
405    fprintf(stderr,"ERROR on line %d\n",__LINE__);
406#endif
407    return "-1";
408  }
409  if((GetLastError() != ERROR_ALREADY_EXISTS)){
410#ifdef DEBUG
411    fprintf(stderr,"ERROR on line %d\n",__LINE__);
412    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
413#endif
414    fIgnore = UnmapViewOfFile(lpvMem); 
415    fIgnore = CloseHandle(hMapObject);
416    return "-1";
417  }
418  fInit=TRUE;
419  if(lpvMem==NULL)
420    lpvMem = MapViewOfFile( 
421                           hMapObject,     // object to map view of
422                           FILE_MAP_READ,  // read/write access
423                           0,              // high offset:  map from
424                           0,              // low offset:   beginning
425                           0);             // default: map entire file
426  if (lpvMem == NULL){
427#ifdef DEBUG
428    fprintf(stderr,"READING STRING S %d\n",__LINE__);
429    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
430#endif
431    return "-1"; 
432  }
433  lpszTmp = (LPWSTR) lpvMem;
434  while (*lpszTmp){
435    lpszBuf[i] = (char)*lpszTmp;
436    *lpszTmp++; 
437    lpszBuf[i+1] = '\0'; 
438    i++;
439  }
440  return (char*)lpszBuf;
441}
442
443#else
444/**
445 * Number of time to try to access a semaphores set
446 * @see getShmLockId
447 */
448#define MAX_RETRIES 10
449
450#ifndef __APPLE__
451/**
452 * arg for semctl system calls.
453 */
454union semun {
455  int val; //!< value for SETVAL
456  struct semid_ds *buf; //!< buffer for IPC_STAT & IPC_SET
457  ushort *array; //!< array for GETALL & SETALL
458};
459#endif
460
461/**
462 * Set in the pre-allocated key the zoo_sem_[OSID] string
463 * where [OSID] is the lid (if any) or osid value from the [lenv] section.
464 *
465 * @param conf the map containing the setting of the main.cfg file
466 */
467int getKeyValue(maps* conf){
468  if(conf==NULL)
469     return 700666;
470  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
471  if(tmpMap==NULL)
472    tmpMap=getMapFromMaps(conf,"lenv","osid");
473  int key=-1;
474  if(tmpMap!=NULL)
475    key=atoi(tmpMap->value);
476  return key;
477}
478
479/**
480 * Try to create or access a semaphore set.
481 *
482 * @see getKeyValue
483 * @param conf the map containing the setting of the main.cfg file
484 * @param nsems number of semaphores
485 * @return a semaphores set indentifier on success, -1 in other case
486 */
487int getShmLockId(maps* conf, int nsems){
488    int i;
489    union semun arg;
490    struct semid_ds buf;
491    struct sembuf sb;
492    semid sem_id;
493    int key=getKeyValue(conf);
494   
495    sem_id = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666);
496
497    if (sem_id >= 0) { /* we got it first */
498        sb.sem_op = 1; 
499        sb.sem_flg = 0;
500        arg.val=1;
501        for(sb.sem_num = 0; sb.sem_num < nsems; sb.sem_num++) { 
502            /* do a semop() to "free" the semaphores. */
503            /* this sets the sem_otime field, as needed below. */
504            if (semop(sem_id, &sb, 1) == -1) {
505                int e = errno;
506                semctl(sem_id, 0, IPC_RMID); /* clean up */
507                errno = e;
508                return -1; /* error, check errno */
509            }
510        }
511    } else if (errno == EEXIST) { /* someone else got it first */
512        int ready = 0;
513
514        sem_id = semget(key, nsems, 0); /* get the id */
515        if (sem_id < 0) return sem_id; /* error, check errno */
516
517        /* wait for other process to initialize the semaphore: */
518        arg.buf = &buf;
519        for(i = 0; i < MAX_RETRIES && !ready; i++) {
520            semctl(sem_id, nsems-1, IPC_STAT, arg);
521            if (arg.buf->sem_otime != 0) {
522#ifdef DEBUG
523              fprintf(stderr,"Semaphore acquired ...\n");
524#endif
525              ready = 1;
526            } else {
527#ifdef DEBUG
528              fprintf(stderr,"Retry to access the semaphore later ...\n");
529#endif
530              zSleep(1);
531            }
532        }
533        errno = ZOO_LOCK_ACQUIRE_FAILED;
534        if (!ready) {
535#ifdef DEBUG
536          fprintf(stderr,"Unable to access the semaphore ...\n");
537#endif
538          errno = ETIME;
539          return -1;
540        }
541    } else {
542        return sem_id; /* error, check errno */
543    }
544#ifdef DEBUG
545    fprintf(stderr,"%d Created !\n",sem_id);
546#endif
547    return sem_id;
548}
549
550/**
551 * Try to remove a semaphore set.
552 *
553 * @param conf the map containing the setting of the main.cfg file
554 * @param nsems number of semaphores
555 * @return 0 if the semaphore can be removed, -1 in other case.
556 */
557int removeShmLock(maps* conf, int nsems){
558  union semun arg;
559  int sem_id=getShmLockId(conf,nsems);
560  if (semctl(sem_id, 0, IPC_RMID, arg) == -1) {
561#ifdef DEBUG
562    perror("semctl remove");
563#endif
564    return -1;
565  }
566#ifdef DEBUG
567  fprintf(stderr,"Semaphore removed!\n");
568#endif
569  return 0;
570}
571
572/**
573 * Lock a semaphore set.
574 *
575 * @param id the semaphores set indetifier
576 * @return 0 if the semaphore can be locked, -1 in other case.
577 */
578int lockShm(int id){
579  struct sembuf sb;
580  sb.sem_num = 0;
581  sb.sem_op = -1;  /* set to allocate resource */
582  sb.sem_flg = SEM_UNDO;
583  if (semop(id, &sb, 1) == -1){
584#ifdef DEBUG
585    perror("semop lock");
586#endif
587    return -1;
588  }
589  return 0;
590}
591
592/**
593 * unLock a semaphore set.
594 *
595 * @param id the semaphores set indetifier
596 * @return 0 if the semaphore can be locked, -1 in other case.
597 */
598int unlockShm(int id){
599  struct sembuf sb;
600  sb.sem_num = 0;
601  sb.sem_op = 1;  /* free resource */
602  sb.sem_flg = SEM_UNDO;
603  if (semop(id, &sb, 1) == -1) {
604#ifdef DEBUG
605    perror("semop unlock");
606#endif
607    return -1;
608  }
609  return 0;
610}
611
612/**
613 * Get the current status of the running service.
614 *
615 * @see getKeyValue, getShmLockId, lockShm
616 * @param pid the semaphores
617 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
618 */
619char* getStatus(int pid){
620  int shmid;
621  key_t key;
622  void *shm;
623  key=pid;
624  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
625#ifdef DEBUG
626    fprintf(stderr,"shmget failed in getStatus\n");
627#endif
628  }else{
629    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
630#ifdef DEBUG
631      fprintf(stderr,"shmat failed in getStatus\n");
632#endif
633    }else{
634      char *ret=strdup((char*)shm);
635      shmdt((void *)shm);
636      return ret;
637    }
638  }
639  return (char*)"-1";
640}
641
642#endif
643
644/**
645 * Update the status of an ongoing service
646 *
647 * @param conf the maps containing the settings of the main.cfg file
648 * @param percentCompleted percentage of completude of execution of the service
649 * @param message information about the current step executed
650 * @return the value of _updateStatus
651 * @see _updateStatus
652 */
653int updateStatus( maps* conf, const int percentCompleted, const char* message ){
654  char tmp[4];
655  snprintf(tmp,4,"%d",percentCompleted);
656  setMapInMaps( conf, "lenv", "status", tmp );
657  setMapInMaps( conf, "lenv", "message", message);
658  return _updateStatus( conf );
659}
660
661/**
662 * Access an input value
663 *
664 * @param inputs the maps to search for the input value
665 * @param parameterName the input name to fetch the value
666 * @param numberOfBytes the resulting size of the value to add (for binary
667 *  values), -1 for basic char* data
668 * @return a pointer to the input value if found, NULL in other case.
669 */
670char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
671  map* res=getMapFromMaps(inputs,parameterName,"value");
672  if(res!=NULL){
673    map* size=getMapFromMaps(inputs,parameterName,"size");
674    if(size!=NULL){
675      *numberOfBytes=(size_t)atoi(size->value);
676      return res->value;
677    }else{
678      *numberOfBytes=strlen(res->value);
679      return res->value;
680    }
681  }
682  return NULL;
683}
684
685/**
686 * Read a file using the GDAL VSI API
687 *
688 * @param conf the maps containing the settings of the main.cfg file
689 * @param dataSource the datasource name to read
690 * @warning make sure to free resources returned by this function
691 */
692char *readVSIFile(maps* conf,const char* dataSource){
693    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
694    VSIStatBufL file_status;
695    VSIStatL(dataSource, &file_status);
696    if(fichier==NULL){
697      char tmp[1024];
698      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %lld.",
699              dataSource,file_status.st_size);
700      setMapInMaps(conf,"lenv","message",tmp);
701      return NULL;
702    }
703    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
704    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
705    res1[file_status.st_size-1]=0;
706    VSIFCloseL(fichier);
707    VSIUnlink(dataSource);
708    return res1;
709}
710
711/**
712 * Set an output value
713 *
714 * @param outputs the maps to define the output value
715 * @param parameterName the output name to set the value
716 * @param data the value to set
717 * @param numberOfBytes size of the value to add (for binary values), -1 for
718 *  basic char* data
719 * @return 0
720 */
721int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
722  if(numberOfBytes==-1){
723    setMapInMaps(outputs,parameterName,"value",data);
724  }else{
725    char size[1024];
726    map* tmp=getMapFromMaps(outputs,parameterName,"value");
727    if(tmp==NULL){
728      setMapInMaps(outputs,parameterName,"value","");
729      tmp=getMapFromMaps(outputs,parameterName,"value");
730    }
731    free(tmp->value);
732    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
733    memcpy(tmp->value,data,numberOfBytes);
734    sprintf(size,"%lu",numberOfBytes);
735    setMapInMaps(outputs,parameterName,"size",size);
736  }
737  return 0;
738}
739
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