WvStreams
|
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__ */