Back to index

lightning-sunbird  0.9+nobinonly
SupportsMixin.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1998
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either of the GNU General Public License Version 2 or later (the "GPL"),
00025  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038        SupportsMixin.cpp
00039        
00040        Experimental way to implement nsISupports interface.
00041        
00042        by Patrick C. Beard.
00043  */
00044 
00045 #include "SupportsMixin.h"
00046 #include "nsAgg.h"
00047 
00048 // Standard nsISupport method implementations.
00049 
00050 #ifdef SUPPORT_AGGREGATION
00051 
00052 SupportsMixin::SupportsMixin(void* instance, const InterfaceInfo interfaces[], UInt32 interfaceCount, nsISupports* outer)
00053        : mInstance(instance), mRefCount(0), mInterfaces(interfaces), mInterfaceCount(interfaceCount), mOuter(outer)
00054 {
00055        if (mOuter != NULL)
00056               mInner = new Inner(this);
00057 }
00058 
00059 SupportsMixin::~SupportsMixin()
00060 {
00061        if (mRefCount > 0) {
00062               ::DebugStr("\pmRefCount > 0!");
00063        }
00064        if (mInner != NULL)
00065               delete mInner;
00066 }
00067 
00072 nsresult SupportsMixin::OuterQueryInterface(const nsIID& aIID, void** aInstancePtr)
00073 {
00074        // first, see if we really implement this interface.
00075        nsresult result = queryInterface(aIID, aInstancePtr);
00076        // if not, then delegate to the outer object, if any.
00077        if (result != NS_OK && mOuter != NULL)
00078               return mOuter->QueryInterface(aIID, aInstancePtr);
00079        else
00080               return result;
00081 }
00082 
00083 nsrefcnt SupportsMixin::OuterAddRef()
00084 {
00085        nsrefcnt result = addRef();
00086        if (mOuter != NULL)
00087               return mOuter->AddRef();
00088        return result;
00089 }
00090 
00091 nsrefcnt SupportsMixin::OuterRelease()
00092 {
00093        if (mOuter != NULL) {
00094               nsIOuter* outer = NULL;
00095               nsISupports* supports = mOuter;
00096               static NS_DEFINE_IID(kIOuterIID, NS_IOUTER_IID);
00097               if (mRefCount == 1 && supports->QueryInterface(kIOuterIID, &outer) == NS_OK) {
00098                      outer->ReleaseInner(mInner);
00099                      outer->Release();
00100               } else
00101                      release();
00102               return supports->Release();
00103        } else {
00104               return release();
00105        }
00106 }
00107 
00108 #else /* !SUPPORT_AGGREGATION */
00109 
00110 SupportsMixin::SupportsMixin(void* instance, const InterfaceInfo interfaces[], UInt32 interfaceCount, nsISupports* /* outer */)
00111        : mInstance(instance), mRefCount(0), mInterfaces(interfaces), mInterfaceCount(interfaceCount)
00112 {
00113 }
00114 
00115 SupportsMixin::~SupportsMixin()
00116 {
00117        if (mRefCount > 0) {
00118               ::DebugStr("\pmRefCount > 0!");
00119        }
00120 }
00121 
00122 #endif /* !SUPPORT_AGGREGATION */
00123 
00129 NS_IMETHODIMP SupportsMixin::queryInterface(const nsIID& aIID, void** aInstancePtr)
00130 {
00131        if (aInstancePtr == NULL) {
00132               return NS_ERROR_NULL_POINTER;
00133        }
00134        // first check to see if it's one of our known interfaces.
00135        // need to solve the non-left inheritance graph case.
00136        const InterfaceInfo* interfaces = mInterfaces;
00137        UInt32 count = mInterfaceCount;
00138        for (UInt32 i = 0; i < count; i++) {
00139               if (aIID.Equals(interfaces[i].mIID)) {
00140                      *aInstancePtr = (void*) (UInt32(mInstance) + interfaces[i].mOffset);
00141                      addRef();
00142                      return NS_OK;
00143               }
00144        }
00145        // finally, does the interface match nsISupports?
00146        static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00147        if (aIID.Equals(kISupportsIID)) {
00148               *aInstancePtr = (void*) mInstance;
00149               addRef();
00150               return NS_OK;
00151        }
00152        return NS_NOINTERFACE;
00153 }
00154 
00155 NS_IMETHODIMP_(nsrefcnt) SupportsMixin::addRef()
00156 {
00157        return ++mRefCount;
00158 }
00159 
00160 NS_IMETHODIMP_(nsrefcnt) SupportsMixin::release()
00161 {
00162        if (--mRefCount == 0) {
00163               delete this;
00164               return 0;
00165        }
00166        return mRefCount;
00167 }