]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/extensible.h
Convert all core ExtensionItem code away from {un,}serialize.
[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 : public classbase
137 {
138  public:
139         typedef insp::flat_map<reference<ExtensionItem>, void*> ExtensibleStore;
140
141         // Friend access for the protected getter/setter
142         friend class ExtensionItem;
143  private:
144         /** Private data store.
145          * Holds all extensible metadata for the class.
146          */
147         ExtensibleStore extensions;
148
149         /** True if this Extensible has been culled.
150          * A warning is generated if false on destruction.
151          */
152         unsigned int culled:1;
153  public:
154         /**
155          * Get the extension items for iteraton (i.e. for metadata sync during netburst)
156          */
157         inline const ExtensibleStore& GetExtList() const { return extensions; }
158
159         Extensible();
160         CullResult cull() CXX11_OVERRIDE;
161         virtual ~Extensible();
162         void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
163
164         /**
165          * Free all extension items attached to this Extensible
166          */
167         void FreeAllExtItems();
168 };
169
170 class CoreExport ExtensionManager
171 {
172  public:
173         typedef std::map<std::string, reference<ExtensionItem> > ExtMap;
174
175         bool Register(ExtensionItem* item);
176         void BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list);
177         ExtensionItem* GetItem(const std::string& name);
178
179         /** Get all registered extensions keyed by their names
180          * @return Const map of ExtensionItem pointers keyed by their names
181          */
182         const ExtMap& GetExts() const { return types; }
183
184  private:
185         ExtMap types;
186 };
187
188 /** Base class for items that are NOT synchronized between servers */
189 class CoreExport LocalExtItem : public ExtensionItem
190 {
191  public:
192         LocalExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
193         virtual ~LocalExtItem();
194         void free(Extensible* container, void* item) CXX11_OVERRIDE = 0;
195 };
196
197 template <typename T, typename Del = stdalgo::defaultdeleter<T> >
198 class SimpleExtItem : public LocalExtItem
199 {
200  public:
201         SimpleExtItem(const std::string& Key, ExtensibleType exttype, Module* parent)
202                 : LocalExtItem(Key, exttype, parent)
203         {
204         }
205
206         virtual ~SimpleExtItem()
207         {
208         }
209
210         inline T* get(const Extensible* container) const
211         {
212                 return static_cast<T*>(get_raw(container));
213         }
214
215         inline void set(Extensible* container, const T& value)
216         {
217                 T* ptr = new T(value);
218                 T* old = static_cast<T*>(set_raw(container, ptr));
219                 Del del;
220                 del(old);
221         }
222
223         inline void set(Extensible* container, T* value)
224         {
225                 T* old = static_cast<T*>(set_raw(container, value));
226                 Del del;
227                 del(old);
228         }
229
230         inline void unset(Extensible* container)
231         {
232                 T* old = static_cast<T*>(unset_raw(container));
233                 Del del;
234                 del(old);
235         }
236
237         void free(Extensible* container, void* item) CXX11_OVERRIDE
238         {
239                 Del del;
240                 del(static_cast<T*>(item));
241         }
242 };
243
244 class CoreExport LocalStringExt : public SimpleExtItem<std::string>
245 {
246  public:
247         LocalStringExt(const std::string& key, ExtensibleType exttype, Module* owner);
248         virtual ~LocalStringExt();
249         std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
250         void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
251 };
252
253 class CoreExport LocalIntExt : public LocalExtItem
254 {
255  public:
256         LocalIntExt(const std::string& key, ExtensibleType exttype, Module* owner);
257         virtual ~LocalIntExt();
258         std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
259         void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
260         intptr_t get(const Extensible* container) const;
261         intptr_t set(Extensible* container, intptr_t value);
262         void unset(Extensible* container) { set(container, 0); }
263         void free(Extensible* container, void* item) CXX11_OVERRIDE;
264 };
265
266 class CoreExport StringExtItem : public ExtensionItem
267 {
268  public:
269         StringExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
270         virtual ~StringExtItem();
271         std::string* get(const Extensible* container) const;
272         std::string ToNetwork(const Extensible* container, void* item) const CXX11_OVERRIDE;
273         void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE;
274         void set(Extensible* container, const std::string& value);
275         void unset(Extensible* container);
276         void free(Extensible* container, void* item) CXX11_OVERRIDE;
277 };