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