diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-12-05 16:16:49 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-12-05 16:16:49 +0100 |
commit | 425d54073a0ae61c68de1b339177bb7c0db116f1 (patch) | |
tree | 8a0e4e91f0a5deeaa3e50ef5f42c983400e0c393 | |
parent | ddc6999a1db1aa1e9bf9df2f1ab444c387bcd5b1 (diff) |
m_cap Specialize extension item
-rw-r--r-- | include/modules/cap.h | 9 | ||||
-rw-r--r-- | src/modules/m_cap.cpp | 55 |
2 files changed, 62 insertions, 2 deletions
diff --git a/include/modules/cap.h b/include/modules/cap.h index 6f91f5aee..9ff5faca9 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -28,7 +28,14 @@ namespace Cap static const unsigned int MAX_VALUE_LENGTH = 100; typedef intptr_t Ext; - typedef LocalIntExt ExtItem; + class ExtItem : public LocalIntExt + { + public: + ExtItem(Module* mod); + std::string serialize(SerializeFormat format, const Extensible* container, void* item) const; + void unserialize(SerializeFormat format, Extensible* container, const std::string& value); + }; + class Capability; enum Protocol diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index e1593e33f..bfce2e68c 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -25,6 +25,8 @@ namespace Cap class ManagerImpl; } +static Cap::ManagerImpl* managerimpl; + class Cap::ManagerImpl : public Cap::Manager { typedef insp::flat_map<std::string, Capability*, irc::insensitive_swo> CapMap; @@ -62,9 +64,10 @@ class Cap::ManagerImpl : public Cap::Manager public: ManagerImpl(Module* mod, Events::ModuleEventProvider& evprovref) : Cap::Manager(mod) - , capext("caps", ExtensionItem::EXT_USER, mod) + , capext(mod) , evprov(evprovref) { + managerimpl = this; } ~ManagerImpl() @@ -199,6 +202,56 @@ class Cap::ManagerImpl : public Cap::Manager } }; +Cap::ExtItem::ExtItem(Module* mod) + : LocalIntExt("caps", ExtensionItem::EXT_USER, mod) +{ +} + +std::string Cap::ExtItem::serialize(SerializeFormat format, const Extensible* container, void* item) const +{ + std::string ret; + // XXX: Cast away the const because IS_LOCAL() doesn't handle it + LocalUser* user = IS_LOCAL(const_cast<User*>(static_cast<const User*>(container))); + if ((format == FORMAT_NETWORK) || (!user)) + return ret; + + // List requested caps + managerimpl->HandleList(ret, user, false, false); + + // Serialize cap protocol version. If building a human-readable string append a new token, otherwise append only a single character indicating the version. + Protocol protocol = managerimpl->GetProtocol(user); + if (format == FORMAT_USER) + ret.append("capversion=3."); + else if (!ret.empty()) + ret.erase(ret.length()-1); + + if (protocol == CAP_302) + ret.push_back('2'); + else + ret.push_back('1'); + + return ret; +} + +void Cap::ExtItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value) +{ + if (format == FORMAT_NETWORK) + return; + + LocalUser* user = IS_LOCAL(static_cast<User*>(container)); + if (!user) + return; // Can't happen + + // Process the cap protocol version which is a single character at the end of the serialized string + const char verchar = *value.rbegin(); + if (verchar == '2') + managerimpl->Set302Protocol(user); + + // Remove the version indicator from the string passed to HandleReq + std::string caplist(value, 0, value.size()-1); + managerimpl->HandleReq(user, caplist); +} + class CommandCap : public SplitCommand { Events::ModuleEventProvider evprov; |