Back to index

lightning-sunbird  0.9+nobinonly
XPCDispInlines.h
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the IDispatch implementation for XPConnect.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * David Bradley.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00044 inline
00045 PRBool nsXPConnect::IsIDispatchEnabled() 
00046 {
00047     return XPCIDispatchExtension::IsEnabled();
00048 }
00049 
00050 //=============================================================================
00051 // XPCDispInterface::Member:ParamInfo inlines
00052 
00053 inline
00054 XPCDispInterface::Member::ParamInfo::ParamInfo(
00055     const ELEMDESC * paramInfo) : mParamInfo(paramInfo) 
00056 {
00057 }
00058 
00059 inline
00060 JSBool XPCDispInterface::Member::ParamInfo::InitializeOutputParam(
00061     void * varBuffer, VARIANT & var) const
00062 {
00063     var.vt = GetType() | VT_BYREF;
00064     var.byref = varBuffer;
00065     return JS_TRUE;
00066 }
00067 
00068 inline
00069 PRBool XPCDispInterface::Member::ParamInfo::IsFlagSet(
00070     unsigned short flag) const 
00071 {
00072     return mParamInfo->paramdesc.wParamFlags & flag ? PR_TRUE : PR_FALSE; 
00073 }
00074 
00075 inline
00076 PRBool XPCDispInterface::Member::ParamInfo::IsIn() const 
00077 {
00078     return IsFlagSet(PARAMFLAG_FIN) || mParamInfo->paramdesc.wParamFlags == 0;
00079 }
00080 
00081 inline
00082 PRBool XPCDispInterface::Member::ParamInfo::IsOut() const 
00083 {
00084     return IsFlagSet(PARAMFLAG_FOUT);
00085 }
00086 
00087 inline
00088 PRBool XPCDispInterface::Member::ParamInfo::IsOptional() const 
00089 {
00090     return IsFlagSet(PARAMFLAG_FOPT);
00091 }
00092 
00093 inline
00094 PRBool XPCDispInterface::Member::ParamInfo::IsRetVal() const 
00095 {
00096     return IsFlagSet(PARAMFLAG_FRETVAL);
00097 }
00098 
00099 // TODO: Handle VT_ARRAY as well
00100 inline
00101 VARTYPE XPCDispInterface::Member::ParamInfo::GetType() const 
00102 {
00103     return mParamInfo->tdesc.vt == VT_PTR ? mParamInfo->tdesc.lptdesc->vt : mParamInfo->tdesc.vt;
00104 }
00105 
00106 //=============================================================================
00107 // XPCDispInterface::Member inlines
00108 
00109 inline
00110 XPCDispInterface::Member::Member() : 
00111     mType(UNINITIALIZED), mFuncDesc(nsnull), mGetterFuncDesc(nsnull),
00112     mTypeInfo(nsnull)
00113 {
00114 }
00115 
00116 inline
00117 XPCDispInterface::Member::~Member() 
00118 {
00119     if(mTypeInfo)
00120     {
00121         // Test to see if we have a separate getter. If we only have a getter they can
00122         // be the same
00123         PRBool releaseGetter = mGetterFuncDesc != nsnull && mFuncDesc != mGetterFuncDesc;
00124         if(mFuncDesc) 
00125             mTypeInfo->ReleaseFuncDesc(mFuncDesc);
00126         if(releaseGetter)
00127             mTypeInfo->ReleaseFuncDesc(mGetterFuncDesc);
00128     }
00129 }
00130 
00131 inline
00132 void* XPCDispInterface::Member::operator new(size_t, Member* p)
00133 {
00134     return p;
00135 }
00136 
00137 inline
00138 void XPCDispInterface::Member::MakeGetter() 
00139 {
00140     NS_ASSERTION(!IsFunction(), "Can't be function and property"); 
00141     mType |= GET_PROPERTY; 
00142 }
00143 
00144 inline
00145 void XPCDispInterface::Member::MakeSetter() 
00146 { 
00147     NS_ASSERTION(!IsFunction(), "Can't be function and property"); 
00148     mType |= SET_PROPERTY; 
00149 }
00150 
00151 inline
00152 void XPCDispInterface::Member::ResetType() 
00153 {
00154     mType = UNINITIALIZED;
00155 }
00156 
00157 inline
00158 void XPCDispInterface::Member::SetFunction() 
00159 { 
00160     NS_ASSERTION(!IsProperty(), "Can't be function and property"); 
00161     mType = FUNCTION; 
00162 }
00163 
00164 inline
00165 PRBool XPCDispInterface::Member::IsFlagSet(unsigned short flag) const 
00166 {
00167     return mType & flag ? PR_TRUE : PR_FALSE; 
00168 }
00169 
00170 inline
00171 PRBool XPCDispInterface::Member::IsSetter() const
00172 {
00173     return IsFlagSet(SET_PROPERTY);
00174 }
00175 
00176 inline
00177 PRBool XPCDispInterface::Member::IsGetter() const
00178 {
00179     return IsFlagSet(GET_PROPERTY);
00180 }
00181 
00182 inline
00183 PRBool XPCDispInterface::Member::IsProperty() const
00184 {
00185     return IsSetter() || IsGetter(); 
00186 }
00187 
00188 inline
00189 PRBool XPCDispInterface::Member::IsFunction() const
00190 {
00191     return IsFlagSet(FUNCTION);
00192 }
00193 
00194 inline
00195 PRBool XPCDispInterface::Member::IsParameterizedSetter() const
00196 {
00197     return IsSetter() && GetParamCount() > 1;
00198 }
00199 
00200 inline
00201 PRBool XPCDispInterface::Member::IsParameterizedGetter() const
00202 {
00203     return IsGetter() && (GetParamCount(PR_TRUE) > 1 ||
00204         (GetParamCount(PR_TRUE) == 1 && !GetParamInfo(0, PR_TRUE).IsRetVal()));
00205 }
00206 
00207 inline
00208 PRBool XPCDispInterface::Member::IsParameterizedProperty() const
00209 {
00210     return IsParameterizedSetter() || IsParameterizedGetter();
00211 }
00212 
00213 inline
00214 jsval XPCDispInterface::Member::GetName() const
00215 {
00216     return mName;
00217 }
00218 
00219 inline
00220 void XPCDispInterface::Member::SetName(jsval name)
00221 {
00222     mName = name;
00223 }
00224 
00225 inline
00226 PRUint32 XPCDispInterface::Member::GetDispID() const
00227 {
00228     return mFuncDesc->memid;
00229 }
00230 
00231 inline
00232 PRUint32 XPCDispInterface::Member::GetParamCount(PRBool getter) const
00233 {
00234     return (getter && mGetterFuncDesc) ? mGetterFuncDesc->cParams : mFuncDesc->cParams;
00235 }
00236 
00237 inline
00238 XPCDispInterface::Member::ParamInfo XPCDispInterface::Member::GetParamInfo(PRUint32 index, PRBool getter) const
00239 {
00240     NS_ASSERTION(index < GetParamCount(getter), "Array bounds error");
00241     return ParamInfo(((getter && mGetterFuncDesc) ? mGetterFuncDesc->lprgelemdescParam : mFuncDesc->lprgelemdescParam) + index);
00242 }
00243 
00244 inline
00245 void XPCDispInterface::Member::SetTypeInfo(DISPID dispID, 
00246                                                 ITypeInfo* pTypeInfo, 
00247                                                 FUNCDESC* funcdesc)
00248 {
00249     mTypeInfo = pTypeInfo; 
00250     mFuncDesc = funcdesc;
00251 }
00252 
00253 inline
00254 void XPCDispInterface::Member::SetGetterFuncDesc(FUNCDESC* funcdesc)
00255 {
00256     mGetterFuncDesc = funcdesc;
00257 }
00258 
00259 inline
00260 PRUint16 XPCDispInterface::Member::GetParamType(PRUint32 index) const 
00261 {
00262     return mFuncDesc->lprgelemdescParam[index].paramdesc.wParamFlags; 
00263 }
00264 
00265 inline
00266 void XPCDispInterface::Member::SetMemID(DISPID memID)
00267 {
00268     mMemID = memID;
00269 }
00270 
00271 inline
00272 DISPID XPCDispInterface::Member::GetMemID() const
00273 {
00274     return mMemID;
00275 }
00276 
00277 //=============================================================================
00278 // XPCDispInterface::Allocator
00279 
00280 inline
00281 XPCDispInterface* XPCDispInterface::Allocator::Allocate()
00282 {
00283     return Valid() ? new (Count()) XPCDispInterface(mCX, mTypeInfo, mIDispatchMembers) : nsnull;
00284 }
00285 
00286 inline
00287 XPCDispInterface::Allocator::~Allocator()
00288 {
00289     delete [] mMemIDs;
00290 }
00291 
00292 PRBool XPCDispInterface::Allocator::Valid() const
00293 {
00294     return mMemIDs ? PR_TRUE : PR_FALSE;
00295 }
00296 
00297 //=============================================================================
00298 // XPCDispInterface inlines
00299 
00300 inline
00301 JSObject* XPCDispInterface::GetJSObject() const
00302 {
00303     return mJSObject;
00304 }
00305 
00306 inline
00307 void XPCDispInterface::SetJSObject(JSObject* jsobj) 
00308 {
00309     mJSObject = jsobj;
00310 }
00311 
00312 inline
00313 const XPCDispInterface::Member* XPCDispInterface::FindMember(jsval name) const
00314 {
00315     // Iterate backwards to save time
00316     const Member* member = mMembers + mMemberCount;
00317     while(member > mMembers)
00318     {
00319         --member;
00320         if(name == member->GetName())
00321         {
00322             return member;
00323         }
00324     }
00325     return nsnull;
00326 }
00327 
00328 
00329 inline
00330 const XPCDispInterface::Member& XPCDispInterface::GetMember(PRUint32 index)
00331 { 
00332     NS_ASSERTION(index < mMemberCount, "invalid index");
00333     return mMembers[index]; 
00334 }
00335 
00336 inline
00337 PRUint32 XPCDispInterface::GetMemberCount() const 
00338 {
00339     return mMemberCount;
00340 }
00341 
00342 inline
00343 void XPCDispInterface::operator delete(void * p) 
00344 {
00345     PR_Free(p);
00346 }
00347 
00348 inline
00349 XPCDispInterface::~XPCDispInterface()
00350 {
00351     // Cleanup our members, the first gets cleaned up by the destructor
00352     // We have to cleanup the rest manually. These members are allocated
00353     // as part of the XPCIDispInterface object at the end
00354     for(PRUint32 index = 1; index < GetMemberCount(); ++index)
00355     {
00356         mMembers[index].~Member();
00357     }
00358 }
00359 
00360 inline
00361 XPCDispInterface::XPCDispInterface(JSContext* cx, ITypeInfo * pTypeInfo,
00362                                    PRUint32 members) : mJSObject(nsnull)
00363 {
00364     InspectIDispatch(cx, pTypeInfo, members);
00365 }
00366 
00367 inline
00368 void * XPCDispInterface::operator new (size_t, PRUint32 members) 
00369 {
00370     // Must allow for the member in XPCDispInterface
00371     if(!members)
00372         members = 1;
00373     // Calculate the size needed for the base XPCDispInterface and its members
00374     return PR_Malloc(sizeof(XPCDispInterface) + sizeof(Member) * (members - 1));
00375 }
00376 
00377 //=============================================================================
00378 // XPCDispNameArray inlines
00379 
00380 inline
00381 XPCDispNameArray::XPCDispNameArray() : mCount(0), mNames(0) 
00382 {
00383 }
00384 
00385 inline
00386 XPCDispNameArray::~XPCDispNameArray() 
00387 { 
00388     delete [] mNames;
00389 }
00390 
00391 inline
00392 void XPCDispNameArray::SetSize(PRUint32 size) 
00393 {
00394     NS_ASSERTION(mCount == 0, "SetSize called more than once");
00395     mCount = size;
00396     mNames = (size ? new nsString[size] : 0);
00397 }
00398 
00399 inline
00400 PRUint32 XPCDispNameArray::GetSize() const 
00401 {
00402     return mCount;
00403 }
00404 
00405 inline
00406 void XPCDispNameArray::SetName(DISPID dispid, nsAString const & name) 
00407 {
00408     NS_ASSERTION(dispid <= (PRInt32)mCount, "Array bounds error in XPCDispNameArray::SetName");
00409     mNames[dispid - 1] = name;
00410 }
00411 
00412 inline
00413 const nsAString & XPCDispNameArray::GetName(DISPID dispid) const 
00414 {
00415     NS_ASSERTION(dispid <= (PRInt32)mCount, "Array bounds error in XPCDispNameArray::Get");
00416     if(dispid > 0)
00417         return mNames[dispid - 1];
00418     return sEmpty;
00419 }
00420 
00421 inline
00422 DISPID XPCDispNameArray::Find(const nsAString &target) const
00423 {
00424     for(PRUint32 index = 0; index < mCount; ++index) 
00425     {
00426         if(mNames[index].Equals(target)) 
00427             return NS_STATIC_CAST(DISPID, index + 1);
00428     }
00429     return 0; 
00430 }
00431 
00432 //=============================================================================
00433 // XPCDispIDArray inlines
00434 
00435 inline
00436 PRUint32 XPCDispIDArray::Length() const
00437 {
00438     return mIDArray.Count();
00439 }
00440 
00441 inline
00442 jsval XPCDispIDArray::Item(JSContext* cx, PRUint32 index) const
00443 {
00444     jsval val;
00445     if(!JS_IdToValue(cx, 
00446                      NS_REINTERPRET_CAST(jsid, 
00447                                          mIDArray.ElementAt(index)), &val))
00448         return JSVAL_NULL;
00449     return val;
00450 }
00451 
00452 inline
00453 void XPCDispIDArray::Unmark()
00454 {
00455     mMarked = JS_FALSE;
00456 }
00457 
00458 inline
00459 JSBool XPCDispIDArray::IsMarked() const
00460 {
00461     return mMarked;
00462 }
00463 
00464     // NOP. This is just here to make the AutoMarkingPtr code compile.
00465 inline
00466 void XPCDispIDArray::MarkBeforeJSFinalize(JSContext*) 
00467 {
00468 }
00469 
00470 //=============================================================================
00471 // XPCDispTypeInfo inlines
00472 
00473 inline
00474 FUNCDESC* XPCDispTypeInfo::FuncDescArray::Get(PRUint32 index) 
00475 {
00476     return NS_REINTERPRET_CAST(FUNCDESC*,mArray[index]);
00477 }
00478 
00479 inline
00480 void XPCDispTypeInfo::FuncDescArray::Release(FUNCDESC *) 
00481 {
00482 }
00483 
00484 inline
00485 PRUint32 XPCDispTypeInfo::FuncDescArray::Length() const 
00486 {
00487     return mArray.Count();
00488 }
00489 
00490 inline
00491 const nsAString & XPCDispTypeInfo::GetNameForDispID(DISPID dispID)
00492 {
00493     return mNameArray.GetName(dispID);
00494 }
00495 
00496 //=============================================================================
00497 // XPCDispJSPropertyInfo inlines
00498 
00499 inline
00500 PRBool XPCDispJSPropertyInfo::Valid() const 
00501 {
00502     return mPropertyType != INVALID;
00503 }
00504 
00505 inline
00506 PRUint32 XPCDispJSPropertyInfo::GetParamCount() const
00507 {
00508     return IsSetter() ? 1 : mParamCount;
00509 }
00510 
00511 inline
00512 PRUint32 XPCDispJSPropertyInfo::GetMemID() const
00513 {
00514     return mMemID;
00515 }
00516 
00517 inline
00518 INVOKEKIND XPCDispJSPropertyInfo::GetInvokeKind() const
00519 {
00520     return IsSetter() ? INVOKE_PROPERTYPUT : 
00521         (IsProperty() ? INVOKE_PROPERTYGET : INVOKE_FUNC); 
00522 }
00523 
00524 inline
00525 PRBool XPCDispJSPropertyInfo::IsProperty() const
00526 {
00527     return PropertyType() == PROPERTY || PropertyType() == READONLY_PROPERTY;
00528 }
00529 
00530 inline
00531 PRBool XPCDispJSPropertyInfo::IsReadOnly() const
00532 {
00533     return PropertyType()== READONLY_PROPERTY;
00534 }
00535 
00536 inline
00537 PRBool XPCDispJSPropertyInfo::IsSetter() const
00538 {
00539     return (mPropertyType & SETTER_MODE) != 0;
00540 }
00541 inline
00542 void XPCDispJSPropertyInfo::SetSetter()
00543 {
00544     mPropertyType |= SETTER_MODE;
00545 }
00546 
00547 inline
00548 const nsAString & XPCDispJSPropertyInfo::GetName() const
00549 {
00550     return mName; 
00551 }
00552 
00553 inline
00554 XPCDispJSPropertyInfo::property_type XPCDispJSPropertyInfo::PropertyType() const
00555 {
00556     return NS_STATIC_CAST(property_type,mPropertyType & ~SETTER_MODE);
00557 }
00558 
00559 //=============================================================================
00560 // GUID/nsIID/nsCID conversion functions
00561 
00562 inline
00563 const nsIID & XPCDispIID2nsIID(const IID & iid)
00564 {
00565     NS_ASSERTION(sizeof(IID) == sizeof(nsIID), "IID is not the same size as nsIID");
00566     return NS_REINTERPRET_CAST(const nsIID &,iid);
00567 }
00568 
00569 inline
00570 const IID & XPCDispIID2IID(const nsIID & iid)
00571 {
00572     NS_ASSERTION(sizeof(IID) == sizeof(nsIID), "IID is not the same size as nsIID");
00573     return NS_REINTERPRET_CAST(const IID &, iid);
00574 }
00575 
00576 inline
00577 const nsCID & XPCDispCLSID2nsCID(const CLSID & clsid)
00578 {
00579     NS_ASSERTION(sizeof(CLSID) == sizeof(nsCID), "CLSID is not the same size as nsCID");
00580     return NS_REINTERPRET_CAST(const nsCID &,clsid);
00581 }
00582 
00583 inline
00584 const CLSID & XPCDispnsCID2CLSID(const nsCID & clsid)
00585 {
00586     NS_ASSERTION(sizeof(CLSID) == sizeof(nsCID), "CLSID is not the same size as nsCID");
00587     return NS_REINTERPRET_CAST(const CLSID &, clsid);
00588 }
00589 
00590 //=============================================================================
00591 // XPCDispParams inlines
00592 
00593 inline
00594 void XPCDispParams::SetNamedPropID()
00595 {
00596     mDispParams.rgdispidNamedArgs = &mPropID; 
00597     mDispParams.cNamedArgs = 1; 
00598 }
00599 
00600 inline
00601 VARIANT & XPCDispParams::GetParamRef(PRUint32 index)
00602 {
00603     NS_ASSERTION(index < mDispParams.cArgs, "XPCDispParams::GetParam bounds error");
00604     return mDispParams.rgvarg[mDispParams.cArgs - index - 1];
00605 }
00606 
00607 inline
00608 _variant_t XPCDispParams::GetParam(PRUint32 index) const
00609 {
00610     return NS_CONST_CAST(XPCDispParams*,this)->GetParamRef(index);
00611 }
00612 
00613 inline
00614 void * XPCDispParams::GetOutputBuffer(PRUint32 index)
00615 {
00616     NS_ASSERTION(index < mDispParams.cArgs, "XPCDispParams::GetParam bounds error");
00617     return mRefBuffer + sizeof(VARIANT) * index;
00618 }
00619 
00620 //=============================================================================
00621 // XPCDispParamPropJSClass inlines
00622 inline
00623 JSBool XPCDispParamPropJSClass::Invoke(XPCCallContext& ccx, 
00624                                        XPCDispObject::CallMode mode,
00625                                        jsval* retval)
00626 {
00627     return XPCDispObject::Dispatch(ccx, mDispObj, mDispID, mode, mDispParams,
00628                                    retval);
00629 }
00630 
00631 //=============================================================================
00632 // Other helper functions
00633 
00640 inline
00641 jschar * xpc_JSString2String(JSContext * cx, jsval val, PRUint32 * len = 0)
00642 {
00643     JSString* str = JSVAL_IS_STRING(val) ? JSVAL_TO_STRING(val) : 
00644                                            JS_ValueToString(cx, val);
00645     if(str)
00646     {
00647         if(len)
00648             *len = JS_GetStringLength(str);
00649         return JS_GetStringChars(str);
00650     }
00651     if(len)
00652         *len = 0;
00653     return nsnull;
00654 }
00655 
00663 inline
00664 PRUnichar* xpc_JSString2PRUnichar(XPCCallContext& ccx, jsval val,
00665                                   size_t* length = nsnull)
00666 {
00667     JSString* str = JS_ValueToString(ccx, val);
00668     if(!str)
00669         return nsnull;
00670     if(length)
00671         *length = JS_GetStringLength(str);
00672     return NS_REINTERPRET_CAST(PRUnichar*,JS_GetStringChars(str));
00673 }
00674