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

Last change on this file since 619 was 586, checked in by djay, 10 years ago

Add the PHP ZOO-API, fix issue if ZTS is not defined, correct loading of the PHP script depending of the ZOO-Kernel location, use a ZEND_HANDLE_FD rather than the ZEND_HANDLE_FP used before, correct location of the hello.php service.

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