source: trunk/zoo-project/zoo-kernel/service_internal_js.c @ 917

Last change on this file since 917 was 917, checked in by djay, 5 years ago

Merge prototype-v0 branch in trunk

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 28.0 KB
RevLine 
[580]1/*
[1]2 * Author : Gérald FENOY
3 *
[360]4 * Copyright (c) 2009-2012 GeoLabs SARL
[1]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
[640]25#include "service_internal_js.h"
26#include "response_print.h"
[1]27
[383]28#ifndef JSCLASS_GLOBAL_FLAGS
29#define JSCLSAS_GLOBAL_FLAGS 0
30#endif
31
[1]32static char dbg[1024];
33
[580]34/**
35 * The function used as alert from the JavaScript environment (ZOO-API)
36 *
37 * @param cx the JavaScript context
38 * @param argc the number of parameters
39 * @param argv1 the parameter values
40 * @return true
41 */
[274]42JSBool
43JSAlert(JSContext *cx, uintN argc, jsval *argv1)
44{
45  jsval *argv = JS_ARGV(cx,argv1);
46  int i=0;
47  JS_MaybeGC(cx);
48  for(i=0;i<argc;i++){
49    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
[471]50    char *tmp=JS_EncodeString(cx,jsmsg);
51    fprintf(stderr,"[ZOO-API:JS] %s\n",tmp);
52    free(tmp);
[274]53  }
54  JS_MaybeGC(cx);
55 
56  return JS_TRUE;
57}
58
[580]59/**
60 * The function used as importScript from the JavaScript environment (ZOO-API)
61 *
62 * @param cx the JavaScript context
63 * @param argc the number of parameters
64 * @param argv1 the parameter values
65 * @return true
66 */
[336]67JSBool
68JSLoadScripts(JSContext *cx, uintN argc, jsval *argv1)
69{
70  JS_MaybeGC(cx);
71
72  jsval *argv = JS_ARGV(cx,argv1);
73  int i=0;
74  JS_MaybeGC(cx);
75  for(i=0;i<argc;i++){
76    char *filename = JSValToChar(cx,&argv[i]);
77#ifdef JS_DEBUG
78    fprintf(stderr,"Trying to load %s\n",api0);
[364]79    fflush(stderr);
[336]80#endif
[784]81    JSObject *api_script1=loadZooApiFile(cx,JS_GetGlobalObject(cx),filename);
[336]82  }
83  JS_MaybeGC(cx);
84  JS_SET_RVAL(cx, argv1, JSVAL_VOID);
85 
86  return JS_TRUE;
87}
88
[580]89/**
90 * Load a JavaScript file then run the function corresponding to the service by
91 * passing the conf, inputs and outputs parameters by value as JavaScript
92 * Objects.
93 *
94 * @param main_conf the conf maps containing the main.cfg settings
95 * @param request the map containing the HTTP request
96 * @param s the service structure
97 * @param inputs the maps containing the inputs
98 * @param outputs the maps containing the outputs
[581]99 * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1
[580]100 *  if the service failed to load or throw error at runtime.
101 */
102int zoo_js_support(maps** main_conf,map* request,service* s,maps **inputs,maps **outputs)
[1]103{
[640]104  /*maps* main=*main_conf;
[9]105  maps* _inputs=*inputs;
[640]106  maps* _outputs=*outputs;*/
[9]107
[1]108  /* The class of the global object. */
[383]109  JSClass global_class= {
[1]110    "global", JSCLASS_GLOBAL_FLAGS,
[364]111    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
[1]112    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
113    JSCLASS_NO_OPTIONAL_MEMBERS
114  };
115
116  /* JS variables. */
117  JSRuntime *rt;
118  JSContext *cx;
119  JSObject  *global;
120
121  /* Create a JS runtime. */
122  rt = JS_NewRuntime(8L * 1024L * 1024L);
123  if (rt == NULL)
124    return 1;
[9]125 
[1]126  /* Create a context. */
[384]127  cx = JS_NewContext(rt,8192);
[1]128  if (cx == NULL){
129    return 1;
130  }
[383]131  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
[1]132  JS_SetVersion(cx, JSVERSION_LATEST);
133  JS_SetErrorReporter(cx, reportError);
134
135  /* Create the global object. */
[328]136  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
[1]137
138  /* Populate the global object with the standard globals,
139     like Object and Array. */
140  if (!JS_InitStandardClasses(cx, global)){
141    return 1;
142  }
[274]143
[403]144  /* Define specific function and global variable to share with JS runtime
145   */
[368]146  jsval tmp=INT_TO_JSVAL(3);
147  if (!JS_SetProperty(cx, global, "SERVICE_SUCCEEDED", &tmp))
148    return 1;
149  tmp=INT_TO_JSVAL(4);
150  if (!JS_SetProperty(cx, global, "SERVICE_FAILED", &tmp))
151    return 1;
[1]152  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
153    return 1;
[377]154  if (!JS_DefineFunction(cx, global, "ZOOTranslate", JSTranslate, 4, 0))
155    return 1;
[26]156  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
157    return 1;
[274]158  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
[336]159    return 1; 
[917]160  if (!JS_DefineFunction(cx, global, "sleep", JSSleep, 1, 0))
161    return 1; 
[336]162  if (!JS_DefineFunction(cx, global, "importScripts", JSLoadScripts, 1, 0))
[274]163    return 1;
[1]164
[336]165  /**
166   * Add private context object
167   */
168  void* cxPrivate = request;
169  JS_SetContextPrivate(cx,cxPrivate);
[505]170
[42]171  map* tmpm1=getMap(request,"metapath");
172  char ntmp[1024];
[784]173  map* cwdMap=getMapFromMaps(*main_conf,"main","servicePath");
174  if(cwdMap!=NULL)
175    sprintf(ntmp,"%s",cwdMap->value);
176  else
177    getcwd(ntmp,1024);
[42]178
179  /**
180   * Load the first part of the ZOO-API
181   */
[505]182  char *api0=(char*)malloc((strlen(ntmp)+17)*sizeof(char));
183  sprintf(api0,"%s/ZOO-proj4js.js",ntmp);
[274]184#ifdef JS_DEBUG
[42]185  fprintf(stderr,"Trying to load %s\n",api0);
[274]186#endif
187  JSObject *api_script1=loadZooApiFile(cx,global,api0);
[471]188  free(api0);
[42]189  fflush(stderr);
190
[505]191  char *api1=(char*)malloc((strlen(ntmp)+13)*sizeof(char));
192  sprintf(api1,"%s/ZOO-api.js",ntmp);
[274]193#ifdef JS_DEBUG
[42]194  fprintf(stderr,"Trying to load %s\n",api1);
[274]195#endif
196  JSObject *api_script2=loadZooApiFile(cx,global,api1);
[471]197  free(api1);
[42]198  fflush(stderr);
199
[1]200  /* Your application code here. This may include JSAPI calls
201     to create your own custom JS objects and run scripts. */
[640]202  //maps* out=*outputs;
[1]203  int res=SERVICE_FAILED;
[640]204  //maps* mc=*main_conf;
[1]205  map* tmpm2=getMap(s->content,"serviceProvider");
[42]206
[364]207  char *filename=(char*)malloc(strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3);
[329]208  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
209  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
[274]210#ifdef JS_DEBUG
[26]211  fprintf(stderr,"FILENAME %s\n",filename);
[274]212#endif
[1]213  struct stat file_status;
214  stat(filename, &file_status);
[471]215  //char *source=(char*)malloc(file_status.st_size);
[640]216  //uint16 lineno;
[1]217  jsval rval;
218  JSBool ok ;
[274]219  JSObject *script = JS_CompileFile(cx, global, filename);
[9]220  if(script!=NULL){
[1]221    (void)JS_ExecuteScript(cx, global, script, &rval);
222  }
223  else{
224    char tmp1[1024];
225    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
[471]226    free(filename);
[576]227    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
[471]228    JS_MaybeGC(cx);
[1]229    JS_DestroyContext(cx);
230    JS_DestroyRuntime(rt);
231    JS_ShutDown();
[471]232    return -1;
[1]233  }
[471]234 
[383]235
[1]236  /* Call a function in obj's scope. */
237  jsval argv[3];
[9]238  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
239  argv[0] = OBJECT_TO_JSVAL(jsargv1);
240  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
241  argv[1] = OBJECT_TO_JSVAL(jsargv2);
242  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
243  argv[2] = OBJECT_TO_JSVAL(jsargv3);
244  jsval rval1=JSVAL_NULL;
[1]245#ifdef JS_DEBUG
246  fprintf(stderr, "object %p\n", (void *) argv[2]);
247#endif
248
249  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
250
251#ifdef JS_DEBUG
252  fprintf(stderr, "object %p\n", (void *) argv[2]);
253#endif
254
255  JSObject *d;
[9]256  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
[1]257#ifdef JS_DEBUG
258    fprintf(stderr,"Function run sucessfully !\n");
259#endif
260    /* Should get a number back from the service function call. */
261    ok = JS_ValueToObject(cx, rval1, &d);
262  }else{
263    /* Unable to run JS function */
264    char tmp1[1024];
[9]265    if(strlen(dbg)==0)
266      sprintf(dbg,"No result was found after the function call");
[274]267    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
268#ifdef JS_DEBUG
[1]269    fprintf(stderr,"%s",tmp1);
[274]270#endif
[576]271    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
[471]272    free(filename);
273    JS_MaybeGC(cx);
[1]274    JS_DestroyContext(cx);
275    JS_DestroyRuntime(rt);
276    JS_ShutDown();
[9]277    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
[471]278    return -1;
[1]279  }
280
[640]281  //jsval t=OBJECT_TO_JSVAL(d);
[9]282  if(JS_IsArrayObject(cx,d)){
[1]283#ifdef JS_DEBUG
284    fprintf(stderr,"An array was returned !\n");
285#endif
[364]286    jsuint       len;
[9]287    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
[1]288#ifdef JS_DEBUG
289      fprintf(stderr,"outputs array is empty\n");
290#endif
291    }
292    jsval tmp1;
[9]293    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
[1]294    res=JSVAL_TO_INT(tmp1);
295#ifdef JS_DEBUG
296    fprintf(stderr," * %d * \n",res);
297#endif
[383]298    if(res==SERVICE_SUCCEEDED){
299      jsval tmp2;
300      JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
301      if(hasElement==JS_TRUE){
302        freeMaps(outputs);
303        free(*outputs);
304        *outputs=mapsFromJSObject(cx,tmp2);
305      }
306    }else{
307      jsval tmp3;
308      JSBool hasConf=JS_GetElement(cx,d,1,&tmp3);
309      if(hasConf==JS_TRUE){
310        freeMaps(main_conf);
311        free(*main_conf);
312        *main_conf=mapsFromJSObject(cx,tmp3);
313      }
[9]314    }
[383]315
[1]316  }
317  else{
[9]318#ifdef JS_DEBUG
[383]319    fprintf(stderr,"The service didn't return an array !\n");
[9]320#endif
[383]321    /**
322     * Extract result
323     */
[1]324    jsval tmp1;
[9]325    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
[1]326    res=JSVAL_TO_INT(tmp1);
327
[9]328#ifdef JS_DEBUG
[1]329    fprintf(stderr," * %d * \n",res);
[9]330#endif
[383]331    /**
332     * Extract outputs when available.
333     */
[1]334    jsval tmp2;
[9]335    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
[383]336    if(!JSVAL_IS_VOID(tmp2) && hasElement==JS_TRUE){
337      freeMaps(outputs);
338      free(*outputs);   
339      *outputs=mapsFromJSObject(cx,tmp2);
340    }
341    JS_MaybeGC(cx);
[274]342#ifdef JS_DEBUG
[383]343    if(JSVAL_IS_VOID(tmp2))
[1]344      fprintf(stderr,"No outputs property returned\n");
[383]345    else{
346      if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
347        fprintf(stderr,"outputs is an array as expected\n");
348      else
349        fprintf(stderr,"outputs is not an array as expected\n");
350    }
351    JS_MaybeGC(cx);
[274]352#endif
[383]353
354    /**
355     * Extract conf when available.
356     */
357    jsval tmp3;
358    JSBool hasConf=JS_GetProperty(cx,d,"conf",&tmp3);
359    if(!JSVAL_IS_VOID(tmp3) && hasConf==JS_TRUE){
360      freeMaps(main_conf);
361      free(*main_conf);
362      *main_conf=mapsFromJSObject(cx,tmp3);
363    }
364    JS_MaybeGC(cx);
365
[1]366#ifdef JS_DEBUG
[364]367    dumpMaps(*outputs);
[1]368#endif
369  }
370  /* Cleanup. */
[383]371  JS_MaybeGC(cx);
[274]372  JS_DestroyContext(cx);
[1]373  JS_DestroyRuntime(rt);
374  JS_ShutDown();
[471]375  free(filename);
[1]376#ifdef JS_DEBUG
377  fprintf(stderr,"Returned value %d\n",res);
378#endif
379  return res;
380}
381
[580]382/**
383 * Load a JavaScript file
384 *
385 * @param cx the JavaScript context
[586]386 * @param global the global JavaScript object (not used)
[580]387 * @param filename the file name to load
[781]388 * @return a JavaScript Object on success, NULL if an errro occurred
[580]389 */
[274]390JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
[42]391  struct stat api_status;
392  int s=stat(filename, &api_status);
393  if(s==0){
394    jsval rval;
[274]395    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
[42]396    if(script!=NULL){
[274]397      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
398#ifdef JS_DEBUG
[42]399      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
[274]400#endif
[42]401      return script;
402    }
[274]403#ifdef JS_DEBUG
[42]404    else
405      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
[274]406#endif
[42]407  }
[274]408#ifdef JS_DEBUG
[42]409  else
410    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
[274]411#endif
[42]412  return NULL;
413}
414
[580]415/**
416 * Convert a maps to a JavaScript Object
417 *
418 * @param cx the JavaScript context
419 * @param t the maps to convert
420 * @return a new JavaScript Object
421 */
[1]422JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
[328]423  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
[9]424  if(res==NULL)
425    fprintf(stderr,"Array Object is NULL!\n");
[1]426  maps* tmp=t;
427  while(tmp!=NULL){
428    JSObject *pval=JSObject_FromMap(cx,tmp->content);
[790]429    if(tmp->child!=NULL){
430      JSObject *pvalc=JSObject_FromMaps(cx,tmp->child);
431      jsval pvaljc=OBJECT_TO_JSVAL(pvalc);
432      JS_SetProperty(cx, pval, "child", &pvaljc);
433    }
[1]434    jsval pvalj=OBJECT_TO_JSVAL(pval);
[328]435    JS_SetProperty(cx, res, tmp->name, &pvalj);
[1]436#ifdef JS_DEBUG
437    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
438#endif
439    tmp=tmp->next;
440  } 
441  return res;
442}
443
[580]444/**
445 * Convert a map to a JavaScript Object
446 *
447 * @param cx the JavaScript context
448 * @param t the map to convert
449 * @return a new JavaScript Object
450 */
[1]451JSObject* JSObject_FromMap(JSContext *cx,map* t){
452  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
453  map* tmpm=t;
[360]454  map* isArray=getMap(t,"isArray");
455  map* isBinary=getMap(t,"size");
456  map* tmap=getMapType(t);
[403]457#ifdef JS_DEBUG
[360]458  if(tmap==NULL)
459    fprintf(stderr,"tmap is null !\n");
460  else
461    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
[364]462#endif
[640]463  while(isArray==NULL && tmpm!=NULL){
[410]464    jsval jsstr;
[752]465    if(isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0)
[410]466      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
467    else
468      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
469    JS_SetProperty(cx, res, tmpm->name,&jsstr);
[1]470#ifdef JS_DEBUG
[410]471    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
[1]472#endif
[410]473    tmpm=tmpm->next;
[1]474  }
[410]475  if(isArray!=NULL){
[360]476    map* len=getMap(t,"length");
477    int cnt=atoi(len->value);
478    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
479    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
[752]480    map *tmpm1,*tmpm2,*tmpm3;
[360]481    int i=0;
482    for(i=0;i<cnt;i++){
483      tmpm1=getMapArray(t,"value",i);
484      tmpm2=getMapArray(t,tmap->name,i);
[752]485      tmpm3=getMapArray(t,"size",i);
[360]486      if(tmpm1!=NULL){
[752]487        jsval jsstr;
488        if(tmpm3!=NULL)
489          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,atoi(tmpm3->value)));
490        else
491          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
[360]492        JS_SetElement( cx, values, i, &jsstr );
493      }
494      if(tmpm2!=NULL){
495        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
496        JS_SetElement( cx, mvalues, i, &jsstr );
497      }
498    }
499    jsval jvalues=OBJECT_TO_JSVAL(values);
500    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
501    JS_SetProperty(cx, res,"value",&jvalues);
502    JS_SetProperty(cx, res,tmap->name,&jmvalues);
[752]503    while(tmpm!=NULL){
504      if(strncasecmp(tmpm->name,"value",5)!=0 && strncasecmp(tmpm->name,"size",4)!=0 && strncasecmp(tmpm->name,tmap->name,strlen(tmap->name))!=0){
505        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
506        JS_SetProperty(cx, res, tmpm->name,&jsstr);
507      }
508#ifdef JS_DEBUG
509      fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
510#endif
511      tmpm=tmpm->next;
512    }
[360]513  }
[1]514  return res;
515}
516
[580]517/**
518 * Convert a JavaScript Object to a maps
519 *
520 * @param cx the JavaScript context
521 * @param t the JavaScript Object to convert
522 * @return a new maps containing the JavaScript Object
523 */
[1]524maps* mapsFromJSObject(JSContext *cx,jsval t){
525  maps *res=NULL;
526  maps *tres=NULL;
[9]527  jsint oi=0;
528  JSObject* tt=JSVAL_TO_OBJECT(t);
[333]529  if(JS_IsArrayObject(cx,tt)){
[1]530#ifdef JS_DEBUG
531    fprintf(stderr,"Is finally an array !\n");
[333]532#endif
[1]533  }
[333]534  else{
535#ifdef JS_DEBUG
[1]536    fprintf(stderr,"Is not an array !\n");
537#endif
[333]538    JSIdArray *idp=JS_Enumerate(cx,tt);
539    if(idp!=NULL) {
540      int index;
541      jsdouble argNum;
542#ifdef JS_DEBUG
543      fprintf(stderr,"Properties length :  %d \n",idp->length);
544#endif
545     
546      for (index=0,argNum=idp->length;index<argNum;index++) { 
547        jsval id = idp->vector[index];
548        jsval vp;
549        JS_IdToValue(cx,id,&vp);
[640]550        char *tmp;
[333]551        JSString *jsmsg;
552        size_t len1;
553        jsmsg = JS_ValueToString(cx,vp);
554        len1 = JS_GetStringLength(jsmsg);
[471]555       
556        tmp=JS_EncodeString(cx,jsmsg);
[790]557        tres=createMaps(tmp);
[333]558
559        jsval nvp=JSVAL_NULL;
[471]560        if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
[333]561#ifdef JS_DEBUG
[471]562          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
[333]563#endif
564        }
[471]565        free(tmp);
[364]566        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
[333]567        JS_ValueToObject(cx,nvp,&nvp1);
568        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
569        if(JSVAL_IS_OBJECT(nvp1j)){
570          tres->content=mapFromJSObject(cx,nvp1j);
571        }
572
[790]573        jsval nvp0=JSVAL_NULL;
574        JSObject *nvp01=JSVAL_TO_OBJECT(JSVAL_NULL);
575        if((JS_GetProperty(cx, nvp1, "child", &nvp0)==JS_FALSE)){
576#ifdef JS_DEBUG
577          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
578#endif
579        }
580        JS_ValueToObject(cx,nvp0,&nvp01);
581        jsval nvp01j=OBJECT_TO_JSVAL(nvp01);
582        if(!JSVAL_IS_NULL(nvp01j)){
583          tres->child=mapsFromJSObject(cx,nvp01j);
584        }
585
[333]586        if(res==NULL)
587          res=dupMaps(&tres);
588        else
589          addMapsToMaps(&res,tres);
590        freeMaps(&tres);
591        free(tres);
592        tres=NULL;
593      }
[471]594      JS_DestroyIdArray(cx,idp);
[333]595    }
596  }
597
[364]598  jsuint len;
[9]599  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
[383]600#ifdef JS_DEBUG
[9]601  if(hasLen==JS_FALSE){
[1]602    fprintf(stderr,"outputs array is empty\n");
603  }
604  fprintf(stderr,"outputs array length : %d\n",len);
605#endif
[640]606  for(oi=0;hasLen && oi < len;oi++){
[1]607#ifdef JS_DEBUG
[9]608    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
[1]609#endif
610    jsval tmp1;
[9]611    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
612    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
613    JSIdArray *idp=JS_Enumerate(cx,otmp1);
[1]614    if(idp!=NULL) {
615      int index;
616      jsdouble argNum;
617#ifdef JS_DEBUG
618      fprintf(stderr,"Properties length :  %d \n",idp->length);
619#endif
[274]620      tres=(maps*)malloc(MAPS_SIZE);
621      tres->name=NULL;
622      tres->content=NULL;
623      tres->next=NULL;
624
[1]625      for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]626        jsval id = idp->vector[index];
[1]627        jsval vp;
628        JS_IdToValue(cx,id,&vp);
[640]629        char *tmp;
[1]630        JSString *jsmsg;
631        size_t len1;
632        jsmsg = JS_ValueToString(cx,vp);
633        len1 = JS_GetStringLength(jsmsg);
[471]634        tmp=JS_EncodeString(cx,jsmsg);
[1]635#ifdef JS_DEBUG
[471]636        fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
[1]637#endif
[9]638        jsval nvp=JSVAL_NULL;
[471]639        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
[1]640#ifdef JS_DEBUG
[471]641          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
[1]642#endif
[274]643        }
[471]644        free(tmp);
[1]645        if(JSVAL_IS_OBJECT(nvp)){
646#ifdef JS_DEBUG
647          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
648#endif
649        }
[274]650
[364]651        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
[1]652        JS_ValueToObject(cx,nvp,&nvp1);
653        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
654        if(JSVAL_IS_OBJECT(nvp1j)){
[274]655          JSString *jsmsg1;
[471]656          char *tmp1, *tmp2;
[364]657          JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
[274]658          jsmsg1 = JS_ValueToString(cx,nvp1j);
659          len1 = JS_GetStringLength(jsmsg1);
[471]660          tmp1=JS_EncodeString(cx,jsmsg1);
661          tmp2=JS_EncodeString(cx,jsmsg);
[277]662#ifdef JS_DEBUG
[471]663          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
[277]664#endif
[471]665          if(strcasecmp(tmp1,"[object Object]")==0){
666            tres->name=zStrdup(tmp2);
[274]667            tres->content=mapFromJSObject(cx,nvp1j);
668          }
[1]669          else
[471]670            if(strcasecmp(tmp2,"name")==0){
671              tres->name=zStrdup(tmp1);
[274]672            }
673            else{
674              if(tres->content==NULL)
[471]675                tres->content=createMap(tmp2,tmp1);
[274]676              else
[471]677                addToMap(tres->content,tmp2,tmp1);
[274]678            }
[471]679          free(tmp1);
680          free(tmp2);
[1]681        }
682#ifdef JS_DEBUG
683        else
684          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
685#endif
686      }
[277]687#ifdef JS_DEBUG
[274]688      dumpMaps(tres);
[277]689#endif
[274]690      if(res==NULL)
691        res=dupMaps(&tres);
692      else
693        addMapsToMaps(&res,tres);
694      freeMaps(&tres);
695      free(tres);
696      tres=NULL;
[471]697      JS_DestroyIdArray(cx,idp);
[1]698    }
699  }
[277]700#ifdef JS_DEBUG
[1]701  dumpMaps(res);
[277]702#endif
[1]703  return res;
704}
705
[580]706/**
707 * Convert a JavaScript Object to a map
708 *
709 * @param cx the JavaScript context
710 * @param t the JavaScript Object to convert
711 * @return a new map containing the JavaScript Object
712 */
[1]713map* mapFromJSObject(JSContext *cx,jsval t){
714  map *res=NULL;
[9]715  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
[1]716#ifdef JS_DEBUG
717  fprintf(stderr,"Properties %p\n",(void*)t);
718#endif
719  if(idp!=NULL) {
720    int index;
721    jsdouble argNum;
722#ifdef JS_DEBUG
723    fprintf(stderr,"Properties length :  %d \n",idp->length);
724#endif
725    for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]726      jsval id = idp->vector[index];
[1]727      jsval vp;
728      JS_IdToValue(cx,id,&vp);
[640]729      char *tmp, *tmp1;
[1]730      JSString *jsmsg,*jsmsg1;
731      size_t len,len1;
732      jsmsg = JS_ValueToString(cx,vp);
733      len = JS_GetStringLength(jsmsg);
734      jsval nvp;
[471]735      tmp=JS_EncodeString(cx,jsmsg);
736      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
[1]737      jsmsg1 = JS_ValueToString(cx,nvp);
738      len1 = JS_GetStringLength(jsmsg1);
[471]739      tmp1=JS_EncodeString(cx,jsmsg1);
[1]740#ifdef JS_DEBUG
[471]741      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
[1]742#endif
[790]743      if(strcasecmp(tmp,"child")!=0){
744        if(res!=NULL){
[26]745#ifdef JS_DEBUG
[790]746          fprintf(stderr,"%s - %s\n",tmp,tmp1);
[26]747#endif
[790]748          addToMap(res,tmp,tmp1);
749        }
750        else{
751          res=createMap(tmp,tmp1);
752          res->next=NULL;
753        }
[9]754      }
[471]755      free(tmp);
756      free(tmp1);
[26]757#ifdef JS_DEBUG
[9]758      dumpMap(res);
[26]759#endif
[1]760    }
[471]761    JS_DestroyIdArray(cx,idp);
[1]762  }
763#ifdef JS_DEBUG
764  dumpMap(res);
765#endif
766  return res;
767}
768
[580]769/**
770 * Print debug information messages on stderr
771 *
772 * @param cx the JavaScript context
773 * @param message the error message
774 * @param report the JavaScript Error Report
775 */
[1]776void reportError(JSContext *cx, const char *message, JSErrorReport *report)
777{
778  sprintf(dbg,"%s:%u:%s\n",
779          report->filename ? report->filename : "<no filename>",
780          (unsigned int) report->lineno,
781          message);
782#ifdef JS_DEBUG
783  fprintf(stderr,"%s",dbg);
784#endif
785  fflush(stderr);
786}
787
[580]788/**
789 * Convert a JavaScript value to a char*
790 *
791 * @param context the JavaScript context
792 * @param arg the JavaScript value
793 * @return a new char*
[781]794 * @warning be sure to free the resources returned by this function
[580]795 */
[368]796char* JSValToChar(JSContext* context, jsval* arg) {
797  char *c;
798  char *tmp;
799  JSString *jsmsg;
800  size_t len;
801  int i;
802  if(!JSVAL_IS_STRING(*arg)) {
803    return NULL;
804  }
805  jsmsg = JS_ValueToString(context,*arg);
806  len = JS_GetStringLength(jsmsg);
807  tmp = JS_EncodeString(context,jsmsg);
808  c = (char*)malloc((len+1)*sizeof(char));
809  c[len] = '\0';
810#ifdef ULINET_DEBUG
811  fprintf(stderr,"%d \n",len);
812#endif
813  for(i = 0;i < len;i++) {
814    c[i] = tmp[i];
815    c[i+1] = 0;
816  }
817#ifdef ULINET_DEBUG
818  fprintf(stderr,"%s \n",c);
819#endif
820  return c;
821}
822
[580]823/**
824 * Set the HTTP header of a request
825 *
826 * @param handle the HINTERNET handle
827 * @param cx the JavaScript context
828 * @param header the JavaScript Array containing the headers to send
829 * @return the HINTERNET handle
830 */
[492]831HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
[368]832  jsuint length=0;
833  jsint i=0;
834  char *tmp1;
835#ifdef ULINET_DEBUG
836  fprintf(stderr,"setHeader\n");
837#endif
838  if(JS_IsArrayObject(cx,header)){
839#ifdef ULINET_DEBUG
840    fprintf(stderr,"header is an array\n");
841#endif
842    JS_GetArrayLength(cx,header,&length);
843#ifdef ULINET_DEBUG
844    fprintf(stderr,"header is an array of %d elements\n",length);
845#endif
[492]846    handle->ihandle[handle->nb].header=NULL;
[368]847    for(i=0;i<length;i++){
848      jsval tmp;
849      JS_GetElement(cx,header,i,&tmp);
850      tmp1=JSValToChar(cx,&tmp);
851#ifdef ULINET_DEBUG
[492]852      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
[368]853      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
854#endif
[492]855      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
[368]856      free(tmp1);
857    }
858  }
859  else{
860    fprintf(stderr,"not an array !!!!!!!\n");
861  }
[492]862  return *handle;
[368]863}
864
[580]865/**
866 * The function used as ZOOTranslate from the JavaScript environment.
867 * Use the ZOO-Services messages translation function from the Python
868 * environment (ZOO-API)
869 *
870 * @param cx the JavaScript context
871 * @param argc the number of parameters
872 * @param argv1 the parameter values
873 * @return true
874 */
[368]875JSBool
[377]876JSTranslate(JSContext *cx, uintN argc, jsval *argv1)
877{
878  jsval *argv = JS_ARGV(cx,argv1);
879  char *str=JSValToChar(cx,&argv[0]);
880  char *tmpValue=_ss(str);
881  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue)))); 
882  JS_MaybeGC(cx);
883  return JS_TRUE;
884}
885
[580]886/**
887 * The function used as ZOORequest from the JavaScript environment (ZOO-API)
888 *
889 * @param cx the JavaScript context
890 * @param argc the number of parameters
891 * @param argv1 the parameter values
892 * @return true
893 * @see setHeader
894 */
[377]895JSBool
[368]896JSRequest(JSContext *cx, uintN argc, jsval *argv1)
897{
898  jsval *argv = JS_ARGV(cx,argv1);
899  HINTERNET hInternet;
900  JSObject *header;
901  char *url;
902  char *method;
903  char* tmpValue;
904  size_t dwRead;
[917]905  maps *tmpConf=createMaps("main");
906  tmpConf->content=createMap("memory","load");
[368]907  JS_MaybeGC(cx);
908  hInternet=InternetOpen("ZooWPSClient\0",
909                         INTERNET_OPEN_TYPE_PRECONFIG,
910                         NULL,NULL, 0);
911  if(!CHECK_INET_HANDLE(hInternet))
912    return JS_FALSE;
913  if(argc>=2){
914    method=JSValToChar(cx,&argv[0]);
915    url=JSValToChar(cx,&argv[1]);
916  }
917  else{
[453]918    method=zStrdup("GET");
[368]919    url=JSValToChar(cx,argv);
920  }
[492]921  hInternet.waitingRequests[hInternet.nb]=strdup(url);
[368]922  if(argc==4){
923    char *body;
924    body=JSValToChar(cx,&argv[2]);
925    header=JSVAL_TO_OBJECT(argv[3]);
926#ifdef ULINET_DEBUG
927    fprintf(stderr,"URL (%s) \nBODY (%s)\n",url,body);
928#endif
929    if(JS_IsArrayObject(cx,header))
[492]930      setHeader(&hInternet,cx,header);
[368]931#ifdef ULINET_DEBUG
932    fprintf(stderr,"BODY (%s)\n",body);
933#endif
[492]934    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
[917]935                    INTERNET_FLAG_NO_CACHE_WRITE,0,tmpConf);   
[492]936    processDownloads(&hInternet);
[368]937    free(body);
938  }else{
939    if(argc==3){
[828]940      if(strncasecmp(method,"GET",3)==0){
941        header=JSVAL_TO_OBJECT(argv[2]);
942        if(JS_IsArrayObject(cx,header)){
943          setHeader(&hInternet,cx,header);
944        }
945        InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
[917]946                        INTERNET_FLAG_NO_CACHE_WRITE,0,tmpConf);
[828]947        processDownloads(&hInternet);
948      }else{
949        char *body=JSValToChar(cx,&argv[2]);
950        InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
[917]951                        INTERNET_FLAG_NO_CACHE_WRITE,0,tmpConf);
[828]952        processDownloads(&hInternet);
953        free(body);
954      }
[492]955    }else{
956      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
[917]957                      INTERNET_FLAG_NO_CACHE_WRITE,0,tmpConf);
[492]958      processDownloads(&hInternet);
[368]959    }
960  }
[492]961  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
962  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
[368]963#ifdef ULINET_DEBUG
964  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
965#endif
966  if(dwRead==0){
967    JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,"Unable to access the file.",strlen("Unable to access the file."))));
968    return JS_TRUE;
969  }
970
971#ifdef ULINET_DEBUG
972  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
973#endif
974  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));
975  free(url);
976  if(argc>=2)
977    free(method);
[917]978  freeMaps(&tmpConf);
979  free(tmpConf);
[492]980  InternetCloseHandle(&hInternet);
[368]981  JS_MaybeGC(cx);
982  return JS_TRUE;
983}
[580]984
985/**
986 * The function used as ZOOUpdateStatus from the JavaScript environment
987 * (ZOO-API).
988 *
989 * @param cx the JavaScript context
990 * @param argc the number of parameters
991 * @param argv1 the parameter values
992 * @return true
[581]993 * @see setHeader,_updateStatus
[580]994 */
995JSBool
996JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
997{
998  jsval *argv = JS_ARGV(cx,argv1);
999  JS_MaybeGC(cx);
1000  int istatus=0;
1001  char *status=NULL;
1002  maps *conf;
1003  if(argc>2){
1004#ifdef JS_DEBUG
1005    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
1006#endif
1007    return JS_FALSE;
1008  }
1009  conf=mapsFromJSObject(cx,argv[0]);
1010  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
1011    char tmpStatus[4];
1012    sprintf(tmpStatus,"%i",istatus);
1013    tmpStatus[3]=0;
1014    status=strdup(tmpStatus);
1015  }
1016  if(getMapFromMaps(conf,"lenv","status")!=NULL){
1017    if(status!=NULL){
1018      setMapInMaps(conf,"lenv","status",status);
1019      free(status);
1020    }
1021    else
1022      setMapInMaps(conf,"lenv","status","15");
1023    _updateStatus(conf);
1024  }
1025  freeMaps(&conf);
1026  free(conf);
1027  JS_MaybeGC(cx);
1028  return JS_TRUE;
1029}
1030
[917]1031/**
1032 * The function used as sleep from the JavaScript environment
1033 * (ZOO-API).
1034 *
1035 * @param cx the JavaScript context
1036 * @param argc the number of parameters
1037 * @param argv1 the parameter values
1038 * @return true
1039 */
1040JSBool
1041JSSleep(JSContext *cx, uintN argc, jsval *argv1)
1042{
1043  jsval *argv = JS_ARGV(cx,argv1);
1044  JS_MaybeGC(cx);
1045  int isleep=0;
1046  if(JS_ValueToInt32(cx,argv[0],&isleep)==JS_TRUE){
1047    zSleep(isleep);
1048  }
1049  JS_MaybeGC(cx);
1050  return JS_TRUE;
1051}
1052
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