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