]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/extensible.h
Merge branch 'insp20' into master.
[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 enum SerializeFormat
23 {
24         /** Shown to a human (does not need to be unserializable) */
25         FORMAT_USER,
26         /** Passed internally to this process (i.e. for /RELOADMODULE) */
27         FORMAT_INTERNAL,
28         /** Passed to other servers on the network (i.e. METADATA s2s command) */
29         FORMAT_NETWORK,
30         /** Stored on disk (i.e. permchannel database) */
31         FORMAT_PERSIST
32 };
33
34 /** Class represnting an extension of some object
35  */
36 class CoreExport ExtensionItem : public ServiceProvider, public usecountbase
37 {
38  public:
39         /** Extensible subclasses
40          */
41         enum ExtensibleType
42         {
43                 EXT_USER,
44                 EXT_CHANNEL,
45                 EXT_MEMBERSHIP
46         };
47
48         /** Type (subclass) of Extensible that this ExtensionItem is valid for
49          */
50         const ExtensibleType type;
51
52         ExtensionItem(const std::string& key, ExtensibleType exttype, Module* owner);
53         virtual ~ExtensionItem();
54         /** Serialize this item into a string
55          *
56          * @param format The format to serialize to
57          * @param container The object containing this item
58          * @param item The item itself
59          */
60         virtual std::string serialize(SerializeFormat format, const Extensible* container, void* item) const = 0;
61         /** Convert the string form back into an item
62          * @param format The format to serialize from (not FORMAT_USER)
63          * @param container The object that this item applies to
64          * @param value The return from a serialize() call that was run elsewhere with this key
65          */
66         virtual void unserialize(SerializeFormat format, Extensible* container, const std::string& value) = 0;
67         /** Free the item */
68         virtual void free(void* item) = 0;
69
70         /** Register this object in the ExtensionManager
71          */
72         void RegisterService() CXX11_OVERRIDE;
73
74  protected:
75         /** Get the item from the internal map */
76         void* get_raw(const Extensible* container) const;
77         /** Set the item in the internal map; returns old value */
78         void* set_raw(Extensible* container, void* value);
79         /** Remove the item from the internal map; returns old value */
80         void* unset_raw(Extensible* container);
81 };
82
83 /** class Extensible is the parent class of many classes such as User and Channel.
84  * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
85  * a map associated with the object. In this way modules can store their own custom information within user
86  * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
87  * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
88  * supports arbitary data storage).
89  */
90 class CoreExport Extensible : public classbase
91 {
92  public:
93         typedef insp::flat_map<reference<ExtensionItem>, void*> ExtensibleStore;
94
95         // Friend access for the protected getter/setter
96         friend class ExtensionItem;
97  private:
98         /** Private data store.
99          * Holds all extensible metadata for the class.
100          */
101         ExtensibleStore extensions;
102
103         /** True if this Extensible has been culled.
104          * A warning is generated if false on destruction.
105          */
106         unsigned int culled:1;
107  public:
108         /**
109          * Get the extension items for iteraton (i.e. for metadata sync during netburst)
110          */
111         inline const ExtensibleStore& GetExtList() const { return extensions; }
112
113         Extensible();
114         CullResult cull() CXX11_OVERRIDE;
115         virtual ~Extensible();
116         void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
117
118         /**
119          * Free all extension items attached to this Extensible
120          */
121         void FreeAllExtItems();
122 };
123
124 class CoreExport ExtensionManager
125 {
126  public:
127         typedef std::map<std::string, reference<ExtensionItem> > ExtMap;
128
129         bool Register(ExtensionItem* item);
130         void BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list);
131         ExtensionItem* GetItem(const std::string& name);
132
133         /** Get all registered extensions keyed by their names
134          * @return Const map of ExtensionItem pointers keyed by their names
135          */
136         const ExtMap& GetExts() const { return types; }
137
138  private:
139         ExtMap types;
140 };
141
142 /** Base class for items that are NOT synchronized between servers */
143 class CoreExport LocalExtItem : public ExtensionItem
144 {
145  public:
146         LocalExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
147         virtual ~LocalExtItem();
148         std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE;
149         void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE;
150         void free(void* item) CXX11_OVERRIDE = 0;
151 };
152
153 template <typename T, typename Del = stdalgo::defaultdeleter<T> >
154 class SimpleExtItem : public LocalExtItem
155 {
156  public:
157         SimpleExtItem(const std::string& Key, ExtensibleType exttype, Module* parent)
158                 : LocalExtItem(Key, exttype, parent)
159         {
160         }
161
162         virtual ~SimpleExtItem()
163         {
164         }
165
166         inline T* get(const Extensible* container) const
167         {
168                 return static_cast<T*>(get_raw(container));
169         }
170
171         inline void set(Extensible* container, const T& value)
172         {
173                 T* ptr = new T(value);
174                 T* old = static_cast<T*>(set_raw(container, ptr));
175                 Del del;
176                 del(old);
177         }
178
179         inline void set(Extensible* container, T* value)
180         {
181                 T* old = static_cast<T*>(set_raw(container, value));
182                 Del del;
183                 del(old);
184         }
185
186         inline void unset(Extensible* container)
187         {
188                 T* old = static_cast<T*>(unset_raw(container));
189                 Del del;
190                 del(old);
191         }
192
193         void free(void* item) CXX11_OVERRIDE
194         {
195                 Del del;
196                 del(static_cast<T*>(item));
197         }
198 };
199
200 class CoreExport LocalStringExt : public SimpleExtItem<std::string>
201 {
202  public:
203         LocalStringExt(const std::string& key, ExtensibleType exttype, Module* owner);
204         virtual ~LocalStringExt();
205         std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE;
206         void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE;
207 };
208
209 class CoreExport LocalIntExt : public LocalExtItem
210 {
211  public:
212         LocalIntExt(const std::string& key, ExtensibleType exttype, Module* owner);
213         virtual ~LocalIntExt();
214         std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE;
215         void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE;
216         intptr_t get(const Extensible* container) const;
217         intptr_t set(Extensible* container, intptr_t value);
218         void unset(Extensible* container) { set(container, 0); }
219         void free(void* item) CXX11_OVERRIDE;
220 };
221
222 class CoreExport StringExtItem : public ExtensionItem
223 {
224  public:
225         StringExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
226         virtual ~StringExtItem();
227         std::string* get(const Extensible* container) const;
228         std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE;
229         void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE;
230         void set(Extensible* container, const std::string& value);
231         void unset(Extensible* container);
232         void free(void* item) CXX11_OVERRIDE;
233 };