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