- std::string::size_type start = 0;
- std::string::size_type i = a.find('\r');
-
- /*
- * The old implementation here took a copy, and rfind() on \r, removing as it found them, before
- * copying a second time onto the recvq. That's ok, but involves three copies minimum (recv() to buffer,
- * buffer to here, here to recvq) - The new method now copies twice (recv() to buffer, buffer to recvq).
- *
- * We use find() instead of rfind() for clarity, however unlike the old code, our scanning of the string is
- * contiguous: as we specify a startpoint, we never see characters we have scanned previously, making this
- * marginally faster in cases with a number of \r hidden early on in the buffer.
- *
- * How it works:
- * Start at first pos of string, find first \r, append everything in the chunk (excluding \r) to recvq. Set
- * i ahead of the \r, search for next \r, add next chunk to buffer... repeat.
- * -- w00t (7 may, 2008)
- */
- if (i == std::string::npos)
- {
- // no \r that we need to dance around, just add to buffer
- recvq.append(a);
- }
- else
- {
- // While we can find the end of a chunk to add
- while (i != std::string::npos)
- {
- // Append the chunk that we have
- recvq.append(a, start, (i - start));
-
- // Start looking for the next one
- start = i + 1;
- i = a.find('\r', start);
- }
-
- if (start != a.length())
- {
- /*
- * This is here to catch a corner case when we get something like:
- * NICK w0
- * 0t\r\nU
- * SER ...
- * in successive calls to us.
- *
- * Without this conditional, the 'U' on the second case will be dropped,
- * which is most *certainly* not the behaviour we want!
- * -- w00t
- */
- recvq.append(a, start, (a.length() - start));
- }
- }
-
- if (this->MyClass && !this->HasPrivPermission("users/flood/increased-buffers") && recvq.length() > this->MyClass->GetRecvqMax())
- {
- ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
- ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax());
- return false;
- }
-
- return true;