WvStreams
utils.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * XPLC - Cross-Platform Lightweight Components
00004  * Copyright (C) 2000-2003, Pierre Phaneuf
00005  * Copyright (C) 2001, Stéphane Lajoie
00006  * Copyright (C) 2002-2004, Net Integration Technologies, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA
00022  *
00023  * As a special exception, you may use this file as part of a free
00024  * software library without restriction.  Specifically, if other files
00025  * instantiate templates or use macros or inline functions from this
00026  * file, or you compile this file and link it with other files to
00027  * produce an executable, this file does not by itself cause the
00028  * resulting executable to be covered by the GNU Lesser General Public
00029  * License.  This exception does not however invalidate any other
00030  * reasons why the executable file might be covered by the GNU Lesser
00031  * General Public License.
00032  */
00033 
00034 #ifndef __XPLC_UTILS_H__
00035 #define __XPLC_UTILS_H__
00036 
00037 #if defined(__GNUC__) && __GNUC__ > 3
00038 # pragma GCC system_header
00039 #endif
00040 
00046 #include <stddef.h>
00047 #include <xplc/core.h>
00048 #include <xplc/IWeakRef.h>
00049 
00053 struct UUID_Info {
00055   const UUID* iid;
00056   ptrdiff_t delta;
00058 };
00059 
00063 #define UUID_MAP_BEGIN(component) const UUID_Info component::xplc_iobject_uuids[] = {
00064 
00068 #define UUID_MAP_ENTRY(iface) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00069 
00075 #define UUID_MAP_ENTRY_2(iface, iface2) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface2*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00076 
00080 #define UUID_MAP_END { 0, 0 } };
00081 
00082 class WeakRef;
00083 
00087 struct IObjectImplInternal {
00091   unsigned int refcount;
00097   WeakRef* weakref;
00098   IObjectImplInternal(): refcount(1), weakref(0) {
00099   }
00103   IObject* getInterface(void* self, const UUID& uuid,
00104                         const UUID_Info* uuidlist);
00105 };
00106 
00107 #ifndef xplcdelete
00108 
00112 #define xplcdelete delete
00113 #endif
00114 
00123 #define IMPLEMENT_IOBJECT(component) \
00124 private: \
00125   IObjectImplInternal xplc_iobject_internal; \
00126   static const UUID_Info xplc_iobject_uuids[]; \
00127   typedef component ThisXPLCComponent; \
00128 public: \
00129   virtual unsigned int addRef() { \
00130     return ++xplc_iobject_internal.refcount; \
00131   } \
00132   virtual unsigned int release() { \
00133     if(--xplc_iobject_internal.refcount) \
00134       return xplc_iobject_internal.refcount; \
00135     /* protect against re-entering the destructor */ \
00136     xplc_iobject_internal.refcount = 1; \
00137     if(xplc_iobject_internal.weakref) { \
00138       xplc_iobject_internal.weakref->release(); \
00139       xplc_iobject_internal.weakref->object = 0; \
00140     } \
00141     xplcdelete this; \
00142     return 0; \
00143   } \
00144   virtual IObject* getInterface(const UUID& uuid) { \
00145     return xplc_iobject_internal.getInterface(this, uuid, xplc_iobject_uuids); \
00146   } \
00147   virtual IWeakRef* getWeakRef() { \
00148     if(!xplc_iobject_internal.weakref) \
00149       xplc_iobject_internal.weakref = new WeakRef(reinterpret_cast<IObject*>(reinterpret_cast<ptrdiff_t>(this) + xplc_iobject_uuids->delta)); \
00150     xplc_iobject_internal.weakref->addRef(); \
00151     return xplc_iobject_internal.weakref; \
00152   }
00153 
00158 class WeakRef: public IWeakRef {
00159   IMPLEMENT_IOBJECT(WeakRef);
00160 public:
00162   IObject* object;
00163   virtual IObject* getObject() {
00164     if(object)
00165       object->addRef();
00166 
00167     return object;
00168   }
00172   WeakRef(IObject* aObj):
00173     object(aObj) {
00174   }
00175 };
00176 
00183 template<class Interface>
00184 Interface* get(IObject* aObj) {
00185   if(!aObj)
00186     return 0;
00187 
00188   return static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00189 }
00190 
00197 template<class Interface>
00198 Interface* mutate(IObject* aObj) {
00199   Interface* rv;
00200 
00201   if(!aObj)
00202     return 0;
00203 
00204   rv = static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00205 
00206   aObj->release();
00207 
00208   return rv;
00209 }
00210 
00211 #endif /* __XPLC_UTILS_H__ */