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