degesch: better message autosplit

This commit is contained in:
Přemysl Eric Janouch 2015-04-22 23:08:01 +02:00
parent 53b46482f5
commit 2633eda69a
1 changed files with 43 additions and 13 deletions

View File

@ -2722,27 +2722,57 @@ send_message_to_target (struct app_context *ctx,
return;
}
int one_message = 0;
// We don't always have the full info for message splitting
int space_in_one_message = 0;
if (ctx->irc_user_host)
// :<nick>!<user>@<host> PRIVMSG <target> :<message>
one_message = 510 - 1 - (int) strlen (ctx->irc_user->nickname)
space_in_one_message = 510
- 1 - (int) strlen (ctx->irc_user->nickname)
- 1 - (int) strlen (ctx->irc_user_host)
- 1 - 7 - 1 - strlen (target) - 1 - 1;
// FIXME: UTF-8 sequences
int left = strlen (message);
while (left)
// Attempt to split the message if it doesn't completely fit into
// a single IRC protocol message while trying not to break UTF-8.
// Unicode can still end up being wrong, though.
// TODO: at least try to word-wrap if nothing else
for (int message_left = strlen (message); message_left; )
{
int part = MIN (one_message, left);
if (!one_message)
part = left;
struct str m;
str_init (&m);
irc_send (ctx, "PRIVMSG %s :%.*s", target, part, message);
int part_left = MIN (space_in_one_message, message_left);
if (!space_in_one_message)
part_left = message_left;
bool empty = true;
while (true)
{
const char *next = utf8_next (message, message_left);
hard_assert (next);
int char_len = message - next;
if (char_len > part_left)
break;
str_append_data (&m, message, char_len);
message += char_len;
message_left -= char_len;
empty = false;
}
if (empty)
{
// Well, that's just weird
buffer_send_error (ctx, buffer, "%s",
"Message splitting was unsuccessful as there was "
"too little room for UTF-8 characters");
message_left = 0;
}
irc_send (ctx, "PRIVMSG %s :%s", target, m.str);
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
ctx->irc_user->nickname, NULL, "%.*s", part, message);
left -= part;
message += part;
ctx->irc_user->nickname, NULL, "%s", m.str);
str_free (&m);
}
}