Back to index

lightning-sunbird  0.9+nobinonly
SupportsMixin.h
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.h
00039        
00040        Experimental way to implement nsISupports interface.
00041        
00042        Uses table-driven approach for fast lookup.
00043        
00044        Aggregation support isn't quite here yet, it requires a helper object that is referenced only by the outer object,
00045        whose QueryInterace, AddRef, and Release act only locally (i.e. they call queryInterface, addRef, and release).
00046        However, if we're not using aggregation (hardly ever are) it seems wasteful to define the helper object.
00047        
00048        by Patrick C. Beard.
00049  */
00050 
00051 #pragma once
00052 
00053 #include "nsISupports.h"
00054 
00055 // #define SUPPORT_AGGREGATION
00056 
00057 struct InterfaceInfo {
00058        nsID mIID;                  // the IID of this interface.
00059        UInt32 mOffset;             // the offset of this interface.
00060 };
00061 
00062 class SupportsMixin {
00063 public:
00064        // These act locally on the current object, and are meant to be called by sub-classes.
00065        nsresult queryInterface(const nsIID& aIID, void** aInstancePtr);
00066        nsrefcnt addRef(void);
00067        nsrefcnt release(void);
00068 
00069 protected:
00070        SupportsMixin(void* instance, const InterfaceInfo interfaces[], UInt32 interfaceCount, nsISupports* outer = NULL);
00071        virtual ~SupportsMixin();
00072 
00073 #ifdef SUPPORT_AGGREGATION
00074        NS_METHOD OuterQueryInterface(REFNSIID aIID, void** aInstancePtr);
00075        NS_METHOD_(nsrefcnt) OuterAddRef(void);
00076        NS_METHOD_(nsrefcnt) OuterRelease(void);
00077 #endif
00078 
00079 private:
00080        void* mInstance;
00081        nsrefcnt mRefCount;
00082        const InterfaceInfo* mInterfaces;
00083        UInt32 mInterfaceCount;
00084 
00085 #ifdef SUPPORT_AGGREGATION
00086        nsISupports* mOuter;
00087        
00088        class Inner : public nsISupports {
00089        public:
00090               NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) { return mSupports->queryInterface(aIID, aInstancePtr); }
00091               NS_IMETHOD_(nsrefcnt) AddRef(void) { return mSupports->addRef(); }
00092               NS_IMETHOD_(nsrefcnt) Release(void) { return mSupports->release(); }
00093               
00094               Inner(SupportsMixin* supports) : mSupports(supports) {}
00095               
00096        private:
00097               SupportsMixin* mSupports;
00098        };
00099 
00100        Inner* mInner;
00101 #endif
00102 };
00103 
00104 #ifdef SUPPORT_AGGREGATION
00105 
00106 #define DECL_SUPPORTS_MIXIN \
00107        NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) { return OuterQueryInterface(aIID, aInstancePtr); } \
00108        NS_IMETHOD_(nsrefcnt) AddRef(void) { return OuterAddRef(); } \
00109        NS_IMETHOD_(nsrefcnt) Release(void) { return OuterRelease(); }
00110 
00111 #else
00112 
00113 #define DECL_SUPPORTS_MIXIN \
00114        NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) { return queryInterface(aIID, aInstancePtr); } \
00115        NS_IMETHOD_(nsrefcnt) AddRef(void) { return addRef(); } \
00116        NS_IMETHOD_(nsrefcnt) Release(void) { return release(); }
00117 
00118 #endif
00119 
00120 #define INTERFACE_OFFSET(leafType, interfaceType) \
00121        UInt32((interfaceType*) ((leafType*)0))