From 17d91b065e98963451e595d7697357a40a1c4425 Mon Sep 17 00:00:00 2001 From: brain Date: Wed, 13 Jun 2007 18:12:04 +0000 Subject: [PATCH] Fixes for tokenization oddness with metadata, and weird behaviour of std::istringstream where the .str() method returns the whole string from the start to end, even AFTER youve read elements from it! Use irc::tokenstream instead and add some overridden methods to it. This is smarter as it reuses code and allows us to format metadata the same way we format irc data. NOTE: If you run any old servers alongside new servers (this revision) you might see spurious colons on the start of reasons for svsholds, cbans and filters. These can safely be ignored) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@7283 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/hashcomp.h | 82 ++++++++++++++++++++------------------- src/hashcomp.cpp | 24 ++++++++++++ src/modules/m_cban.cpp | 17 ++++---- src/modules/m_filter.h | 17 ++++---- src/modules/m_svshold.cpp | 14 +++---- 5 files changed, 90 insertions(+), 64 deletions(-) diff --git a/include/hashcomp.h b/include/hashcomp.h index aa3504994..338e23a09 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -6,7 +6,7 @@ * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -71,9 +71,41 @@ namespace irc { /** The operator () does the actual comparison in hash_map */ - bool operator()(const std::string& s1, const std::string& s2) const; + bool operator()(const std::string& s1, const std::string& s2) const; }; + /** The irc_char_traits class is used for RFC-style comparison of strings. + * This class is used to implement irc::string, a case-insensitive, RFC- + * comparing string class. + */ + struct irc_char_traits : std::char_traits { + + /** Check if two chars match + */ + static bool eq(char c1st, char c2nd); + + /** Check if two chars do NOT match + */ + static bool ne(char c1st, char c2nd); + + /** Check if one char is less than another + */ + static bool lt(char c1st, char c2nd); + + /** Compare two strings of size n + */ + static CoreExport int compare(const char* str1, const char* str2, size_t n); + + /** Find a char within a string up to position n + */ + static CoreExport const char* find(const char* s1, int n, char c); + }; + + CoreExport std::string hex(const unsigned char *raw, size_t rawsz); + + /** This typedef declares irc::string based upon irc_char_traits + */ + typedef basic_string > string; /** irc::stringjoiner joins string lists into a string, using * the given seperator string. @@ -216,6 +248,9 @@ namespace irc * @return The next token is returned, or an empty string if none remain */ bool GetToken(std::string &token); + bool GetToken(irc::string &token); + bool GetToken(int &token); + bool GetToken(long &token); }; /** irc::sepstream allows for splitting token seperated lists. @@ -371,23 +406,23 @@ namespace irc * * mydbitmask() : irc::dynamicbitmask() * { - * freebits = new unsigned char[this->bits_size]; - * memset(freebits, 0, this->bits_size); + * freebits = new unsigned char[this->bits_size]; + * memset(freebits, 0, this->bits_size); * } * * ~mydbitmask() * { - * delete[] freebits; + * delete[] freebits; * } * * unsigned char* GetFreeBits() * { - * return freebits; + * return freebits; * } * * void SetFreeBits(unsigned char* freebt) * { - * freebits = freebt; + * freebits = freebt; * } * }; * \endcode @@ -461,39 +496,6 @@ namespace irc virtual void SetFreeBits(unsigned char* freebits) { } }; - /** The irc_char_traits class is used for RFC-style comparison of strings. - * This class is used to implement irc::string, a case-insensitive, RFC- - * comparing string class. - */ - struct irc_char_traits : std::char_traits { - - /** Check if two chars match - */ - static bool eq(char c1st, char c2nd); - - /** Check if two chars do NOT match - */ - static bool ne(char c1st, char c2nd); - - /** Check if one char is less than another - */ - static bool lt(char c1st, char c2nd); - - /** Compare two strings of size n - */ - static CoreExport int compare(const char* str1, const char* str2, size_t n); - - /** Find a char within a string up to position n - */ - static CoreExport const char* find(const char* s1, int n, char c); - }; - - CoreExport std::string hex(const unsigned char *raw, size_t rawsz); - - /** This typedef declares irc::string based upon irc_char_traits - */ - typedef basic_string > string; - CoreExport const char* Spacify(const char* n); } diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 0a7264576..630faba4b 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -215,6 +215,30 @@ bool irc::tokenstream::GetToken(std::string &token) return false; } +bool irc::tokenstream::GetToken(irc::string &token) +{ + std::string stdstring; + bool returnval = GetToken(stdstring); + token = assign(stdstring); + return returnval; +} + +bool irc::tokenstream::GetToken(int &token) +{ + std::string tok; + bool returnval = GetToken(tok); + token = ConvToInt(tok); + return returnval; +} + +bool irc::tokenstream::GetToken(long &token) +{ + std::string tok; + bool returnval = GetToken(tok); + token = ConvToInt(tok); + return returnval; +} + irc::sepstream::sepstream(const std::string &source, char seperator) : tokens(source), sep(seperator) { last_starting_position = tokens.begin(); diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp index 04a99674d..3b6c4eccd 100644 --- a/src/modules/m_cban.cpp +++ b/src/modules/m_cban.cpp @@ -202,20 +202,19 @@ class ModuleCBan : public Module std::string EncodeCBan(const CBan &ban) { std::ostringstream stream; - stream << ban.chname << " " << ban.set_by << " " << ban.set_on << " " << ban.length << " " << ban.reason; - return stream.str(); + stream << ban.chname << " " << ban.set_by << " " << ban.set_on << " " << ban.length << " :" << ban.reason; + return stream.str(); } CBan DecodeCBan(const std::string &data) { CBan res; - std::istringstream stream(data); - stream >> res.chname; - stream >> res.set_by; - stream >> res.set_on; - stream >> res.length; - res.reason = stream.str(); - + irc::tokenstream tokens(data); + tokens.GetToken(res.chname); + tokens.GetToken(res.set_by); + tokens.GetToken(res.set_on); + tokens.GetToken(res.length); + tokens.GetToken(res.reason); return res; } diff --git a/src/modules/m_filter.h b/src/modules/m_filter.h index 6bf112107..f2986804c 100644 --- a/src/modules/m_filter.h +++ b/src/modules/m_filter.h @@ -402,28 +402,29 @@ std::string FilterBase::EncodeFilter(FilterResult* filter) std::ostringstream stream; std::string x = filter->freeform; + /* Hax to allow spaces in the freeform without changing the design of the irc protocol */ for (std::string::iterator n = x.begin(); n != x.end(); n++) if (*n == ' ') *n = '\7'; - stream << x << " " << filter->action << " " << (filter->flags.empty() ? "-" : filter->flags) << " " << filter->gline_time << " " << filter->reason; + stream << x << " " << filter->action << " " << (filter->flags.empty() ? "-" : filter->flags) << " " << filter->gline_time << " :" << filter->reason; return stream.str(); } FilterResult FilterBase::DecodeFilter(const std::string &data) { FilterResult res; - std::istringstream stream(data); - - stream >> res.freeform; - stream >> res.action; - stream >> res.flags; + irc::tokenstream tokens(data); + tokens.GetToken(res.freeform); + tokens.GetToken(res.action); + tokens.GetToken(res.flags); if (res.flags == "-") res.flags = ""; res.FillFlags(res.flags); - stream >> res.gline_time; - res.reason = stream.str(); + tokens.GetToken(res.gline_time); + tokens.GetToken(res.reason); + /* Hax to allow spaces in the freeform without changing the design of the irc protocol */ for (std::string::iterator n = res.freeform.begin(); n != res.freeform.end(); n++) if (*n == '\7') *n = ' '; diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index 25df81f7b..7a164d920 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -238,19 +238,19 @@ class ModuleSVSHold : public Module std::string EncodeSVSHold(const SVSHold* ban) { std::ostringstream stream; - stream << ban->nickname << " " << ban->set_by << " " << ban->set_on << " " << ban->length << " " << ban->reason; + stream << ban->nickname << " " << ban->set_by << " " << ban->set_on << " " << ban->length << " :" << ban->reason; return stream.str(); } SVSHold* DecodeSVSHold(const std::string &data) { SVSHold* res = new SVSHold(); - std::istringstream stream(data); - stream >> res->nickname; - stream >> res->set_by; - stream >> res->set_on; - stream >> res->length; - res->reason = stream.str(); + irc::tokenstream tokens(data); + tokens.GetToken(res->nickname); + tokens.GetToken(res->set_by); + tokens.GetToken(res->set_on); + tokens.GetToken(res->length); + tokens.GetToken(res->reason); return res; } -- 2.39.2