]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/command_parse.cpp
publish "JSON-RPC" interface
[user/henk/code/inspircd.git] / src / command_parse.cpp
index 5985853153008e8170cd35f06221a442fbe38afc..52c58ef999aba743e78506101cd314538479aea6 100644 (file)
@@ -1,4 +1,4 @@
-       /*       +------------------------------------+
+/*       +------------------------------------+
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
@@ -62,34 +62,47 @@ std::string InspIRCd::TimeString(time_t curtime)
        return std::string(ctime(&curtime),24);
 }
 
-long InspIRCd::Duration(const char* str)
+/** Refactored by Brain, Jun 2007. Much faster with some clever O(1) array
+ * lookups and pointer maths.
+ */
+long InspIRCd::Duration(const std::string &str)
 {
-       char n_field[MAXBUF];
-       const char* maxsize = n_field + MAXBUF;
+       unsigned char multiplier = 0;
        long total = 0;
-       char* field_ptr = n_field;
-       *n_field = 0;
+       long times = 1;
+       long subtotal = 0;
 
-       for (const char* i = str; *i; i++)
+       /* Iterate each item in the string, looking for number or multiplier */
+       for (std::string::const_reverse_iterator i = str.rbegin(); i != str.rend(); ++i)
        {
-               if ((*i >= '0') && (*i <= '9') && (field_ptr < maxsize))
-                       *field_ptr++ = *i;
+               /* Found a number, queue it onto the current number */
+               if ((*i >= '0') && (*i <= '9'))
+               {
+                       subtotal = subtotal + ((*i - '0') * times);
+                       times = times * 10;
+               }
                else
                {
-                       *field_ptr = 0;
-                       field_ptr = n_field;
-                       total += atoi(n_field) * duration_multi[(const unsigned char)*i];
-                       *n_field = 0;
+                       /* Found something thats not a number, find out how much
+                        * it multiplies the built up number by, multiply the total
+                        * and reset the built up number.
+                        */
+                       if (subtotal)
+                               total += subtotal * duration_multi[multiplier];
+
+                       /* Next subtotal please */
+                       subtotal = 0;
+                       multiplier = *i;
+                       times = 1;
                }
        }
-       // add trailing seconds
-       if (*n_field)
+       if (multiplier)
        {
-               *field_ptr = 0;
-               total += atoi(n_field);
+               total += subtotal * duration_multi[multiplier];
+               subtotal = 0;
        }
-
-       return total;
+       /* Any trailing values built up are treated as raw seconds */
+       return total + subtotal;
 }
 
 /* LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
@@ -120,7 +133,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
         */
        irc::commasepstream items1(parameters[splithere]);
        irc::commasepstream items2(parameters[extra]);
-       std::string item = "*";
+       std::string item("*");
        unsigned int max = 0;
 
        /* Attempt to iterate these lists and call the command objech
@@ -161,7 +174,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
 
        /* Only one commasepstream here */
        irc::commasepstream items1(parameters[splithere]);
-       std::string item = "*";
+       std::string item("*");
        unsigned int max = 0;
 
        /* Parse the commasepstream until there are no tokens remaining.
@@ -382,6 +395,7 @@ void CommandParser::RemoveCommand(command_table::iterator safei, const char* sou
        if (x->source == std::string(source))
        {
                cmdlist.erase(safei);
+               delete x;
        }
 }