internal string ReadCodedStringInternal(IBinaryReader reader, int? maxLength) { StringBuilder sb = new StringBuilder(); int count = 0; for (count = 0; (!maxLength.HasValue) || (maxLength.HasValue && count < maxLength);) { // Check for custom codes ushort peek = reader.PeekUShort(); byte upper = (byte)((peek >> 8) & 0xFF); if (upper == 0xEF) { // Custom code with one-byte argument inline reader.ReadByte(); byte arg = reader.ReadByte(); count++; sb.Append($"[EF{arg:X2}]"); } else if (peek == 0xFEFF) { // Custom code (hot springs) with two-byte argument following reader.ReadShort(); ushort arg = reader.ReadUShort(); count += 2; sb.Append($"[HOTSPRING {arg:X4}]"); } else { ControlCode code = ProcessChar(reader, sb, ref count); if (code != null && code.Flags.HasFlag(ControlCodeFlags.Terminate)) { break; } } } // Advance the position past the end of the string if applicable while (maxLength.HasValue && count++ < maxLength) { reader.ReadShort(); } return sb.ToString(); }