Вопрос пользователя связан с извлечением UTF-16 символов из массива байтов в средах разработки Free Pascal и Delphi. Пользователь имеет массив из 1000 байтов и хочет извлечь из него только те символы, которые могут представлять собой имя файла, не зная точно, где эти символы начинаются и заканчиваются в массиве.
Решение проблемы:
Для решения задачи пользователя необходимо написать функцию, которая будет последовательно проверять каждый блок байтов в массиве на принадлежность к UTF-16 кодировке. UTF-16 может использовать как 2 байта, так и 4 байта на символ, в зависимости от диапазона кодовой точки. Важно учитывать, что некоторые кодовые точки (D800-DBFF) требуют последующего 2-байтового символа (DC00-DFFF) для формирования полноценного символа Unicode.
Пример кода на Object Pascal (Delphi):
program ExtractUTF16Chars;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
function IsValidUTF16Char(High, Low: Word): Boolean;
begin
Result := (High >= $D800) and (High <= $DBFF);
if Result then
Result := (Low >= $DC00) and (Low <= $DFFF);
end;
function ExtractUTF16Strings(const Buffer: array of Byte; Length: Integer): TStringList;
var
I, J: Integer;
High, Low: Word;
Char: Char;
begin
Result := TStringList.Create;
I := 0;
while (I <= Length - 2) do
begin
Low := Buffer[I];
Inc(I);
High := Buffer[I];
Inc(I);
if not IsValidUTF16Char(High, Low) then
begin
// Проверяем, является ли пара байтов валидным 16-битным словом
if (Low >= $00) and (Low <= $7F) then
begin
// 7-битный символ
Result.Add(Char(Low));
end
else if (Low & $C0) = $80 then
begin
// 11-битный символ, начальный байт
// Пропускаем, так как требуется минимум 2 байта для кодировки
end
else
begin
// 16-битный символ
if High = $FEFF then // Byte Order Mark (BOM)
Continue; // Пропускаем BOM
if High & $FC = $FC then // 2-байтовый символ
begin
// Проверяем, что следующий байт следует за первым в правильном порядке (big-endian или little-endian)
if Low & $C0 = $80 then
Continue; // Пропускаем, так как следующий байт не валиден для 16-битного слова
// Преобразуем в Unicode символ
if not IsValidUTF16Char(High, Low) then
Result.Add((High shl 8) + Low);
end
else if High & $F8 = $F0 then // 3-байтовый символ
begin
// Пропускаем, так как 3-байтовые символы не поддерживаются в UTF-16
Continue;
end
else if High & $FF = $BF then // 4-байтовый символ
begin
// Проверяем, что следующие 2 байта следуют за первым в правильном порядке
Low := Buffer[I]; Inc(I); // Третий байт
High := Buffer[I]; Inc(I); // Четвёртый байт
if not ((Low & $FC = $FC) and (IsValidUTF16Char(Low, High))) then
Continue; // Пропускаем, если третий и четвёртый байты не валидны
// Преобразуем в Unicode символ
Result.Add((((High shl 8) + Low) - 0x800) shl 10) + (High shl 8) + Low;
end;
end;
end;
end;
Result.DuplicateStrings := False;
end;
var
Buffer: array[0..1000] of Byte;
i, j: Integer;
FileNames: TStringList;
begin
// Предполагаем, что Buffer уже заполнен данными
FileNames := ExtractUTF16Strings(Buffer, Length(Buffer));
for j := 0 to FileNames.Count - 1 do
Writeln(FileNames[j]);
FileNames.Free;
Readln;
end.
Этот код демонстрирует функцию ExtractUTF16Strings, которая принимает массив байтов и его длину, и возвращает список строк, содержащих только UTF-16 символы. Функция IsValidUTF16Char используется для проверки, является ли пара байтов частью суррогатной пары в UTF-16. Функция учитывает различные случаи кодировки UTF-16, включая BOM и возможные невалидные последовательности байтов.
Подтвержденный ответ:
Пользователь может использовать представленный код для извлечения UTF-16 символов из массива байтов. Код проверяет каждый блок байтов на принадлежность к валидным UTF-16 символам и собирает их в список строк. Пользователю необходимо будет адаптировать код под свои нужды, например, если известны начальные и конечные метки для имен файлов, это можно использовать для более точного извлечения.
Пользователь задаёт вопрос о том, как извлечь из массива байтов символы, представляющие собой имена файлов, используя кодировку UTF-16, без точного знания их начальных и конечных позиций в массиве.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.