summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-13 20:30:25 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-13 20:30:25 +0000
commit6d57bbe05c31c79eaad02fe81cfb9c1ed6b79c58 (patch)
treee0c89ed36b00f4c2925d7f39c32a835657b0fa6e /include
parent7eea21b8d43b0d5993e88b62d9d4894c2af49303 (diff)
Change Extensible to use strongly typed entries
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11696 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'include')
-rw-r--r--include/base.h118
-rw-r--r--include/extensible.h150
-rw-r--r--include/inspircd.h1
-rw-r--r--include/modules.h3
-rw-r--r--include/u_listmode.h62
-rw-r--r--include/users.h6
6 files changed, 172 insertions, 168 deletions
diff --git a/include/base.h b/include/base.h
index 6bcf76817..ab52545f9 100644
--- a/include/base.h
+++ b/include/base.h
@@ -18,9 +18,6 @@
#include <deque>
#include <string>
-/** A private data store for an Extensible class */
-typedef std::map<std::string,char*> ExtensibleStore;
-
/** The base class for all inspircd classes.
* Wherever possible, all classes you create should inherit from this,
* giving them the ability to be passed to various core functions
@@ -29,126 +26,11 @@ typedef std::map<std::string,char*> ExtensibleStore;
class CoreExport classbase
{
public:
- /** Constructor.
- * Sets the object's time
- */
classbase();
- /** Destructor.
- * Does sweet FA.
- */
virtual ~classbase() { }
};
-/** class Extensible is the parent class of many classes such as User and Channel.
- * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
- * a map associated with the object. In this way modules can store their own custom information within user
- * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
- * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
- * supports arbitary data storage).
- */
-class CoreExport Extensible : public classbase
-{
- /** Private data store.
- * Holds all extensible metadata for the class.
- */
- ExtensibleStore Extension_Items;
-
-public:
-
- /** Extend an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @param p This parameter is a pointer to any data you wish to associate with the object
- *
- * You must provide a key to store the data as via the parameter 'key' and store the data
- * in the templated parameter 'p'.
- * The data will be inserted into the map. If the data already exists, you may not insert it
- * twice, Extensible::Extend will return false in this case.
- *
- * @return Returns true on success, false if otherwise
- */
- template<typename T> bool Extend(const std::string &key, T* p)
- {
- /* This will only add an item if it doesnt already exist,
- * the return value is a std::pair of an iterator to the
- * element, and a bool saying if it was actually inserted.
- */
- return this->Extension_Items.insert(std::make_pair(key, (char*)p)).second;
- }
-
- /** Extend an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- *
- * You must provide a key to store the data as via the parameter 'key', this single-parameter
- * version takes no 'data' parameter, this is used purely for boolean values.
- * The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
- * then you may not insert it twice, Extensible::Extend will return false in this case.
- *
- * @return Returns true on success, false if otherwise
- */
- bool Extend(const std::string &key)
- {
- /* This will only add an item if it doesnt already exist,
- * the return value is a std::pair of an iterator to the
- * element, and a bool saying if it was actually inserted.
- */
- return this->Extension_Items.insert(std::make_pair(key, (char*)NULL)).second;
- }
-
- /** Shrink an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- *
- * You must provide a key name. The given key name will be removed from the classes data. If
- * you provide a nonexistent key (case is important) then the function will return false.
- * @return Returns true on success.
- */
- bool Shrink(const std::string &key);
-
- /** Get an extension item.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
- * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
- */
- template<typename T> bool GetExt(const std::string &key, T* &p)
- {
- ExtensibleStore::iterator iter = this->Extension_Items.find(key); /* Find the item */
- if(iter != this->Extension_Items.end())
- {
- p = (T*)iter->second; /* Item found */
- return true;
- }
- else
- {
- p = NULL; /* Item not found */
- return false;
- }
- }
-
- /** Get an extension item.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @return Returns true if the item was found and false if it was not.
- *
- * This single-parameter version only checks if the key exists, it does nothing with
- * the 'data' field and is probably only useful in conjunction with the single-parameter
- * version of Extend().
- */
- bool GetExt(const std::string &key)
- {
- return (this->Extension_Items.find(key) != this->Extension_Items.end());
- }
-
- /** Get a list of all extension items names.
- * @param list A deque of strings to receive the list
- * @return This function writes a list of all extension items stored in this object by name into the given deque and returns void.
- */
- void GetExtList(std::deque<std::string> &list);
-};
-
/** BoolSet is a utility class designed to hold eight bools in a bitmask.
* Use BoolSet::Set and BoolSet::Get to set and get bools in the bitmask,
* and Unset and Invert for special operations upon them.
diff --git a/include/extensible.h b/include/extensible.h
new file mode 100644
index 000000000..0a33470b5
--- /dev/null
+++ b/include/extensible.h
@@ -0,0 +1,150 @@
+class Extensible;
+class Module;
+
+/** Class represnting an extension of some object
+ */
+class CoreExport ExtensionItem
+{
+ public:
+ const std::string key;
+ Module* const owner;
+ ExtensionItem(const std::string& key, Module* owner);
+ /** Serialize this item into a string */
+ virtual std::string serialize(Module* requestor, const Extensible* container, void* item) = 0;
+ /** Convert the string form back into an item */
+ virtual void unserialize(Module* requestor, Extensible* container, const std::string& value) = 0;
+ /** Free the item */
+ virtual void free(void* item) = 0;
+
+ protected:
+ /** Get the item from the internal map */
+ void* get_raw(const Extensible* container);
+ /** Set the item in the internal map; returns old value */
+ void* set_raw(Extensible* container, void* value);
+ /** Remove the item from the internal map; returns old value */
+ void* unset_raw(Extensible* container);
+};
+
+/** A private data store for an Extensible class */
+typedef std::map<std::string,void*> ExtensibleStore;
+
+/** class Extensible is the parent class of many classes such as User and Channel.
+ * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
+ * a map associated with the object. In this way modules can store their own custom information within user
+ * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
+ * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
+ * supports arbitary data storage).
+ */
+class CoreExport Extensible : public classbase
+{
+ /** Private data store.
+ * Holds all extensible metadata for the class.
+ */
+ ExtensibleStore extensions;
+ typedef std::map<std::string, ExtensionItem*> ExtensibleTypes;
+ static ExtensibleTypes extension_types;
+ public:
+ /**
+ * Get the extension items for iteraton (i.e. for metadata sync during netburst)
+ */
+ inline const ExtensibleStore& GetExtList() const { return extensions; }
+ static inline const ExtensibleTypes& GetTypeList() { return extension_types; }
+ static inline ExtensionItem* GetItem(const std::string& name)
+ {
+ ExtensibleTypes::iterator i = extension_types.find(name);
+ if (i == extension_types.end())
+ return NULL;
+ return i->second;
+ }
+
+ virtual ~Extensible();
+
+ static bool Register(ExtensionItem* item);
+ static void UnRegister(Module* module);
+
+ // Friend access for the protected getter/setter
+ friend class ExtensionItem;
+};
+
+/** Base class for items that are NOT synchronized between servers */
+class CoreExport LocalExtItem : public ExtensionItem
+{
+ public:
+ LocalExtItem(const std::string& key, Module* owner);
+ // this is deliberately NOT virtual; don't subclass LocalExtItem if you want to sync data!
+ std::string serialize(Module* requestor, const Extensible* container, void* item);
+ void unserialize(Module* requestor, Extensible* container, const std::string& value);
+ virtual void free(void* item) = 0;
+};
+
+template<typename T>
+class CoreExport SimpleExtItem : public LocalExtItem
+{
+ public:
+ SimpleExtItem(const std::string& Key, Module* parent) : LocalExtItem(Key, parent)
+ {
+ }
+
+ inline T* get(const Extensible* container)
+ {
+ return static_cast<T*>(get_raw(container));
+ }
+
+ inline T* getNew(Extensible* container)
+ {
+ T* ptr = get(container);
+ if (!ptr)
+ {
+ ptr = new T;
+ set_raw(container, ptr);
+ }
+ return ptr;
+ }
+
+ inline void set(Extensible* container, const T& value)
+ {
+ T* ptr = new T(value);
+ T* old = static_cast<T*>(set_raw(container, ptr));
+ delete old;
+ }
+
+ inline void set(Extensible* container, T* value)
+ {
+ T* old = static_cast<T*>(set_raw(container, value));
+ delete old;
+ }
+
+ inline void unset(Extensible* container)
+ {
+ T* old = static_cast<T*>(unset_raw(container));
+ delete old;
+ }
+
+ virtual void free(void* item)
+ {
+ delete static_cast<T*>(item);
+ }
+};
+
+typedef SimpleExtItem<std::string> LocalStringExt;
+
+class CoreExport LocalIntExt : public LocalExtItem
+{
+ public:
+ LocalIntExt(const std::string& key, Module* owner);
+ intptr_t get(const Extensible* container);
+ intptr_t set(Extensible* container, intptr_t value);
+ void free(void* item);
+};
+
+class CoreExport StringExtItem : public ExtensionItem
+{
+ public:
+ StringExtItem(const std::string& key, Module* owner);
+ std::string* get(const Extensible* container);
+ std::string serialize(Module* requestor, const Extensible* container, void* item);
+ void unserialize(Module* requestor, Extensible* container, const std::string& value);
+ void set(Extensible* container, const std::string& value);
+ void unset(Extensible* container);
+ void free(void* item);
+};
diff --git a/include/inspircd.h b/include/inspircd.h
index ae46569a0..a7eed47ff 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -75,6 +75,7 @@ typedef std::multimap< std::string, KeyValList > ConfigDataHash;
#include "inspircd_config.h"
#include "inspircd_version.h"
+#include "extensible.h"
#include "numerics.h"
#include "uid.h"
#include "users.h"
diff --git a/include/modules.h b/include/modules.h
index 3f779fe80..9e9686ad2 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -442,11 +442,10 @@ class ConfigReader;
*/
class CoreExport Module : public Extensible
{
- protected:
+ public:
/** Creator/owner pointer
*/
InspIRCd* ServerInstance;
- public:
/** File that this module was loaded from
*/
std::string ModuleSourceFile;
diff --git a/include/u_listmode.h b/include/u_listmode.h
index 773ca421f..9d9b5f836 100644
--- a/include/u_listmode.h
+++ b/include/u_listmode.h
@@ -107,9 +107,6 @@ class ListModeRequest : public Request
class ListModeBase : public ModeHandler
{
protected:
- /** Storage key
- */
- std::string infokey;
/** Numeric to use when outputting the list
*/
unsigned int listnumeric;
@@ -131,6 +128,10 @@ class ListModeBase : public ModeHandler
limitlist chanlimits;
public:
+ /** Storage key
+ */
+ SimpleExtItem<modelist> extItem;
+
/** Constructor.
* @param Instance The creator of this class
* @param modechar Mode character
@@ -141,18 +142,19 @@ class ListModeBase : public ModeHandler
* @param ctag Configuration tag to get limits from
*/
ListModeBase(InspIRCd* Instance, Module* Creator, char modechar, const std::string &eolstr, unsigned int lnum, unsigned int eolnum, bool autotidy, const std::string &ctag = "banlist")
- : ModeHandler(Instance, Creator, modechar, 1, 1, true, MODETYPE_CHANNEL, false), listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy), configtag(ctag)
+ : ModeHandler(Instance, Creator, modechar, 1, 1, true, MODETYPE_CHANNEL, false),
+ listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy),
+ configtag(ctag), extItem("listbase_mode_" + std::string(1, mode) + "_list", Creator)
{
this->DoRehash();
- infokey = "listbase_mode_" + std::string(1, mode) + "_list";
+ Extensible::Register(&extItem);
}
/** See mode.h
*/
std::pair<bool,std::string> ModeSet(User*, User*, Channel* channel, const std::string &parameter)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
for (modelist::iterator it = el->begin(); it != el->end(); it++)
@@ -172,8 +174,7 @@ class ListModeBase : public ModeHandler
*/
virtual void DisplayList(User* user, Channel* channel)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
for (modelist::reverse_iterator it = el->rbegin(); it != el->rend(); ++it)
@@ -195,8 +196,7 @@ class ListModeBase : public ModeHandler
*/
virtual void RemoveMode(Channel* channel, irc::modestacker* stack)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
irc::modestacker modestack(ServerInstance, false);
@@ -271,8 +271,7 @@ class ListModeBase : public ModeHandler
virtual ModeAction OnModeChange(User* source, User*, Channel* channel, std::string &parameter, bool adding)
{
// Try and grab the list
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (adding)
{
@@ -281,7 +280,7 @@ class ListModeBase : public ModeHandler
{
// Make one
el = new modelist;
- channel->Extend(infokey, el);
+ extItem.set(channel, el);
}
// Clean the mask up
@@ -362,8 +361,7 @@ class ListModeBase : public ModeHandler
el->erase(it);
if (el->size() == 0)
{
- channel->Shrink(infokey);
- delete el;
+ extItem.unset(channel);
}
return MODEACTION_ALLOW;
}
@@ -384,29 +382,6 @@ class ListModeBase : public ModeHandler
return MODEACTION_DENY;
}
- /** Get Extensible key for this mode
- */
- virtual std::string& GetInfoKey()
- {
- return infokey;
- }
-
- /** Handle channel deletion.
- * See modules.h.
- * @param chan Channel being deleted
- */
- virtual void DoChannelDelete(Channel* chan)
- {
- modelist* mlist;
- chan->GetExt(infokey, mlist);
-
- if (mlist)
- {
- chan->Shrink(infokey);
- delete mlist;
- }
- }
-
/** Syncronize channel item list with another server.
* See modules.h
* @param chan Channel to syncronize
@@ -415,8 +390,7 @@ class ListModeBase : public ModeHandler
*/
virtual void DoSyncChannel(Channel* chan, Module* proto, void* opaque)
{
- modelist* mlist;
- chan->GetExt(infokey, mlist);
+ modelist* mlist = extItem.get(chan);
irc::modestacker modestack(ServerInstance, true);
std::vector<std::string> stackresult;
std::vector<TranslateType> types;
@@ -493,8 +467,7 @@ class ListModeBase : public ModeHandler
ListModeRequest* LM = (ListModeRequest*)request;
if (strcmp("LM_CHECKLIST", request->GetId()) == 0)
{
- modelist* mlist;
- LM->chan->GetExt(GetInfoKey(), mlist);
+ modelist* mlist = extItem.get(LM->chan);
if (mlist)
{
std::string mask = LM->user->nick + "!" + LM->user->ident + "@" + LM->user->GetIPString();
@@ -508,8 +481,7 @@ class ListModeBase : public ModeHandler
}
else if (strcmp("LM_CHECKLIST_EX", request->GetId()) == 0)
{
- modelist* mlist;
- LM->chan->GetExt(GetInfoKey(), mlist);
+ modelist* mlist = extItem.get(LM->chan);
if (mlist)
{
diff --git a/include/users.h b/include/users.h
index 5338deb4c..a6c36b7fd 100644
--- a/include/users.h
+++ b/include/users.h
@@ -274,6 +274,9 @@ class CoreExport User : public EventHandler
*/
InspIRCd* ServerInstance;
+ static LocalIntExt NICKForced;
+ static LocalStringExt OperQuit;
+
/** Contains a pointer to the connect class a user is on from - this will be NULL for remote connections.
* The pointer is guarenteed to *always* be valid. :)
*/
@@ -977,7 +980,4 @@ class CoreExport UserResolver : public Resolver
void OnError(ResolverError e, const std::string &errormessage);
};
-/* Configuration callbacks */
-//class ServerConfig;
-
#endif