]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/extensible.h
Send * for empty targets in the no such nick/channel message.
[user/henk/code/inspircd.git] / include / extensible.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #pragma once
21
22 /** DEPRECATED: use {To,From}{Human,Internal,Network} instead. */
23 enum SerializeFormat
24 {
25         FORMAT_USER,
26         FORMAT_INTERNAL,
27         FORMAT_NETWORK,
28         FORMAT_PERSIST
29 };
30
31 /** Base class for logic that extends an Extensible object. */
32 class CoreExport ExtensionItem : public ServiceProvider, public usecountbase
33 {
34  public:
35         /** Types of Extensible that an ExtensionItem can apply to. */
36         enum ExtensibleType
37         {
38                 /** The ExtensionItem applies to a User object. */
39                 EXT_USER,
40
41                 /** The ExtensionItem applies to a Channel object. */
42                 EXT_CHANNEL,
43
44                 /** The ExtensionItem applies to a Membership object. */
45                 EXT_MEMBERSHIP
46         };
47
48         /** The type of Extensible that this ExtensionItem applies to. */
49         const ExtensibleType type;
50
51         /** Initializes an instance of the ExtensionItem class.
52          * @param key The name of the extension item (e.g. ssl_cert).
53          * @param exttype The type of Extensible that this ExtensionItem applies to.
54          * @param owner The module which created this ExtensionItem 
55          */
56         ExtensionItem(const std::string& key, ExtensibleType exttype, Module* owner);
57
58         /** Destroys an instance of the ExtensionItem class. */
59         virtual ~ExtensionItem();
60
61         /** Sets an ExtensionItem using a value in the internal format.
62          * @param container A container the ExtensionItem should be set on.
63          * @param value A value in the internal format.
64          */
65         virtual void FromInternal(Extensible* container, const std::string& value);
66
67         /** Sets an ExtensionItem using a value in the network format.
68          * @param container A container the ExtensionItem should be set on.
69          * @param value A value in the network format.
70          */
71         virtual void FromNetwork(Extensible* container, const std::string& value);
72
73         /** Gets an ExtensionItem's value in a human-readable format.
74          * @param container The container the ExtensionItem is set on.
75          * @param item The value to convert to a human-readable format.
76          * @return The value specified in \p item in a human readable format.
77          */
78         virtual std::string ToHuman(const Extensible* container, void* item) const;
79         /** Gets an ExtensionItem's value in the internal format.
80          * @param container The container the ExtensionItem is set on.
81          * @param item The value to convert to the internal format.
82          * @return The value specified in \p item in the internal format.
83          */
84         virtual std::string ToInternal(const Extensible* container, void* item) const ;
85
86         /** Gets an ExtensionItem's value in the network format.
87          * @param container The container the ExtensionItem is set on.
88          * @param item The value to convert to the network format.
89          * @return The value specified in \p item in the network format.
90          */
91         virtual std::string ToNetwork(const Extensible* container, void* item) const;
92
93         /** Deallocates the specified ExtensionItem value.
94          * @param container The container that the ExtensionItem is set on.
95          * @param item The item to deallocate.
96          */
97         virtual void free(Extensible* container, void* item) = 0;
98
99         /** Registers this object with the ExtensionManager. */
100         void RegisterService() CXX11_OVERRIDE;
101
102         /** DEPRECATED: use To{Human,Internal,Network} instead. */
103         DEPRECATED_METHOD(virtual std::string serialize(SerializeFormat format, const Extensible* container, void* item) const);
104
105         /** DEPRECATED: use From{Internal,Network} instead. */
106         DEPRECATED_METHOD(virtual void unserialize(SerializeFormat format, Extensible* container, const std::string& value));
107
108  protected:
109         /** Retrieves the value for this ExtensionItem from the internal map.
110          * @param container The container that the ExtensionItem is set on.
111          * @return Either the value of this ExtensionItem or NULL if it is not set.
112          */
113         void* get_raw(const Extensible* container) const;
114
115         /** Stores a value for this ExtensionItem in the internal map and returns the old value if one was set.
116          * @param container A container the ExtensionItem should be set on.
117          * @param value The value to set on the specified container.
118          * @return Either the old value or NULL if one is not set.
119          */
120         void* set_raw(Extensible* container, void* value);
121
122         /** Removes the value for this ExtensionItem from the internal map and returns it.
123          * @param container A container the ExtensionItem should be removed from.
124          * @return Either the old value or NULL if one is not set.
125         */
126         void* unset_raw(Extensible* container);
127 };
128
129 /** class Extensible is the parent class of many classes such as User and Channel.
130  * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
131  * a map associated with the object. In this way modules can store their own custom information within user
132  * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
133  * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
134  * supports arbitary data storage).
135  */
136 class CoreExport Extensible
137         : public classbase
138         , public Serializable
139 {
140  public:
141         typedef insp::flat_map<reference<ExtensionItem>, void*> ExtensibleStore;
142
143         // Friend access for the protected getter/setter
144         friend class ExtensionItem;
145  private:
146         /** Private data store.
147          * Holds all extensible metadata for the class.
148          */
149         ExtensibleStore extensions;
150
151         /** True if this Extensible has been culled.
152          * A warning is generated if false on destruction.
153          */
154         unsigned int culled:1;
155  public:
156         /**
157          * Get the extension items for iteraton (i.e. for metadata sync during netburst)
158          */
159         inline const ExtensibleStore& GetExtList() const { return extensions; }
160
161         Extensible();
162         CullResult cull() CXX11_OVERRIDE;
163         virtual ~Extensible();
164         void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
165
166         /**
167          * Free all extension items attached to this Extensible
168          */
169         void FreeAllExtItems();
170
171         /** @copydoc Serializable::Deserialize. */
172         bool Deserialize(Data& data) CXX11_OVERRIDE;
173
174         /** @copydoc Serializable::Deserialize. */
175         bool Serialize(Serializable::Data& data) CXX11_OVERRIDE;
176 };
177
178 class CoreExport ExtensionManager
179 {
180  public:
181         typedef std::map<std::string, reference<ExtensionItem> > ExtMap;
182
183         bool Register(ExtensionItem* item);
184         void BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list);
185         ExtensionItem* GetItem(const std::string& name);
186
187         /** Get all registered extensions keyed by their names
188          * @return Const map of ExtensionItem pointers keyed by their names
189          */
190         const ExtMap& GetExts() const { return types; }
191
192  private:
193         ExtMap types;
194 };
195
196 /** DEPRECATED: use ExtensionItem instead. */
197 typedef ExtensionItem LocalExtItem;
198
199 template <typename T, typename Del = stdalgo::defaultdeleter<T> >
200 class SimpleExtItem : public ExtensionItem
201 {
202  public:
203         SimpleExtItem(const std::string& Key, ExtensibleType exttype, Module* parent)
204                 : ExtensionItem(Key, exttype, parent)
205         {
206         }
207
208         virtual ~SimpleExtItem()
209         {
210         }
211
212         inline T* get(const Extensible* container) const
213         {
214                 return static_cast<T*>(get_raw(container));
215         }
216
217         inline void set(Extensible* container, const T& value)
218         {
219                 T* ptr = new T(value);
220                 T* old = static_cast<T*>(set_raw(container, ptr));
221                 free(container, old);
222         }
223
224         inline void set(Extensible* container, T* value)
225         {
226                 T* old = static_cast<T*>(set_raw(container, value));
227                 free(container, old);
228         }
229
230         inline void unset(Extensible* container)
231         {
232                 T* old = static_cast<T*>(unset_raw(container));
233                 free(container, old);
234         }
235
236         void free(Extensible* container, void* item) CXX11_OVERRIDE
237         {
238                 Del del;
239                 del(static_cast<T*>(item));
240         }
241 };
242
243 class CoreExport LocalStringExt : public SimpleExtItem<std::string>
244 {
245  public:
246         LocalStringExt(const std::string& key, ExtensibleType exttype, Module* owner);
247         virtual ~LocalStringExt();
248         std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
249         void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
250 };
251
252 class CoreExport LocalIntExt : public ExtensionItem
253 {
254  public:
255         LocalIntExt(const std::string& key, ExtensibleType exttype, Module* owner);
256         virtual ~LocalIntExt();
257         std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
258         void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
259         intptr_t get(const Extensible* container) const;
260         intptr_t set(Extensible* container, intptr_t value);
261         void unset(Extensible* container) { set(container, 0); }
262         void free(Extensible* container, void* item) CXX11_OVERRIDE;
263 };
264
265 class CoreExport StringExtItem : public ExtensionItem
266 {
267  public:
268         StringExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
269         virtual ~StringExtItem();
270         std::string* get(const Extensible* container) const;
271         std::string ToNetwork(const Extensible* container, void* item) const CXX11_OVERRIDE;
272         void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE;
273         void set(Extensible* container, const std::string& value);
274         void unset(Extensible* container);
275         void free(Extensible* container, void* item) CXX11_OVERRIDE;
276 };