cut messages at 512 bytes, taking into account the UTF-8 codepoints
ref #3067
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
#include <utils/encoding.hpp>
|
||||||
|
|
||||||
bool to_bool(const std::string& val)
|
bool to_bool(const std::string& val)
|
||||||
{
|
{
|
||||||
@@ -11,8 +12,17 @@ std::vector<std::string> cut(const std::string& val, const std::size_t size)
|
|||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
while (pos < val.size())
|
while (pos < val.size())
|
||||||
{
|
{
|
||||||
res.emplace_back(val.substr(pos, size));
|
// Get the number of chars, <= size, that contain only whole
|
||||||
pos += size;
|
// UTF-8 codepoints.
|
||||||
|
std::size_t s = 0;
|
||||||
|
auto codepoint_size = utils::get_next_codepoint_size(val[pos + s]);
|
||||||
|
while (s + codepoint_size <= size)
|
||||||
|
{
|
||||||
|
s += codepoint_size;
|
||||||
|
codepoint_size = utils::get_next_codepoint_size(val[pos + s]);
|
||||||
|
}
|
||||||
|
res.emplace_back(val.substr(pos, s));
|
||||||
|
pos += s;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -388,6 +388,8 @@ void IrcClient::send_message(IrcMessage&& message)
|
|||||||
res += " " + arg;
|
res += " " + arg;
|
||||||
}
|
}
|
||||||
res += "\r\n";
|
res += "\r\n";
|
||||||
|
log_debug("Effective size: ", res.size());
|
||||||
|
log_debug(res);
|
||||||
this->send_data(std::move(res));
|
this->send_data(std::move(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,8 +460,7 @@ bool IrcClient::send_channel_message(const std::string& chan_name, const std::st
|
|||||||
}
|
}
|
||||||
// Cut the message body into 512-bytes parts, because the whole command
|
// Cut the message body into 512-bytes parts, because the whole command
|
||||||
// must fit into 512 bytes.
|
// must fit into 512 bytes.
|
||||||
// Count the ':' at the start of the text, and two spaces
|
const auto line_size = 500 - ::strlen("PRIVMSG ") - chan_name.length() - ::strlen(" :\r\n");
|
||||||
const auto line_size = 512 - ::strlen("PRIVMSG") - chan_name.length() - 3;
|
|
||||||
const auto lines = cut(body, line_size);
|
const auto lines = cut(body, line_size);
|
||||||
for (const auto& line: lines)
|
for (const auto& line: lines)
|
||||||
this->send_message(IrcMessage("PRIVMSG", {chan_name, line}));
|
this->send_message(IrcMessage("PRIVMSG", {chan_name, line}));
|
||||||
|
|||||||
+7
-1
@@ -93,4 +93,10 @@ TEST_CASE("string cut")
|
|||||||
{
|
{
|
||||||
CHECK(cut("coucou", 2).size() == 3);
|
CHECK(cut("coucou", 2).size() == 3);
|
||||||
CHECK(cut("bonjour les copains", 6).size() == 4);
|
CHECK(cut("bonjour les copains", 6).size() == 4);
|
||||||
}
|
CHECK(cut("««««", 2).size() == 4);
|
||||||
|
CHECK(cut("a««««", 2).size() == 5);
|
||||||
|
const auto res = cut("rhello, ♥", 10);
|
||||||
|
CHECK(res.size() == 2);
|
||||||
|
CHECK(res[0] == "rhello, ");
|
||||||
|
CHECK(res[1] == "♥");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user