55 lines
2.2 KiB
C#
55 lines
2.2 KiB
C#
using System.Globalization;
|
|
|
|
namespace WxAgent.Core;
|
|
|
|
public static class WechatTextInput
|
|
{
|
|
public const int MaxSegmentLength = 4000;
|
|
public const int MaxTextLength = 20_000;
|
|
|
|
public static string Prepare(string text)
|
|
{
|
|
var normalized = PrepareLongText(text);
|
|
if (normalized.Length > MaxSegmentLength)
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, $"Message text must not exceed {MaxSegmentLength} characters.");
|
|
return normalized;
|
|
}
|
|
|
|
public static string PrepareLongText(string text)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "Message text must not be empty.");
|
|
var normalized = text.ReplaceLineEndings("\n");
|
|
if (normalized.Length > MaxTextLength || normalized.Any(character => char.IsControl(character) && character is not ('\n' or '\t')))
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, $"Message text must not exceed {MaxTextLength} characters or contain unsupported control characters.");
|
|
return normalized;
|
|
}
|
|
|
|
public static IReadOnlyList<string> SplitForSend(string text)
|
|
{
|
|
var normalized = PrepareLongText(text);
|
|
if (normalized.Length <= MaxSegmentLength)
|
|
return [normalized];
|
|
|
|
var textElementStarts = StringInfo.ParseCombiningCharacters(normalized);
|
|
var segments = new List<string>();
|
|
var start = 0;
|
|
while (start < normalized.Length)
|
|
{
|
|
var end = Math.Min(start + MaxSegmentLength, normalized.Length);
|
|
if (end < normalized.Length)
|
|
{
|
|
var boundaryIndex = Array.BinarySearch(textElementStarts, end);
|
|
if (boundaryIndex < 0) boundaryIndex = ~boundaryIndex - 1;
|
|
if (boundaryIndex < 0 || textElementStarts[boundaryIndex] <= start)
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "A text element exceeds the per-message length limit.");
|
|
end = textElementStarts[boundaryIndex];
|
|
}
|
|
|
|
segments.Add(normalized[start..end]);
|
|
start = end;
|
|
}
|
|
return segments;
|
|
}
|
|
}
|