using System; using System.Buffers.Binary; namespace AcDream.Core.Net.Messages; /// /// Shared reader for the AC String16L wire format used by every /// inbound and outbound chat / name / message body. /// /// /// Wire shape: /// /// u16 length // byte count, NOT char count /// byte[] text // CP1252-encoded bytes, no terminator /// pad to 4-byte boundary /// /// /// /// /// Codec is Windows-1252 (CP1252), matching retail and holtburger's /// encoding_rs::WINDOWS_1252. Registration of the /// CodePagesEncodingProvider is handled by /// . /// /// internal static class StringReader { /// /// Read a String16L from at , /// advancing past the length, body, and 4-byte /// alignment padding. Throws on truncation. /// public static string ReadString16L(ReadOnlySpan source, ref int pos) { if (source.Length - pos < 2) throw new FormatException("truncated String16L length"); ushort length = BinaryPrimitives.ReadUInt16LittleEndian(source.Slice(pos)); pos += 2; if (source.Length - pos < length) throw new FormatException("truncated String16L body"); string result = Encodings.Windows1252.GetString(source.Slice(pos, length)); pos += length; int recordSize = 2 + length; int padding = (4 - (recordSize & 3)) & 3; pos += padding; return result; } }