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