]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
irc::tokenstream is a token parser which using std::string and std::vector builds...
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 16 Jul 2006 01:40:58 +0000 (01:40 +0000)
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 16 Jul 2006 01:40:58 +0000 (01:40 +0000)
e.g.:
:arse PRIVMSG #chan :foo bar baz
becomes
a[0] = ":arse", a[1] = "PRIVMSG", a[2] = "#chan", a[3] = "foo bar baz".

*** SOMEONE *** needs to optimize this or at least verify its neatness (without making it total craq and unreadable). Feel free to mess with my code.
Any optimizations you make, run them against the COMMENTED OUT TEST SUITE at the top of main() in src/inspircd.cpp and ensure ALL output is the same
with no crashes. (note: if you comment out and build with the test suite, all inspircd will do is output test data and exit!)

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4396 e03df62e-2008-0410-955e-edbf42e46eb7

include/hashcomp.h
src/hashcomp.cpp
src/inspircd.cpp

index 36e5dd0c3d41d5d360fbe69daf5c7d933e791eb9..ad6a2133e8fdbeafcd3a643205e3b55920fa9b04 100644 (file)
@@ -79,6 +79,19 @@ namespace irc
                bool operator()(const in_addr &s1, const in_addr &s2) const;
        };
 
+       class tokenstream
+       {
+        private:
+               std::string tokenbuffer;
+               std::vector<std::string> tokens;
+        public:
+               tokenstream(std::string &source);
+               ~tokenstream();
+
+               unsigned int GetNumTokens();
+               const std::string& GetToken(unsigned int index);
+       };
+
 
        /** 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-
index 3271e599cda9dfa3e2cd3daebf1fbd5794af9dba..08fbc8e2f0f0a81157f1112b912e9bdc309549fa 100644 (file)
@@ -177,3 +177,47 @@ std::istream& operator>>(std::istream &is, irc::string &str)
        str = tmp.c_str();
        return is;
 }
+
+irc::tokenstream::tokenstream(std::string &source)
+{
+       std::string::iterator last_starting_position = source.begin();
+       bool last_pushed = false;
+
+       for (std::string::iterator n = source.begin(); n != source.end(); n++)
+       {
+               if ((last_pushed) && (*n == ':'))
+               {
+                       /* If we find a token thats not the first and starts with :,
+                        * this is the last token on the line
+                        */
+                       tokens.push_back(std::string(n+1, source.end()));
+                       break;
+               }
+
+               last_pushed = false;
+
+               if ((*n == ' ') || (n+1 == source.end()))
+               {
+                       /* If we find a space, or end of string, this is the end of a token.
+                        */
+                       tokens.push_back(std::string(last_starting_position, n+1 == source.end() ? n+1  : n));
+                       last_starting_position = n+1;
+                       last_pushed = true;
+               }
+       }
+}
+
+irc::tokenstream::~tokenstream()
+{
+}
+
+unsigned int irc::tokenstream::GetNumTokens()
+{
+       return tokens.size();
+}
+
+const std::string& irc::tokenstream::GetToken(unsigned int index)
+{
+       return tokens[index];
+}
+
index 23a232c4620bef89b4c99b2c10d7aa89e9a069fb..9635f707a5f652b86d027e1ec8b36b3fd6d65a1e 100644 (file)
@@ -944,6 +944,66 @@ int InspIRCd::Run()
 
 int main(int argc, char** argv)
 {
+       /* TEST SUITE FOR TOKENSTREAM
+        *
+        * Expected output:
+        * 
+        * String: 'PRIVMSG #test FOO BAR'
+        * NumItems = 4
+        * Token 0 = 'PRIVMSG'
+        * Token 1 = '#test'
+        * Token 2 = 'FOO'
+        * Token 3 = 'BAR'
+        * String: 'PRIVMSG #test :FOO BAR BAZ'
+        * NumItems = 3
+        * Token 0 = 'PRIVMSG'
+        * Token 1 = '#test'
+        * Token 2 = 'FOO BAR BAZ'
+        * String: ':PRIVMSG #test :FOO BAR BAZ'
+        * NumItems = 3
+        * Token 0 = ':PRIVMSG'
+        * String: 'AAAAAAA'
+        * NumItems = 1
+        * Token 0 = 'AAAAAAA'
+        * String: ''
+        * NumItems = 0
+        *
+       std::string a = "PRIVMSG #test FOO BAR";
+       printf("String: '%s'\n",a.c_str());
+       irc::tokenstream test(a);
+       printf("NumItems = %d\n",test.GetNumTokens());
+       printf("Token 0 = '%s'\n",test.GetToken(0).c_str());
+       printf("Token 1 = '%s'\n",test.GetToken(1).c_str());
+       printf("Token 2 = '%s'\n",test.GetToken(2).c_str());
+       printf("Token 3 = '%s'\n",test.GetToken(3).c_str());
+
+       std::string b = "PRIVMSG #test :FOO BAR BAZ";
+       printf("String: '%s'\n",b.c_str());
+       irc::tokenstream test2(b);
+       printf("NumItems = %d\n",test2.GetNumTokens());
+       printf("Token 0 = '%s'\n",test2.GetToken(0).c_str());
+       printf("Token 1 = '%s'\n",test2.GetToken(1).c_str());
+       printf("Token 2 = '%s'\n",test2.GetToken(2).c_str());
+
+       std::string c = ":PRIVMSG #test :FOO BAR BAZ";
+       printf("String: '%s'\n",c.c_str());
+       irc::tokenstream test3(c);
+       printf("NumItems = %d\n",test3.GetNumTokens());
+       printf("Token 0 = '%s'\n",test3.GetToken(0).c_str());
+
+       c = "AAAAAAA";
+       printf("String: '%s'\n",c.c_str());
+       irc::tokenstream test4(c);
+       printf("NumItems = %d\n",test4.GetNumTokens());
+       printf("Token 0 = '%s'\n",test4.GetToken(0).c_str());
+
+       c = "";
+       printf("String: '%s'\n",c.c_str());
+       irc::tokenstream test5(c);
+       printf("NumItems = %d\n",test5.GetNumTokens());
+
+       exit(0); */
+       
        try
        {
                ServerInstance = new InspIRCd(argc, argv);