SBjsiFuncs.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:19k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. /*****************************************************************************
  23.  *****************************************************************************
  24.  *
  25.  * Implementation of the SBjsi functions defined in SBjsiAPI.h,
  26.  * see that header for details. These implementations are just a thin
  27.  * C wrapper around the real implementation.
  28.  *
  29.  *****************************************************************************
  30.  ****************************************************************************/
  31. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  32. #include "SBjsiInternal.h"
  33. #include "SBjsiLog.h"                // For logging
  34. #include "JsiRuntime.hpp"            // For JsiRuntime class
  35. #include "JsiContext.hpp"            // For JsiContext class
  36. #include "SBjsiInterface.h"          // For SBjsiInterface
  37. #include "SBjsiAPI.h"                // Header for these functions
  38. #include <xercesc/dom/DOMDocument.hpp>
  39. // Real VXIjsiContext API object
  40. extern "C" {
  41. typedef struct VXIjsiContext
  42. {
  43.   // JavaScript context object
  44.   JsiContext *jsiContext;
  45. } VXIjsiContext;
  46. }
  47. // Convenience macro
  48. #define GET_SBJSI(pThis, context, rc) 
  49.   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS; 
  50.   SBjsiInterface *sbJsi = (SBjsiInterface *) pThis; 
  51.   if (( ! sbJsi ) || ( ! context )) { 
  52.     if ( sbJsi ) SBjsiLogger::Error(sbJsi->log, MODULE_SBJSI, 
  53.                                       JSI_ERROR_NULL_INTERFACE_PTR, NULL); 
  54.     rc = VXIjsi_RESULT_INVALID_ARGUMENT; 
  55.     return rc; 
  56.   }
  57. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  58. /**
  59.  * Return the version
  60.  */
  61. extern "C" 
  62. VXIint32 SBjsiGetVersion(void)
  63. {
  64.   return VXI_CURRENT_VERSION;
  65. }
  66. /**
  67.  * Return the implementation name
  68.  */
  69. extern "C" 
  70. const VXIchar* SBjsiGetImplementationName(void)
  71. {
  72.   return SBJSI_IMPLEMENTATION_NAME;
  73. }
  74. /**
  75.  * Create and initialize a new script context
  76.  *
  77.  * This creates a new environment using a model, usually the global
  78.  * environment created by VXIjsiInit(). Currently one context is
  79.  * created per thread, but the implementation must support the ability
  80.  * to have multiple contexts per thread.
  81.  *
  82.  * @param model    [IN]  Pointer to the model context that will be the
  83.  *                       basis for the new context, pass NULL to use the
  84.  *                       default environment
  85.  * @param context  [OUT] Newly created context
  86.  *
  87.  * @result VXIjsiResult 0 on success 
  88.  */
  89. extern "C"
  90. VXIjsiResult SBjsiCreateContext(VXIjsiInterface        *pThis,
  91. VXIjsiContext         **context)
  92. {
  93.   static const wchar_t func[] = L"SBjsiCreateContext";
  94.   GET_SBJSI(pThis, context, rc);
  95.   sbJsi->log->Diagnostic(sbJsi->log, sbJsi->diagTagBase + SBJSI_LOG_API,
  96.   func, L"entering: 0x%p", context);
  97.   // Allocate the wrapper object and the new context
  98.   *context = NULL;
  99.   VXIjsiContext *newContext = new VXIjsiContext;
  100.   if ( newContext == NULL ) {
  101.     SBjsiLogger::Error(sbJsi->log, MODULE_SBJSI, JSI_ERROR_OUT_OF_MEMORY,
  102.  NULL);
  103.     rc = VXIjsi_RESULT_OUT_OF_MEMORY;
  104.   } else if ( (newContext->jsiContext = new JsiContext) == NULL ) {
  105.     delete newContext;
  106.     SBjsiLogger::Error(sbJsi->log, MODULE_SBJSI, JSI_ERROR_OUT_OF_MEMORY,
  107.  NULL);
  108.     rc = VXIjsi_RESULT_OUT_OF_MEMORY;
  109.     sbJsi->log->Diagnostic(sbJsi->log, sbJsi->diagTagBase + SBJSI_LOG_API, 
  110.     func, L"exiting: returned %d", rc);
  111.     return rc;
  112.   }
  113.   // Now do the low-level creation
  114.   rc = newContext->jsiContext->Create(sbJsi->jsiRuntime, sbJsi->contextSize,
  115.        sbJsi->maxBranches, sbJsi->log,
  116.        sbJsi->diagTagBase);
  117.   if ( rc == VXIjsi_RESULT_SUCCESS ) {
  118.     *context = newContext;
  119.   } else {
  120.     delete newContext->jsiContext;
  121.     delete newContext;
  122.   }
  123.   sbJsi->log->Diagnostic(sbJsi->log, sbJsi->diagTagBase + SBJSI_LOG_API,
  124.   func, L"exiting: returned %d, 0x%p", rc, *context);
  125.   return rc;
  126. }
  127. /**
  128.  * Destroy a script context, clean up storage if required
  129.  *
  130.  * @param context  [IN] Context to destroy
  131.  *
  132.  * @result VXIjsiResult 0 on success
  133.  */
  134. extern "C"
  135. VXIjsiResult SBjsiDestroyContext(VXIjsiInterface        *pThis,
  136.  VXIjsiContext         **context)
  137. {
  138.   static const wchar_t func[] = L"SBjsiDestroyContext";
  139.   GET_SBJSI(pThis, context, rc);
  140.   sbJsi->log->Diagnostic(sbJsi->log, sbJsi->diagTagBase + SBJSI_LOG_API, 
  141.   func, L"entering: 0x%p (0x%p)", 
  142.   context, (context ? *context : NULL));
  143.   if ( *context == NULL ) {
  144.     SBjsiLogger::Error(sbJsi->log, MODULE_SBJSI, JSI_ERROR_INVALID_ARG,
  145.  NULL);
  146.     rc = VXIjsi_RESULT_INVALID_ARGUMENT;
  147.   } else {
  148.     delete (*context)->jsiContext;
  149.     delete *context;
  150.     *context = NULL;
  151.   }
  152.   sbJsi->log->Diagnostic(sbJsi->log, sbJsi->diagTagBase + SBJSI_LOG_API, func,
  153.   L"exiting: returned %d", rc);
  154.   return rc;
  155. }
  156. /**
  157.  * Create a script variable relative to the current scope, initialized
  158.  *  to an expression
  159.  *
  160.  * NOTE: When there is an expression, the expression is evaluated,
  161.  *  then the value of the evaluated expression (the final
  162.  *  sub-expression) assigned. Thus an expression of "1; 2;" actually
  163.  *  assigns 2 to the variable.
  164.  *
  165.  * @param context  [IN] JavaScript context to create the variable within
  166.  * @param name     [IN] Name of the variable to create
  167.  * @param expr     [IN] Expression to set the initial value of the variable 
  168.  *                      (if NULL or empty the variable is set to JavaScript 
  169.  *                      Undefined as required for VoiceXML 1.0 <var>)
  170.  *
  171.  * @result VXIjsiResult 0 on success 
  172.  */
  173. extern "C"
  174. VXIjsiResult SBjsiCreateVarExpr(VXIjsiInterface        *pThis,
  175. VXIjsiContext          *context, 
  176. const VXIchar          *name, 
  177. const VXIchar          *expr)
  178. {
  179.   static const wchar_t func[] = L"SBjsiCreateVarExpr";
  180.   GET_SBJSI(pThis, context, rc);
  181.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  182.      L"entering: 0x%p, '%s', '%s'", 
  183.      context, name, expr);
  184.   rc = context->jsiContext->CreateVar(name, expr);
  185.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  186.   return rc;
  187. }
  188.   
  189. /**
  190.  * Create a script variable relative to the current scope, initialized
  191.  *  to a VXIValue based value
  192.  *
  193.  * @param context  [IN] JavaScript context to create the variable within
  194.  * @param name     [IN] Name of the variable to create
  195.  * @param value    [IN] VXIValue based value to set the initial value of 
  196.  *                      the variable (if NULL the variable is set to 
  197.  *                      JavaScript Undefined as required for VoiceXML 1.0
  198.  *                      <var>). VXIMap is used to pass JavaScript objects.
  199.  *
  200.  * @result VXIjsiResult 0 on success 
  201.  */
  202. extern "C"
  203. VXIjsiResult SBjsiCreateVarValue(VXIjsiInterface        *pThis,
  204.  VXIjsiContext          *context, 
  205.  const VXIchar          *name, 
  206.  const VXIValue         *value)
  207. {
  208.   static const wchar_t func[] = L"SBjsiCreateVarValue";
  209.   GET_SBJSI(pThis, context, rc);
  210.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  211.      L"entering: 0x%p, '%s', 0x%p", 
  212.      context, name, value);
  213.   rc = context->jsiContext->CreateVar(name, value);
  214.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  215.   return rc;
  216. }
  217.   
  218. /**
  219.  * Set a script variable to an expression relative to the current scope
  220.  *
  221.  * NOTE: The expression is evaluated, then the value of the
  222.  *  evaluated expression (the final sub-expression) assigned. Thus
  223.  *  an expression of "1; 2;" actually assigns 2 to the variable.
  224.  *
  225.  * @param context  [IN] JavaScript context to set the variable within
  226.  * @param name     [IN] Name of the variable to set
  227.  * @param expr     [IN] Expression to be assigned
  228.  *
  229.  * @result VXIjsiResult 0 on success 
  230.  */
  231. extern "C"
  232. VXIjsiResult SBjsiSetVarExpr(VXIjsiInterface        *pThis,
  233.      VXIjsiContext          *context, 
  234.      const VXIchar          *name, 
  235.      const VXIchar          *expr)
  236. {
  237.   static const wchar_t func[] = L"SBjsiSetVarExpr";
  238.   GET_SBJSI(pThis, context, rc);
  239.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  240.      L"entering: 0x%p, '%s', '%s'", 
  241.      context, name, expr);
  242.   rc = context->jsiContext->SetVar(name, expr);
  243.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  244.   return rc;
  245. }
  246. /**
  247.  * Set a script variable to a DOMDocument relative to the current scope
  248.  *
  249.  * NOTE: The expression is evaluated, then the value of the
  250.  *  evaluated expression (the final sub-expression) assigned. Thus
  251.  *  an expression of "1; 2;" actually assigns 2 to the variable.
  252.  *
  253.  * @param context  [IN] JavaScript context to set the variable within
  254.  * @param name     [IN] Name of the variable to set
  255.  * @param doc      [IN] DOMDocument to be assigned
  256.  *
  257.  * @result VXIjsiResult 0 on success 
  258.  */
  259. extern "C"
  260. VXIjsiResult SBjsiCreateVarDOM(VXIjsiInterface        *pThis,
  261.      VXIjsiContext          *context, 
  262.      const VXIchar          *name, 
  263.  VXIPtr                 *doc )
  264. {
  265.   static const wchar_t func[] = L"SBjsiCreateVarDOM";
  266.   GET_SBJSI(pThis, context, rc);
  267.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  268.      L"entering: 0x%p, '%s'", 
  269.      context, name);
  270.   xercesc::DOMDocument *domdoc = reinterpret_cast<xercesc::DOMDocument *>(VXIPtrValue(doc));
  271.   rc = context->jsiContext->CreateVar(name, domdoc);
  272.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  273.   return rc;
  274. }
  275.   
  276. /**
  277.  * Set a script variable to a value relative to the current scope
  278.  *
  279.  * @param context  [IN] JavaScript context to set the variable within
  280.  * @param name     [IN] Name of the variable to set
  281.  * @param value    [IN] VXIValue based value to be assigned. VXIMap is 
  282.  *                      used to pass JavaScript objects.
  283.  *
  284.  * @result VXIjsiResult 0 on success 
  285.  */
  286. extern "C"
  287. VXIjsiResult SBjsiSetVarValue(VXIjsiInterface        *pThis,
  288.       VXIjsiContext          *context, 
  289.       const VXIchar          *name, 
  290.       const VXIValue         *value)
  291. {
  292.   static const wchar_t func[] = L"SBjsiSetVarValue";
  293.   GET_SBJSI(pThis, context, rc);
  294.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  295.      L"entering: 0x%p, '%s', 0x%p", 
  296.      context, name, value);
  297.   rc = context->jsiContext->SetVar(name, value);
  298.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  299.   return rc;
  300. }
  301. /**
  302.  * Get the value of a variable
  303.  *
  304.  * @param context  [IN]  JavaScript context to get the variable from
  305.  * @param name     [IN]  Name of the variable to get
  306.  * @param value    [OUT] Value of the variable, returned as the VXI
  307.  *                       type that most closely matches the variable's
  308.  *                       JavaScript type. This function allocates this
  309.  *                       for return on success (returns a NULL pointer
  310.  *                       otherwise), the caller is responsible for
  311.  *                       destroying it via VXIValueDestroy(). VXIMap
  312.  *                       is used to return JavaScript objects.
  313.  *
  314.  * @result VXIjsiResult 0 on success, VXIjsi_RESULT_FAILURE if the
  315.  *         variable has a JavaScript value of Null,
  316.  *         VXIjsi_RESULT_NON_FATAL_ERROR if the variable is not
  317.  *         defined (JavaScript Undefined), or another error code for
  318.  *         severe errors 
  319.  */
  320. extern "C"
  321. VXIjsiResult SBjsiGetVar(VXIjsiInterface         *pThis,
  322.  const VXIjsiContext     *context, 
  323.  const VXIchar           *name,
  324.  VXIValue               **value)
  325. {
  326.   static const wchar_t func[] = L"SBjsiGetVar";
  327.   GET_SBJSI(pThis, context, rc);
  328.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  329.      L"entering: 0x%p, '%s', 0x%p", 
  330.      context, name, value);
  331.   rc = context->jsiContext->GetVar(name, value);
  332.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  333.      L"exiting: returned %d, 0x%p (0x%p)",
  334.      rc, value, (value ? *value : NULL));
  335.   return rc;
  336. }
  337. /**
  338.  * Check whether a variable is defined (not JavaScript Undefined)
  339.  *
  340.  * NOTE: A variable with a JavaScript Null value is considered defined
  341.  *
  342.  * @param context  [IN]  JavaScript context to check the variable in
  343.  * @param name     [IN]  Name of the variable to check
  344.  *
  345.  * @result VXIjsiResult 0 on success (variable is defined),
  346.  *         VXIjsi_RESULT_FAILURE if the variable is not defined,
  347.  *         or another error code for severe errors
  348.  */
  349. extern "C"
  350. VXIjsiResult SBjsiCheckVar(VXIjsiInterface        *pThis,
  351.    const VXIjsiContext    *context, 
  352.    const VXIchar          *name)
  353. {
  354.   static const wchar_t func[] = L"SBjsiCheckVar";
  355.   GET_SBJSI(pThis, context, rc);
  356.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"entering: 0x%p, '%s'",
  357.      context, name);
  358.   rc = context->jsiContext->CheckVar(name);
  359.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  360.   return rc;
  361. }
  362. /**
  363.   * set a script variable read-only to the current scope
  364.   *  
  365.   * @param context  [IN] ECMAScript context in which the variable
  366.   *                      has been created
  367.   * @param name     [IN] Name of the variable to set as read only.
  368.   *
  369.   * @return VXIjsi_RESULT_SUCCESS on success
  370.   */
  371. extern "C"
  372. VXIjsiResult SBjsiSetReadOnly(struct VXIjsiInterface *pThis,
  373.                              VXIjsiContext    *context,
  374.                              const VXIchar          *name)
  375. {
  376.   static const wchar_t func[] = L"SBjsiSetReadOnly";
  377.   GET_SBJSI(pThis, context, rc);
  378.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"entering: 0x%p, '%s'",
  379.      context, name);
  380.   rc = context->jsiContext->SetReadOnly(name);
  381.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  382.   return rc;
  383. }                          
  384. /**
  385.  * Execute a script, optionally returning any execution result
  386.  *
  387.  * @param context  [IN]  JavaScript context to execute within
  388.  * @param expr     [IN]  Buffer containing the script text
  389.  * @param value    [OUT] Result of the script execution, returned 
  390.  *                       as the VXI type that most closely matches 
  391.  *                       the variable's JavaScript type. Pass NULL
  392.  *                       if the result is not desired. Otherwise
  393.  *                       this function allocates this for return on 
  394.  *                       success when there is a return value (returns 
  395.  *                       a NULL pointer otherwise), the caller is 
  396.  *                       responsible for destroying it via 
  397.  *                       VXIValueDestroy(). VXIMap is used to return 
  398.  *                       JavaScript objects.
  399.  *
  400.  * @result VXIjsiResult 0 on success
  401.  */
  402. extern "C"
  403. VXIjsiResult SBjsiEval(VXIjsiInterface         *pThis,
  404.        VXIjsiContext           *context,
  405.        const VXIchar           *expr,
  406.        VXIValue               **result)
  407. {
  408.   static const wchar_t func[] = L"SBjsiEval";
  409.   GET_SBJSI(pThis, context, rc);
  410.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  411.      L"entering: 0x%p, '%s', 0x%p", 
  412.      context, expr, result);
  413.   rc = context->jsiContext->Eval(expr, result);
  414.   context->jsiContext->Diag(SBJSI_LOG_API, func, 
  415.      L"exiting: returned %d, 0x%p (0x%p)", 
  416.      rc, result, (result ? *result : NULL));
  417.   return rc;
  418. }
  419. /**
  420.  * Push a new context onto the scope chain (add a nested scope)
  421.  * @param context  [IN] JavaScript context to push the scope onto
  422.  * @param name     [IN] Name of the scope, used to permit referencing
  423.  *                      variables from an explicit scope within the
  424.  *                      scope chain, such as "myscope.myvar" to access
  425.  *                      "myvar" within a scope named "myscope"
  426.  *
  427.  * @result VXIjsiResult 0 on success
  428.  */
  429. extern "C"
  430. VXIjsiResult SBjsiPushScope(VXIjsiInterface        *pThis,
  431.     VXIjsiContext          *context,
  432.     const VXIchar          *name,
  433.     const VXIjsiScopeAttr  attr)
  434. {
  435.   static const wchar_t func[] = L"SBjsiPushScope";
  436.   GET_SBJSI(pThis, context, rc);
  437.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"entering: 0x%p, '%s'",
  438.      context, name);
  439.   rc = context->jsiContext->PushScope(name, attr);
  440.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  441.   return rc;
  442. }
  443. /**
  444.  * Pop a context from the scope chain (remove a nested scope)
  445.  *
  446.  * @param context  [IN] JavaScript context to pop the scope from
  447.  *
  448.  * @result VXIjsiResult 0 on success
  449.  */
  450. extern "C"
  451. VXIjsiResult SBjsiPopScope(VXIjsiInterface        *pThis,
  452.    VXIjsiContext          *context)
  453. {
  454.   static const wchar_t func[] = L"SBjsiPopScope";
  455.   GET_SBJSI(pThis, context, rc);
  456.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"entering: 0x%p", context);
  457.   rc = context->jsiContext->PopScope();
  458.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  459.   return rc;
  460. }
  461. /**
  462.  * Reset the scope chain to the global scope (pop all nested scopes)
  463.  *
  464.  * @param context  [IN] JavaScript context to pop the scopes from
  465.  *
  466.  * @result VXIjsiResult 0 on success
  467.  */
  468. extern "C"
  469. VXIjsiResult SBjsiClearScopes(VXIjsiInterface        *pThis,
  470.       VXIjsiContext          *context)
  471. {
  472.   static const wchar_t func[] = L"SBjsiClearScopes";
  473.   GET_SBJSI(pThis, context, rc);
  474.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"entering: 0x%p", context);
  475.   rc = context->jsiContext->ClearScopes();
  476.   context->jsiContext->Diag(SBJSI_LOG_API, func, L"exiting: returned %d", rc);
  477.   return rc;
  478. }
  479. extern "C" const VXIMap *SBjsiGetLastError(VXIjsiInterface *pThis, VXIjsiContext *context)
  480. {
  481.   return context->jsiContext->GetLastException();
  482. }