2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013, 2017-2020 Sadie Powell <sadie@witchery.services>
5 * Copyright (C) 2012, 2014-2015 Attila Molnar <attilamolnar@hush.com>
6 * Copyright (C) 2012 Robby <robby@chatbelgie.be>
7 * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
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.
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
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/>.
25 /** DEPRECATED: use {To,From}{Human,Internal,Network} instead. */
34 /** Base class for logic that extends an Extensible object. */
35 class CoreExport ExtensionItem : public ServiceProvider, public usecountbase
38 /** Types of Extensible that an ExtensionItem can apply to. */
41 /** The ExtensionItem applies to a User object. */
44 /** The ExtensionItem applies to a Channel object. */
47 /** The ExtensionItem applies to a Membership object. */
51 /** The type of Extensible that this ExtensionItem applies to. */
52 const ExtensibleType type;
54 /** Initializes an instance of the ExtensionItem class.
55 * @param key The name of the extension item (e.g. ssl_cert).
56 * @param exttype The type of Extensible that this ExtensionItem applies to.
57 * @param owner The module which created this ExtensionItem.
59 ExtensionItem(const std::string& key, ExtensibleType exttype, Module* owner);
61 /** Destroys an instance of the ExtensionItem class. */
62 virtual ~ExtensionItem();
64 /** Sets an ExtensionItem using a value in the internal format.
65 * @param container A container the ExtensionItem should be set on.
66 * @param value A value in the internal format.
68 virtual void FromInternal(Extensible* container, const std::string& value);
70 /** Sets an ExtensionItem using a value in the network format.
71 * @param container A container the ExtensionItem should be set on.
72 * @param value A value in the network format.
74 virtual void FromNetwork(Extensible* container, const std::string& value);
76 /** Gets an ExtensionItem's value in a human-readable format.
77 * @param container The container the ExtensionItem is set on.
78 * @param item The value to convert to a human-readable format.
79 * @return The value specified in \p item in a human readable format.
81 virtual std::string ToHuman(const Extensible* container, void* item) const;
82 /** Gets an ExtensionItem's value in the internal format.
83 * @param container The container the ExtensionItem is set on.
84 * @param item The value to convert to the internal format.
85 * @return The value specified in \p item in the internal format.
87 virtual std::string ToInternal(const Extensible* container, void* item) const ;
89 /** Gets an ExtensionItem's value in the network format.
90 * @param container The container the ExtensionItem is set on.
91 * @param item The value to convert to the network format.
92 * @return The value specified in \p item in the network format.
94 virtual std::string ToNetwork(const Extensible* container, void* item) const;
96 /** Deallocates the specified ExtensionItem value.
97 * @param container The container that the ExtensionItem is set on.
98 * @param item The item to deallocate.
100 virtual void free(Extensible* container, void* item) = 0;
102 /** Registers this object with the ExtensionManager. */
103 void RegisterService() CXX11_OVERRIDE;
105 /** DEPRECATED: use To{Human,Internal,Network} instead. */
106 DEPRECATED_METHOD(virtual std::string serialize(SerializeFormat format, const Extensible* container, void* item) const);
108 /** DEPRECATED: use From{Internal,Network} instead. */
109 DEPRECATED_METHOD(virtual void unserialize(SerializeFormat format, Extensible* container, const std::string& value));
112 /** Retrieves the value for this ExtensionItem from the internal map.
113 * @param container The container that the ExtensionItem is set on.
114 * @return Either the value of this ExtensionItem or NULL if it is not set.
116 void* get_raw(const Extensible* container) const;
118 /** Stores a value for this ExtensionItem in the internal map and returns the old value if one was set.
119 * @param container A container the ExtensionItem should be set on.
120 * @param value The value to set on the specified container.
121 * @return Either the old value or NULL if one is not set.
123 void* set_raw(Extensible* container, void* value);
125 /** Removes the value for this ExtensionItem from the internal map and returns it.
126 * @param container A container the ExtensionItem should be removed from.
127 * @return Either the old value or NULL if one is not set.
129 void* unset_raw(Extensible* container);
132 /** class Extensible is the parent class of many classes such as User and Channel.
133 * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
134 * a map associated with the object. In this way modules can store their own custom information within user
135 * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
136 * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
137 * supports arbitrary data storage).
139 class CoreExport Extensible
141 , public Serializable
144 typedef insp::flat_map<reference<ExtensionItem>, void*> ExtensibleStore;
146 // Friend access for the protected getter/setter
147 friend class ExtensionItem;
149 /** Private data store.
150 * Holds all extensible metadata for the class.
152 ExtensibleStore extensions;
154 /** True if this Extensible has been culled.
155 * A warning is generated if false on destruction.
157 unsigned int culled:1;
160 * Get the extension items for iteraton (i.e. for metadata sync during netburst)
162 inline const ExtensibleStore& GetExtList() const { return extensions; }
165 CullResult cull() CXX11_OVERRIDE;
166 virtual ~Extensible();
167 void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
170 * Free all extension items attached to this Extensible
172 void FreeAllExtItems();
174 /** @copydoc Serializable::Deserialize */
175 bool Deserialize(Data& data) CXX11_OVERRIDE;
177 /** @copydoc Serializable::Deserialize */
178 bool Serialize(Serializable::Data& data) CXX11_OVERRIDE;
181 class CoreExport ExtensionManager
184 typedef std::map<std::string, reference<ExtensionItem> > ExtMap;
186 bool Register(ExtensionItem* item);
187 void BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list);
188 ExtensionItem* GetItem(const std::string& name);
190 /** Get all registered extensions keyed by their names
191 * @return Const map of ExtensionItem pointers keyed by their names
193 const ExtMap& GetExts() const { return types; }
199 /** DEPRECATED: use ExtensionItem instead. */
200 typedef ExtensionItem LocalExtItem;
202 template <typename T, typename Del = stdalgo::defaultdeleter<T> >
203 class SimpleExtItem : public ExtensionItem
206 SimpleExtItem(const std::string& Key, ExtensibleType exttype, Module* parent)
207 : ExtensionItem(Key, exttype, parent)
211 virtual ~SimpleExtItem()
215 inline T* get(const Extensible* container) const
217 return static_cast<T*>(get_raw(container));
220 inline void set(Extensible* container, const T& value)
222 T* ptr = new T(value);
223 T* old = static_cast<T*>(set_raw(container, ptr));
224 free(container, old);
227 inline void set(Extensible* container, T* value)
229 T* old = static_cast<T*>(set_raw(container, value));
230 free(container, old);
233 inline void unset(Extensible* container)
235 T* old = static_cast<T*>(unset_raw(container));
236 free(container, old);
239 void free(Extensible* container, void* item) CXX11_OVERRIDE
242 del(static_cast<T*>(item));
246 class CoreExport LocalStringExt : public SimpleExtItem<std::string>
249 LocalStringExt(const std::string& key, ExtensibleType exttype, Module* owner);
250 virtual ~LocalStringExt();
251 std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
252 void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
255 class CoreExport LocalIntExt : public ExtensionItem
258 LocalIntExt(const std::string& key, ExtensibleType exttype, Module* owner);
259 virtual ~LocalIntExt();
260 std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE;
261 void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE;
262 intptr_t get(const Extensible* container) const;
263 intptr_t set(Extensible* container, intptr_t value);
264 void unset(Extensible* container) { set(container, 0); }
265 void free(Extensible* container, void* item) CXX11_OVERRIDE;
268 class CoreExport StringExtItem : public ExtensionItem
271 StringExtItem(const std::string& key, ExtensibleType exttype, Module* owner);
272 virtual ~StringExtItem();
273 std::string* get(const Extensible* container) const;
274 std::string ToNetwork(const Extensible* container, void* item) const CXX11_OVERRIDE;
275 void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE;
276 void set(Extensible* container, const std::string& value);
277 void unset(Extensible* container);
278 void free(Extensible* container, void* item) CXX11_OVERRIDE;