]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/base.cpp
Fix mistakenly using Clang instead of GCC on older FreeBSD versions.
[user/henk/code/inspircd.git] / src / base.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2004-2006 Craig Edwards <craigedwards@brainbox.cc>
7  *   Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
8  *
9  * This file is part of InspIRCd.  InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include "inspircd.h"
24 #include "base.h"
25 #include <time.h>
26 #include <typeinfo>
27
28 classbase::classbase()
29 {
30         if (ServerInstance && ServerInstance->Logs)
31                 ServerInstance->Logs->Log("CULLLIST", DEBUG, "classbase::+ @%p", (void*)this);
32 }
33
34 CullResult classbase::cull()
35 {
36         if (ServerInstance && ServerInstance->Logs)
37                 ServerInstance->Logs->Log("CULLLIST", DEBUG, "classbase::-%s @%p",
38                         typeid(*this).name(), (void*)this);
39         return CullResult();
40 }
41
42 classbase::~classbase()
43 {
44         if (ServerInstance && ServerInstance->Logs)
45                 ServerInstance->Logs->Log("CULLLIST", DEBUG, "classbase::~ @%p", (void*)this);
46 }
47
48 CullResult::CullResult()
49 {
50 }
51
52 // This trick detects heap allocations of refcountbase objects
53 static void* last_heap = NULL;
54
55 void* refcountbase::operator new(size_t size)
56 {
57         last_heap = ::operator new(size);
58         return last_heap;
59 }
60
61 void refcountbase::operator delete(void* obj)
62 {
63         if (last_heap == obj)
64                 last_heap = NULL;
65         ::operator delete(obj);
66 }
67
68 refcountbase::refcountbase() : refcount(0)
69 {
70         if (this != last_heap)
71                 throw CoreException("Reference allocate on the stack!");
72 }
73
74 refcountbase::~refcountbase()
75 {
76         if (refcount && ServerInstance && ServerInstance->Logs)
77                 ServerInstance->Logs->Log("CULLLIST", DEBUG, "refcountbase::~ @%p with refcount %d",
78                         (void*)this, refcount);
79 }
80
81 usecountbase::~usecountbase()
82 {
83         if (usecount && ServerInstance && ServerInstance->Logs)
84                 ServerInstance->Logs->Log("CULLLIST", DEBUG, "usecountbase::~ @%p with refcount %d",
85                         (void*)this, usecount);
86 }
87
88 ServiceProvider::~ServiceProvider()
89 {
90 }
91
92 ExtensionItem::ExtensionItem(const std::string& Key, Module* mod) : ServiceProvider(mod, Key, SERVICE_METADATA)
93 {
94 }
95
96 ExtensionItem::~ExtensionItem()
97 {
98 }
99
100 void* ExtensionItem::get_raw(const Extensible* container) const
101 {
102         Extensible::ExtensibleStore::const_iterator i =
103                 container->extensions.find(const_cast<ExtensionItem*>(this));
104         if (i == container->extensions.end())
105                 return NULL;
106         return i->second;
107 }
108
109 void* ExtensionItem::set_raw(Extensible* container, void* value)
110 {
111         std::pair<Extensible::ExtensibleStore::iterator,bool> rv =
112                 container->extensions.insert(std::make_pair(this, value));
113         if (rv.second)
114         {
115                 return NULL;
116         }
117         else
118         {
119                 void* old = rv.first->second;
120                 rv.first->second = value;
121                 return old;
122         }
123 }
124
125 void* ExtensionItem::unset_raw(Extensible* container)
126 {
127         Extensible::ExtensibleStore::iterator i = container->extensions.find(this);
128         if (i == container->extensions.end())
129                 return NULL;
130         void* rv = i->second;
131         container->extensions.erase(i);
132         return rv;
133 }
134
135 bool ExtensionManager::Register(ExtensionItem* item)
136 {
137         return types.insert(std::make_pair(item->name, item)).second;
138 }
139
140 void ExtensionManager::BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list)
141 {
142         std::map<std::string, reference<ExtensionItem> >::iterator i = types.begin();
143         while (i != types.end())
144         {
145                 std::map<std::string, reference<ExtensionItem> >::iterator me = i++;
146                 ExtensionItem* item = me->second;
147                 if (item->creator == module)
148                 {
149                         list.push_back(item);
150                         types.erase(me);
151                 }
152         }
153 }
154
155 ExtensionItem* ExtensionManager::GetItem(const std::string& name)
156 {
157         std::map<std::string, reference<ExtensionItem> >::iterator i = types.find(name);
158         if (i == types.end())
159                 return NULL;
160         return i->second;
161 }
162
163 void Extensible::doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove)
164 {
165         for(std::vector<reference<ExtensionItem> >::const_iterator i = toRemove.begin(); i != toRemove.end(); ++i)
166         {
167                 ExtensionItem* item = *i;
168                 ExtensibleStore::iterator e = extensions.find(item);
169                 if (e != extensions.end())
170                 {
171                         item->free(e->second);
172                         extensions.erase(e);
173                 }
174         }
175 }
176
177 static struct DummyExtensionItem : LocalExtItem
178 {
179         DummyExtensionItem() : LocalExtItem("", NULL) {}
180         void free(void*) {}
181 } dummy;
182
183 Extensible::Extensible()
184 {
185         extensions[&dummy] = NULL;
186 }
187
188 CullResult Extensible::cull()
189 {
190         for(ExtensibleStore::iterator i = extensions.begin(); i != extensions.end(); ++i)
191         {
192                 i->first->free(i->second);
193         }
194         extensions.clear();
195         return classbase::cull();
196 }
197
198 Extensible::~Extensible()
199 {
200         if (!extensions.empty() && ServerInstance && ServerInstance->Logs)
201                 ServerInstance->Logs->Log("CULLLIST", DEBUG,
202                         "Extensible destructor called without cull @%p", (void*)this);
203 }
204
205 LocalExtItem::LocalExtItem(const std::string& Key, Module* mod) : ExtensionItem(Key, mod)
206 {
207 }
208
209 LocalExtItem::~LocalExtItem()
210 {
211 }
212
213 std::string LocalExtItem::serialize(SerializeFormat format, const Extensible* container, void* item) const
214 {
215         return "";
216 }
217
218 void LocalExtItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value)
219 {
220 }
221
222 LocalStringExt::LocalStringExt(const std::string& Key, Module* Owner)
223         : SimpleExtItem<std::string>(Key, Owner) { }
224
225 LocalStringExt::~LocalStringExt()
226 {
227 }
228
229 std::string LocalStringExt::serialize(SerializeFormat format, const Extensible* container, void* item) const
230 {
231         if (item && format == FORMAT_USER)
232                 return *static_cast<std::string*>(item);
233         return "";
234 }
235
236 LocalIntExt::LocalIntExt(const std::string& Key, Module* mod) : LocalExtItem(Key, mod)
237 {
238 }
239
240 LocalIntExt::~LocalIntExt()
241 {
242 }
243
244 std::string LocalIntExt::serialize(SerializeFormat format, const Extensible* container, void* item) const
245 {
246         if (format != FORMAT_USER)
247                 return "";
248         return ConvToStr(reinterpret_cast<intptr_t>(item));
249 }
250
251 intptr_t LocalIntExt::get(const Extensible* container) const
252 {
253         return reinterpret_cast<intptr_t>(get_raw(container));
254 }
255
256 intptr_t LocalIntExt::set(Extensible* container, intptr_t value)
257 {
258         if (value)
259                 return reinterpret_cast<intptr_t>(set_raw(container, reinterpret_cast<void*>(value)));
260         else
261                 return reinterpret_cast<intptr_t>(unset_raw(container));
262 }
263
264 void LocalIntExt::free(void*)
265 {
266 }
267
268 StringExtItem::StringExtItem(const std::string& Key, Module* mod) : ExtensionItem(Key, mod)
269 {
270 }
271
272 StringExtItem::~StringExtItem()
273 {
274 }
275
276 std::string* StringExtItem::get(const Extensible* container) const
277 {
278         return static_cast<std::string*>(get_raw(container));
279 }
280
281 std::string StringExtItem::serialize(SerializeFormat format, const Extensible* container, void* item) const
282 {
283         return item ? *static_cast<std::string*>(item) : "";
284 }
285
286 void StringExtItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value)
287 {
288         if (value.empty())
289                 unset(container);
290         else
291                 set(container, value);
292 }
293
294 void StringExtItem::set(Extensible* container, const std::string& value)
295 {
296         void* old = set_raw(container, new std::string(value));
297         delete static_cast<std::string*>(old);
298 }
299
300 void StringExtItem::unset(Extensible* container)
301 {
302         void* old = unset_raw(container);
303         delete static_cast<std::string*>(old);
304 }
305
306 void StringExtItem::free(void* item)
307 {
308         delete static_cast<std::string*>(item);
309 }
310
311 ModuleException::ModuleException(const std::string &message, Module* who)
312         : CoreException(message, who ? who->ModuleSourceFile : "A Module")
313 {
314 }
315