diff options
author | Joachim Lingner <jl@openoffice.org> | 2000-10-17 08:12:07 +0000 |
---|---|---|
committer | Joachim Lingner <jl@openoffice.org> | 2000-10-17 08:12:07 +0000 |
commit | c5c6f770a0fbdb47e4efa317316f05288f085fda (patch) | |
tree | d34778ff3aceb4aa6680c6db680f69fd8fca232d /extensions/source/ole | |
parent | 9c87d6e2c89850f10b8f7e020eabd222e9334df3 (diff) |
function name convertVARIANTARGS changed to convertDispparamsArgs, return type of convertDispparamsArgs is now HRESULT rather than sal_Bool, convertDispparamsArgs uses XInvocation2 now to aquire type information
Diffstat (limited to 'extensions/source/ole')
-rw-r--r-- | extensions/source/ole/unoobjw.cxx | 245 |
1 files changed, 112 insertions, 133 deletions
diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx index 34047c90daa2..12ebead9cb5d 100644 --- a/extensions/source/ole/unoobjw.cxx +++ b/extensions/source/ole/unoobjw.cxx @@ -2,9 +2,9 @@ * * $RCSfile: unoobjw.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: jl $ $Date: 2000-10-12 13:09:12 $ + * last change: $Author: jl $ $Date: 2000-10-17 09:12:07 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -99,8 +99,10 @@ #ifndef _COM_SUN_STAR_CONTAINER_NOSUCHELEMENTEXCEPTION_HPP_ #include <com/sun/star/container/NoSuchElementException.hpp> #endif -#include <com/sun/star/beans/XMaterialHolder.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> +#include <com/sun/star/script/XInvocation2.hpp> +#include <com/sun/star/script/MemberType.hpp> #ifndef _TYPELIB_TYPEDESCRIPTION_H_ #include <uno/typedescription.h> @@ -353,14 +355,15 @@ STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID riid, return ret; } -// "convertVARIANTARGS" converts VARIANTS to their respecting Any counterparts -// As parameter it uses some of the parameters passed to IDispatch::Invoke. These -// ar "id", "wFlags" and "pdispparams". The function handles special JavaScript -// cases where a VARIANT of type VT_DISPATCH is ambiguous and can represent -// an object, array ( JavaScript Array object), out ( Array) and in/out ( Array) +// "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts +// The parameters "id", "wFlags" and "pdispparams" equal those as used in +// IDispatch::Invoke. The function handles special JavaScript +// cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent +// an object, array ( JavaScript Array object), out ( JavaScript Array object) and in/out +// (JavaScript Array object) // parameter. Because all those VT_DISPATCH objects need a different conversion // we have to find out what the object is supposed to be. The function does this -// by either using type information or by help of specialized JavaScript object. +// by either using type information or by help of a specialized JavaScript object. // A. Type Information // ----------------------------------------------------------------------------- @@ -379,7 +382,7 @@ STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID riid, // objects used within a JScript script. To obtain an instance one has to call // "_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl). // A value object is appropriately initialized within the script and passed as -// parameter to an UNO object method or property. The convertVARIANTARGS function +// parameter to an UNO object method or property. The convertDispparamsArgs function // can easily find out that a param is such an object by queriing for the // IJScriptValue interface. By this interface one the type and kind ( out, in/out) // can be determined and the right conversion can be applied. @@ -393,26 +396,29 @@ STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID riid, // out Parameter in Visual Basic have the type VT_BYREF | VT_VARIANT and if the bridge // is used from C++ than the type is usually VT_BYREF |VT_xxx. Those parameter are converted // and we don't go to the trouble of aquiring type information. -sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams, Sequence<Any>& rSeq) +HRESULT InterfaceOleWrapper_Impl::convertDispparamsArgs( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams, Sequence<Any>& rSeq) { - HRESULT hr; - if( pdispparams->cArgs == 0) - return TRUE; - sal_Bool convOk = TRUE; + HRESULT hr= S_OK; + sal_Int32 countArgs= pdispparams->cArgs; + if( countArgs == 0) + return S_OK; + sal_Bool convOk = sal_True; - // iterate over all parameter and check for special JScript value objects that originated in this bridge. - // Those can be converted straight away. The index in the sequence "seqConvertedParams" matches the index in the - // DISPPARAMS.rgvarg array. If the value is true then the corresponding VARIANT has been converted - // and the any has been written to the Sequence that holds the converted values. - Sequence< sal_Bool > seqConvertedParams( pdispparams->cArgs); - rSeq.realloc( pdispparams->cArgs); + // If a parameter is a JScript Value Object then it is being converted + // by convertValueObject function and the result is stored in this Sequence. + Sequence< sal_Bool > seqConvertedParams( countArgs); + rSeq.realloc( countArgs); Any* pParams = rSeq.getArray(); sal_Bool allDispHandled= sal_True; Any anyParam; sal_Bool bHandled= sal_False; - for( int i= 0; i < pdispparams->cArgs; i++) + // iterate over all parameter and check for special JScript value objects that originated in this bridge. + // Those can be converted straight away. The index in the sequence "seqConvertedParams" matches the index in the + // DISPPARAMS.rgvarg array. If the value is true then the corresponding VARIANT has been converted + // and the any has been written to the Sequence that holds the converted values. + for( int i= 0; i < countArgs; i++) { if( sal_False == convertValueObject( &pdispparams->rgvarg[i], anyParam, bHandled) ) { @@ -421,7 +427,7 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor } else if( bHandled) {// a param is a JScriptValue and could be converted - pParams[pdispparams->cArgs - i - 1]= anyParam; + pParams[countArgs - i - 1]= anyParam; seqConvertedParams[i]= sal_True; continue; }// also take care of VBasic ( VT_BYREF) @@ -430,107 +436,77 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor } if( ! convOk) - return sal_False; + return DISP_E_BADVARTYPE; // ---------------------- - // If there is a VT_DISPATCH and it is no JScriptValue object then + // If there is a VT_DISPATCH and if it is no JScriptValue object then // we need to know if it represents a Sequence, out or in/out parameter // or an actual object. Therefore we obtain type information try{ - Sequence<ParamMode> seqParamMode; sal_Bool bTypesAvailable= sal_False; - Sequence< Type > seqParamTypes; - sal_Bool bIsMethod= sal_False; + InvocationInfo info; //only aquire type information if at least one of the parameter is IDispatch - // and has not been convert yet because it is no JScriptValue object + // and has not been converted yet because it is no JScriptValue object if( ! allDispHandled) { - if( !m_xInvocation.is() )return FALSE; - Reference<XIntrospectionAccess> xIntroAccess= m_xInvocation->getIntrospection(); - if( !xIntroAccess.is()) return FALSE; - - // We need the name of the property or method to get its type description - // The name can be identified through the param "id" - // that is kept als value in the map m_nameToDispIdMap. - // Proplem: the Windows JScript engine sometimes changes small letters to capital - // letters as happens in xidlclass_obj.createObject( var) // in JScript. - // IDispatch::GetIdsOfNames is then called with "CreateObject" !!! - // m_nameToDispIdMap can contain several names for one DISPID but only one is - // the exact one. If there's no m_xExactName and therfore no exact name then - // there's only one entry in the map. - typedef NameToIdMap::const_iterator cit; - OUString sMemberName; - if( m_xExactName.is()) + if( !m_xInvocation.is() )return DISP_E_EXCEPTION; + Reference<XInvocation2> inv2( m_xInvocation, UNO_QUERY); + if( inv2.is()) { + + // We need the name of the property or method to get its type information. + // The name can be identified through the param "id" + // that is kept als value in the map m_nameToDispIdMap. + // Proplem: the Windows JScript engine sometimes changes small letters to capital + // letters as happens in xidlclass_obj.createObject( var) // in JScript. + // IDispatch::GetIdsOfNames is then called with "CreateObject" !!! + // m_nameToDispIdMap can contain several names for one DISPID but only one is + // the exact one. If there's no m_xExactName and therfore no exact name then + // there's only one entry in the map. + typedef NameToIdMap::const_iterator cit; + OUString sMemberName; + for(cit ci1= m_nameToDispIdMap.begin(); ci1 != m_nameToDispIdMap.end(); ci1++) { if( (*ci1).second == id) // iterator is a pair< OUString, DISPID> { sMemberName= (*ci1).first; - sMemberName= m_xExactName->getExactName( sMemberName); break; } } - } - else // the first match is certainly the only - { - for(cit ci1= m_nameToDispIdMap.begin(); ci1 != m_nameToDispIdMap.end(); ci1++) + + // Get information for the current call ( property or method). + // There could be similar names which only differ in the cases + // of letters. First we assume that the name which was passed into + // GetIDsOfNames is correct. If we won't get information with that + // name then we have the invocation service use the XExactName interface. + sal_Bool validInfo= sal_True; + try{ + info= inv2->getInfoForName( sMemberName, sal_False); + } + catch( IllegalArgumentException ) { - if( (*ci1).second == id) // iterator is a pair< OUString, DISPID> - { - sMemberName= (*ci1).first; - break; - } + validInfo= sal_False; } - } - if( sMemberName == L"") - return FALSE; - // Get the type description of the uno method or property - // Problem: In some cases DISPATCH_METHOD AND!!! DISPATCH_PROPERTYPUT or - // DISPATCH_PROPERTYGET can be set. That might - // be due to VBScript or JScript that can't differ what's what or it doesnt matter - // For that reaseon we can't use the wFlags param in Invoke - // The automation wrapper (this class (InterfaceOleWrapper_Impl) doesn't provide - // any type information currently. - try{ - // throws // NoSuchMethodException - Reference< XIdlMethod > spTypeMethod= xIntroAccess->getMethod( sMemberName, MethodConcept::ALL); - // ---------------- - Sequence< ParamInfo > seqInfos= spTypeMethod->getParameterInfos(); - Sequence< Reference< XIdlClass > > seqParamClasses= spTypeMethod->getParameterTypes(); - int count= min( seqParamClasses.getLength(), seqConvertedParams.getLength()); - - seqParamTypes.realloc( count); - seqParamMode.realloc( count); - // -------------------- - for( int i= 0; i < count ; i++) + if( ! validInfo) { - seqParamTypes[i]= Type( seqParamClasses[count - 1 - i]->getTypeClass(), - seqParamClasses[count - 1 - i]->getName()); - - seqParamMode[i]= seqInfos[ count - 1 -i].aMode; + info= inv2->getInfoForName( sMemberName, sal_True); } - bTypesAvailable= sal_True; - bIsMethod= sal_True; - }catch(...) {} - if( ! bTypesAvailable) - { - try{ - // throws NoSuchElementException - Property aProperty= xIntroAccess->getProperty( sMemberName, PropertyConcept::ATTRIBUTES); - seqParamTypes.realloc(1); - seqParamTypes[0]= aProperty.Type; - bTypesAvailable= sal_True; - }catch(...) {} + // If the current call is being dispatched to a method, + // make sure that the number of arguments in DISPPARAMS::cArgs is equal + // to the one in InvocationInfo::aParamTypes.getLength(); + if( info.eMemberType == MemberType_METHOD && + countArgs != info.aParamTypes.getLength() ) + hr= DISP_E_BADPARAMCOUNT; + + bTypesAvailable= sal_True; } - if( ! bTypesAvailable) - return FALSE; } - // used within the for loop. If the param is a IDispatch and the reqired parameter + // Used within the following "for" loop. If the param is a IDispatch and the reqired parameter // is an in/out parameter, then this uno wrapper is likely used in JScript. Then we // extract Array[0] and put the value into varParam. At the end of the loop varParam // is converted if it contains a value otherwise the VARIANT from @@ -541,7 +517,7 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor // by convertValueObject ( see above ). If a parameter is converted or is can be infered // from the Sequence seqConvertedParams. Its values relate to the VARIANT params in DISPPARAMS // at the same index. - for (int i = 0; convOk && (i < pdispparams->cArgs); i++) + for (int i = 0; convOk && (i < countArgs); i++) { if( seqConvertedParams[i] == sal_True) continue; @@ -552,7 +528,8 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor // from JScript like an Array used for Squences and out-params if( pdispparams->rgvarg[i].vt == VT_DISPATCH ) { - if( bIsMethod && seqParamMode[i] == ParamMode_INOUT) + + if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ] == ParamMode_INOUT) { // An INOUT-param in JSCript must be VT_DISPATCH since JScript Array objects are used // for OUT-params. Index ( property) "0" contains the actual IN-param. @@ -569,14 +546,16 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor if( FAILED( hr)) { varParam.Clear(); - convOk= FALSE; break; + convOk= sal_False; break; + hr= DISP_E_EXCEPTION; + break; } } - else if( bIsMethod && seqParamMode[i] == ParamMode_OUT) + else if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ] == ParamMode_OUT) { // No conversion necessary. The VT_DISPATCH represents // an Array in which the outparam is written on index 0 - bDoConversion= FALSE; + bDoConversion= sal_False; } } if( bDoConversion) @@ -585,37 +564,35 @@ sal_Bool InterfaceOleWrapper_Impl::convertVARIANTARGS( DISPID id, unsigned shor varParam= pdispparams->rgvarg[i]; Any theParam; - if( bTypesAvailable) + if( bTypesAvailable && info.eMemberType == MemberType_METHOD) convOk= variantToAny2( & varParam,theParam, - seqParamTypes[i]); + info.aParamTypes[ countArgs - i - 1]); + else if( bTypesAvailable && info.eMemberType == MemberType_PROPERTY) + convOk= variantToAny2( & varParam,theParam, info.aType); + else convOk = variantToAny( & varParam, theParam); if( convOk) - pParams[pdispparams->cArgs - (i + 1)]= theParam; + pParams[countArgs - (i + 1)]= theParam; } }// end for / iterating over all parameters - }catch(NoSuchMethodException e) - { - e; - convOk= FALSE; - }catch(RuntimeException e) + }catch( IllegalArgumentException ) // XInvocation2::getInfoForName { - e; - convOk= FALSE; - }catch( NoSuchElementException e) - { - e; - convOk= FALSE; + hr= DISP_E_BADVARTYPE; } catch(...) { - convOk= FALSE; + hr= DISP_E_EXCEPTION; } - return convOk; + + if( SUCCEEDED( hr) && convOk == sal_False) + hr= DISP_E_EXCEPTION; + + return hr; } // XBridgeSupplier2 --------------------------------------------------- @@ -955,7 +932,8 @@ STDMETHODIMP InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember, else { Sequence<Any> params; - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams , params )) + + if( SUCCEEDED(ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams , params ) )) { ret= doInvoke( pdispparams, pvarResult, pexcepinfo, puArgErr, d.name, params ); @@ -976,7 +954,8 @@ STDMETHODIMP InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember, else { Sequence<Any> params; - if (convertVARIANTARGS(dispidMember, wFlags, pdispparams, params ) && (params.getLength() > 0)) + ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params ); + if( SUCCEEDED( ret) && (params.getLength() > 0)) { ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, d.name, params); } @@ -1047,10 +1026,9 @@ HRESULT InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS * pdispparams, VARIANT * // ret = NOERROR; // } } - catch(IllegalArgumentException e) + catch(IllegalArgumentException ) { - e; - ret = ResultFromScode(DISP_E_TYPEMISMATCH); + ret = DISP_E_TYPEMISMATCH; } catch(CannotConvertException e) { @@ -1349,7 +1327,8 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri { // DISPID called for the first time if( wFlags == DISPATCH_METHOD ) { - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + + if( SUCCEEDED(ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params ))) { if( FAILED( ret= doInvoke( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params)) @@ -1372,14 +1351,14 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri if( SUCCEEDED( ret ) ) info.flags= DISPATCH_METHOD; - } // end if ( convertVARIANTARGS ) - else // convertVARIANTARGS failed + } // end if ( convertDispparamsArgs ) + else // convertDispparamsArgs failed ret= DISP_E_BADVARTYPE; } //if( wFlags == DISPATCH_METHOD ) else if( wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_PROPERTYPUTREF) { - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + if( SUCCEEDED( ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params ))) { if( FAILED( ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params)) @@ -1401,7 +1380,7 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri } if( SUCCEEDED( ret ) ) info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET; - } // end if ( convertVARIANTARGS ) + } // end if ( convertDispparamsArgs ) else ret= DISP_E_BADVARTYPE; @@ -1436,7 +1415,7 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri OUString exactName; // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + if( SUCCEEDED( ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params )) ) {// try first as method if( FAILED( ret= doInvoke( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params)) @@ -1476,14 +1455,14 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri if( SUCCEEDED( ret ) ) info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET; } - } // end if ( convertVARIANTARGS ) + } // end if ( convertDispparamsArgs ) else ret= DISP_E_BADVARTYPE; } else if( wFlags & DISPATCH_METHOD && wFlags & DISPATCH_PROPERTYGET) { OUString exactName; - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + if( SUCCEEDED(ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params )) ) { if( FAILED( ret= doInvoke( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params)) @@ -1505,7 +1484,7 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri if( SUCCEEDED( ret ) ) info.flags= DISPATCH_METHOD; - } // end if ( convertVARIANTARGS ) + } // end if ( convertDispparamsArgs ) else ret= DISP_E_BADVARTYPE; @@ -1541,7 +1520,7 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri { if( wFlags & DISPATCH_METHOD && info.flags == DISPATCH_METHOD) { - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + if( SUCCEEDED(ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params )) ) { ret= doInvoke( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params); @@ -1552,7 +1531,7 @@ STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID ri else if( (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF ) && info.flags & DISPATCH_PROPERTYPUT) { - if( convertVARIANTARGS(dispidMember, wFlags, pdispparams, params )) + if( SUCCEEDED( ret= convertDispparamsArgs(dispidMember, wFlags, pdispparams, params )) ) { ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, info.name, params); |