You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by sn...@apache.org on 2002/09/11 23:21:24 UTC

cvs commit: xml-soap/java/src/org/apache/soap/providers/com COMProvider.dll RPCProvider.cpp RPCProvider.h

snichol     2002/09/11 14:21:24

  Modified:    java/src/org/apache/soap/providers/com COMProvider.dll
                        RPCProvider.cpp RPCProvider.h
  Log:
  Avoid use of ws2mbs macro when handling strings.  That macro makes a copy
  of the string on the stack, which is a problem for long strings.
  
  Revision  Changes    Path
  1.5       +18 -9     xml-soap/java/src/org/apache/soap/providers/com/COMProvider.dll
  
  	<<Binary file>>
  
  
  1.4       +129 -30   xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.cpp
  
  Index: RPCProvider.cpp
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RPCProvider.cpp	16 Aug 2002 19:17:38 -0000	1.3
  +++ RPCProvider.cpp	11 Sep 2002 21:21:23 -0000	1.4
  @@ -74,12 +74,11 @@
   
   using namespace std;
   
  -
  -
   HRESULT   variant2object (JNIEnv *jenv, const VARIANT &var,  jobject &ret, bool *localRefCreated= NULL);
   
   wchar_t ModuleName[MAX_PATH *2 ]={0};
   HANDLE thisModule;
  +
   BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID fImpLoad)
   {
     if(fdwReason == DLL_PROCESS_ATTACH)
  @@ -133,6 +132,9 @@
   const short LOG_ERROR = 1;
   short eventLevel= LOG_ERROR;
   
  +/*
  + *  Undoes an action when exiting scope.
  + */
   struct Undoit
   {
    void (__stdcall*coinit )(void);
  @@ -147,14 +149,23 @@
    }
   };
   
  +/*
  + *  The actual provider.
  + */
   class COMProvider
   {
     jobject jPP;  //the java pluggable provider
     JNIEnv *env;
     static const char* javaClass;
     public:
  +  /*
  +   * Constructor that initializes member variables.
  +   */
     COMProvider(JNIEnv *e, jobject jthis):jPP(jthis),env(e){};
  -
  +  /*
  +   * Gets the dispatch type to handle property get/set as
  +   * well as straight method calls.
  +   */
     WORD getMethodDispatchType( const wchar_t *mname)
     {
       WORD ret = DISPATCH_METHOD;
  @@ -162,13 +173,21 @@
       else if(0 == wcsncmp(L"set_", mname, 4)) ret= DISPATCH_PROPERTYPUT;
       return ret;
     }
  -
  +  /*
  +   * Invokes a method on a COM object, translating parameters and results
  +   * between Java types and COM types.
  +   */
     jobject invoke (jstring jthreadingModel, jstring jprogid, jstring jmethodName, jbyteArray parms_in)
     {
      eventlog(LOG_SUCCESS, msgCalledDLL, ModuleName );
      wchar_t progid[256];
      Undoit undoit;
      ZeroIt(undoit);
  +   //
  +   // Get a local copy of parameters.  The Java code for the
  +   // provider has already munged the Java parameters into the
  +   // byte array (which is really a VARIANT array) we use here.
  +   //
      jsize noParmsBytes= NULL == parms_in ? 0 : env->GetArrayLength( parms_in);
      unsigned noParms= noParmsBytes/ sizeof VARIANT;
      eventlog(LOG_SUCCESS, msgNoParms, noParms );
  @@ -195,6 +214,9 @@
        dumpVariant(vp[i]);
      }
      */
  +   //
  +   // Initialize COM
  +   //
      DWORD coInit= COINIT_MULTITHREADED; //The default.
      bool oleInit= false;
      jboolean isCopy;
  @@ -236,7 +258,9 @@
        }
        undoit.coinit= CoUninitialize; //Ensure we uninitialize.
      }
  -
  +   //
  +   // Get the method name
  +   //
      cstr= (wchar_t *)env->GetStringChars(jmethodName, &isCopy);
      wchar_t *methodName= _wcsdup(cstr);
      if(isCopy == JNI_TRUE) env->ReleaseStringChars(jmethodName, cstr);
  @@ -246,7 +270,9 @@
          throwSoapException( msgFailedMemory);
          return NULL;
      }
  -
  +   //
  +   // Get the CLSID
  +   //
      CLSID clsid;
      cstr= (wchar_t*) env->GetStringChars(jprogid, &isCopy);
      if( L'{' == cstr[0]) //clsid is specified as a string
  @@ -278,8 +304,9 @@
      wcsncpy(progid, cstr, (sizeof(progid)/(sizeof progid[0]))-1);
      if(isCopy == JNI_TRUE) env->ReleaseStringChars(jprogid, cstr);
   
  -   //Start doing COM stuff
  -
  +   //
  +   // Create an instance of the COM object
  +   //
      hr= CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IDispatch, (void **)&undoit.idisp  );
   
      if (ASSERT_FAILED(hr))
  @@ -289,8 +316,9 @@
        if(methodName) free(methodName);
        return NULL;
      }
  -
  -
  +   //
  +   // Get the dispatch id of the method
  +   //
      DISPID dispid;
      ZeroIt(dispid);
      bool isSet= false;
  @@ -308,7 +336,9 @@
        if(methodName) free(methodName);
        return NULL;
      }
  -
  +   //
  +   // Initialize the parameter info
  +   //
      DISPPARAMS dispparams;
      ZeroIt( dispparams);
      dispparams.rgvarg= undoit.vp;
  @@ -319,15 +349,19 @@
        dispparams.cNamedArgs=  1 ;
        dispparams.rgdispidNamedArgs= &didpp;
      }
  +   //
  +   // Invoke the COM method
  +   //
      VARIANT result;
      ZeroIt(result);
      EXCEPINFO expInfo;
      ZeroIt( expInfo);
      unsigned  parg;
      ZeroIt( parg);
  -
      hr= undoit.idisp->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), getMethodDispatchType(methodName), &dispparams, &result, &expInfo, &parg);
  -
  +   //
  +   // Translate COM errors or exceptions to Java
  +   //
      if(hr == DISP_E_EXCEPTION )
      {
        unsigned long err= (unsigned long) expInfo.wCode;
  @@ -352,6 +386,9 @@
        if(methodName) free(methodName);
        return NULL;
      }
  +   //
  +   // Convert the result to a variant
  +   //
      jobject jresult= NULL;
   
      hr= variant2object (env, result, jresult);
  @@ -369,30 +406,47 @@
      ::VariantClear(&result);
      return jresult;
     }
  -  //Throw a Java SOAP Exception.
  +  /*
  +   * Throws a SOAP exception for a UNICODE string.
  +   */
     BOOL throwSoapException( const wchar_t *msg)
     {
       if(NULL== msg) msg= L"Exception thrown by COMProvider";
  -    jstring jmsg= env->NewStringUTF(ws2mbs(msg));
  +//    jstring jmsg= env->NewStringUTF(ws2mbs(msg));
  +    jstring jmsg= env->NewString(msg, wcslen(msg));
       jclass jcASE= env->FindClass(javaClass);
       jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
       jthrowable jt= (jthrowable) env->CallStaticObjectMethod(jcASE,mid, jmsg);
       env->Throw(jt);
       return true;
     }
  -
  +  /*
  +   * Throws a SOAP exception for a string.
  +   */
  +  BOOL throwSoapException( const char *msg)
  +  {
  +    if(NULL== msg) msg= "Exception thrown by COMProvider";
  +    jstring jmsg= env->NewStringUTF(msg);
  +    jclass jcASE= env->FindClass(javaClass);
  +    jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
  +    jthrowable jt= (jthrowable) env->CallStaticObjectMethod(jcASE,mid, jmsg);
  +    env->Throw(jt);
  +    return true;
  +  }
  +  /*
  +   * Throws a SOAP exception for a Win32 message id.
  +   */
     BOOL throwSoapException( int id, ...)
     {
  -
       va_list a;
       va_start( a, id);
       wchar_t *msgbuf= NULL;
       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_STRING ,
         (wchar_t *)id, 0, 3, (wchar_t *) &msgbuf, 10000, &a);
   
  -
       if(NULL== msgbuf || *msgbuf == L'\0') msgbuf= L"Exception thrown by COMProvider";
  -    jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
  +//    jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
  +    jstring jmsg= env->NewString(msgbuf, wcslen(msgbuf));
       LocalFree( msgbuf );
       jclass jcASE= env->FindClass(javaClass);
       jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
  @@ -400,12 +454,13 @@
       env->Throw(jt);
       env->DeleteLocalRef(jmsg);
   
  -   return true;
  +    return true;
     }
  -
  +  /*
  +   * Logs an event
  +   */
     BOOL eventlog(short eventtype,  int id, ...)
     {
  -
      if( (eventtype & eventLevel) == 0 ) return false;
      va_list a;
      va_start( a, id);
  @@ -415,7 +470,8 @@
   
      // fwprintf( stderr,  L"%s\n", msgbuf);
      jclass  spClass= env->GetObjectClass(jPP);
  -   jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
  +//   jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
  +   jstring jmsg= env->NewString(msgbuf, wcslen(msgbuf));
      jmethodID mid= env->GetMethodID(spClass, "logit", "(ILjava/lang/String;)V");
      env->CallVoidMethod(jPP, mid, (jint)eventtype, jmsg);
      env->DeleteLocalRef(jmsg);
  @@ -424,11 +480,21 @@
      return true;
     }
   };//class COMProvider
  - const char* COMProvider::javaClass= "org/apache/soap/providers/com/RPCProvider";
   
  +/*
  + *  Native methods
  + */
  +const char* COMProvider::javaClass= "org/apache/soap/providers/com/RPCProvider";
  +
  +/*
  + * org.apache.soap.providers.com.RPCProvider#invoke
  + *
  + * Invokes the COM method as the SOAP service.
  + */
   extern "C" JNIEXPORT jobject JNICALL Java_org_apache_soap_providers_com_RPCProvider_invoke
     (JNIEnv *env, jobject jo, jstring threadingModel, jstring jprogid, jstring jmethodName, jbyteArray parms_in)
   {
  + // Instantiate a COMProvider (see above) and call its invoke member function.
    CRTDBGBRK
    COMProvider cp(env, jo);
   #ifdef NDEBUG  //This also will to debug on demand so if we are debugging don't do the catch.
  @@ -439,6 +505,25 @@
    return cp.invoke(threadingModel, jprogid, jmethodName,  parms_in);
   #ifdef NDEBUG
    }
  + catch(wchar_t *wstr)
  + {
  +   env->ExceptionClear(); //Ignore all previous errors.
  +   cp.throwSoapException(wstr);
  +   return NULL;
  + }
  + catch(char *str)
  + {
  +   env->ExceptionClear(); //Ignore all previous errors.
  +   cp.throwSoapException(str);
  +   return NULL;
  + }
  + catch(unsigned int ui)
  + {
  +   env->ExceptionClear(); //Ignore all previous errors.
  +   wchar_t numbuf[16];
  +   cp.throwSoapException(_ultow(ui, numbuf, 10));
  +   return NULL;
  + }
    catch( ... )
    { //Main point here is not to trap the JVM!
      env->ExceptionClear(); //Ignore all previous errors.
  @@ -447,10 +532,20 @@
    }
   #endif
   }
  +/*
  + * org.apache.soap.providers.com.RPCProvider#initlog
  + *
  + * Sets the logging level.
  + */
   extern "C" JNIEXPORT void JNICALL Java_org_apache_soap_providers_com_RPCProvider_initlog(JNIEnv *env, jclass jc, jshort jlvl)
   {
    eventLevel= jlvl;
   }
  +/*
  + * org.apache.soap.providers.com.RPCProvider#nativeConvertToBString
  + *
  + * Converts a Java string to a BSTR.
  + */
   extern "C" JNIEXPORT jbyteArray JNICALL Java_org_apache_soap_providers_com_RPCProvider_nativeConvertToBString(JNIEnv *env, jclass jc, jstring s)
   {
    env->ExceptionClear(); //Let a calling thread to invoke a call record the error.
  @@ -466,8 +561,9 @@
    return jByteArray;
   }
   
  -/* make objects from primitives */
  -
  +/*
  + * Functions to create a Java Object from primitive types.
  + */
   jobject bsf_makeBoolean (JNIEnv *jenv, int val) {
     jclass classobj = jenv->FindClass ( "java/lang/Boolean");
     jmethodID constructor =
  @@ -486,8 +582,7 @@
     jclass classobj = jenv->FindClass ( "java/lang/Short");
     jmethodID constructor =
       jenv->GetMethodID ( classobj, "<init>", "(S)V");
  -  return jenv->NewObject ( classobj, constructor, (jshort) val);
  -}
  +  return jenv->NewObject ( classobj, constructor, (jshort) val);
}
   
   jobject bsf_makeInteger (JNIEnv *jenv, int val) {
     jclass classobj = jenv->FindClass ( "java/lang/Integer");
  @@ -517,6 +612,9 @@
     return jenv->NewObject ( classobj, constructor, (jdouble) val);
   }
   
  +/*
  + * Create a Java Object from VARIANT types.
  + */
   HRESULT variant2object (JNIEnv *jenv, const VARIANT &var, jobject &jresult,  bool *localRefCreated)
   {
    HRESULT result = S_OK;
  @@ -550,8 +648,9 @@
     break;
    case VT_BSTR:
     /* if its a string with the right stuff, retract the object */
  -  buf= ws2mbs(var.bstrVal);
  -  jresult = jenv->NewStringUTF (buf);
  +//  buf= ws2mbs(var.bstrVal);
  +//  jresult = jenv->NewStringUTF (buf);
  +  jresult = jenv->NewString(var.bstrVal, wcslen(var.bstrVal));
     break;
    case VT_BOOL:
     jresult = bsf_makeBoolean (jenv, (int) V_BOOL (&var));
  
  
  
  1.2       +2 -0      xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.h
  
  Index: RPCProvider.h
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RPCProvider.h	14 Mar 2001 19:39:56 -0000	1.1
  +++ RPCProvider.h	11 Sep 2002 21:21:23 -0000	1.2
  @@ -127,6 +127,8 @@
    return (char *) d;
   }
   
  +// TODO: this requires sufficient stack for a copy of the string,
  +// which may simply not be available.
   #define ws2mbs(s) (ws2mbsConvert((s),  _alloca( ((2+(wcslen((const wchar_t *)(s))<<1))))))
   
   template<class T> inline void ZeroIt(T &t){  memset(&t, 0, sizeof t);};
  
  
  

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>