diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-13 20:30:25 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-13 20:30:25 +0000 |
commit | 6d57bbe05c31c79eaad02fe81cfb9c1ed6b79c58 (patch) | |
tree | e0c89ed36b00f4c2925d7f39c32a835657b0fa6e /include | |
parent | 7eea21b8d43b0d5993e88b62d9d4894c2af49303 (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.h | 118 | ||||
-rw-r--r-- | include/extensible.h | 150 | ||||
-rw-r--r-- | include/inspircd.h | 1 | ||||
-rw-r--r-- | include/modules.h | 3 | ||||
-rw-r--r-- | include/u_listmode.h | 62 | ||||
-rw-r--r-- | include/users.h | 6 |
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 ¶meter) { - 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 ¶meter, 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 |