Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 TEncoding и его потомки  [new]
Праздный интерес
Guest
Может кто-нибудь на пальцах объяснить откуда взялись формулы в следующих методах:
function TUTF8Encoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * 3;
end;

function TUnicodeEncoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * 2;
end;

function TUTF7Encoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount * 3) + 2;
end;

function TMBCSEncoding.GetMaxByteCount(CharCount: Integer): Integer;
begin
  Result := (CharCount + 1) * FMaxCharSize;
end;

Я могу понять только формулу в TUTF7Encoding, происхождение остальных для меня является загадкой.
Скопировано из XE7, возможно в других версиях другие формулы.
4 окт 17, 18:05    [20843182]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9501
Какие вопросы ставил перед собой и как на них отвечал ?
Или вопросы не ставил, в виду ..., и ответ праздо нужен ?
4 окт 17, 18:26    [20843234]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
alekcvp
Member

Откуда:
Сообщений: 403
Dmitry Arefiev,

Вот, кстати, мне тоже стало [праздно] интересно, откуда взялись первая и третья формулы?.. :)
(автор темы не я)
4 окт 17, 19:24    [20843362]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
alekcvp, можете глянуть на комментарии в дотнете
UTF8
        public override int GetMaxByteCount(int charCount)
        {
            if (charCount < 0)
               throw new ArgumentOutOfRangeException("charCount",
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.EndContractBlock();

            // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
            long byteCount = (long)charCount + 1;

            if (EncoderFallback.MaxCharCount > 1)
                byteCount *= EncoderFallback.MaxCharCount;

            // Max 3 bytes per char.  (4 bytes per 2 chars for surrogates)
            byteCount *= 3;

            if (byteCount > 0x7fffffff)
                throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));

            return (int)byteCount;
        }


UTF7
        public override int GetMaxByteCount(int charCount)
        {
            if (charCount < 0)
               throw new ArgumentOutOfRangeException("charCount",
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.EndContractBlock();

            // Suppose that every char can not be direct-encoded, we know that
            // a byte can encode 6 bits of the Unicode character.  And we will
            // also need two extra bytes for the shift-in ('+') and shift-out ('-') mark.
            // Therefore, the max byte should be:
            // byteCount = 2 + Math.Ceiling((double)charCount * 16 / 6);
            // That is always <= 2 + 3 * charCount;
            // Longest case is alternating encoded, direct, encoded data for 5 + 1 + 5... bytes per char.
            // UTF7 doesn't have left over surrogates, but if no input we may need an output - to turn off
            // encoding if MustFlush is true.

            // Its easiest to think of this as 2 bytes to turn on/off the base64 mode, then 3 bytes per char.
            // 3 bytes is 18 bits of encoding, which is more than we need, but if its direct encoded then 3
            // bytes allows us to turn off and then back on base64 mode if necessary.

            // Note that UTF7 encoded surrogates individually and isn't worried about mismatches, so all
            // code points are encodable int UTF7.
            long byteCount = (long)charCount * 3 + 2;

            // check for overflow
            if (byteCount > 0x7fffffff)
                throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));

            return (int)byteCount;
        }
4 окт 17, 20:04    [20843457]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Праздный интерес
Guest
white_nigger
alekcvp, можете глянуть на комментарии в дотнете
UTF8

Прочитал комментарии для UTF8 в дотнете и так и не понял почему 1 символ максимально занимает 6 байт, в то время как сейчас по стандарту максимальный размер одного символа 4 байта в UTF8. Если отталкиваться от UTF16 (с суррагатными парами, которые расширяют интервал до 20бит), то 1 символ всегда занимает 3 байта и только если это суррогатная пара - то 4 байта, но суррогатная пара это уже 2 символа, которые будут занимать 6 байт если это будут не суррогатные символы. Т.е. TUTF8Encoding.GetMaxByteCount всегда возвращает длину на 3 байта больше чем может быть в реальности. Если же отталкиваться от UTF32, то функция возвращает всегда меньше чем может занимать строка в реальности.
5 окт 17, 16:18    [20845866]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 726
Праздный интерес,

В Википедии же всё написано
https://ru.wikipedia.org/wiki/UTF-8

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
5 окт 17, 16:23    [20845883]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Праздный интерес
Guest
Няшик,

Именно википедией и пользовался, вот только в моих расчетах максимальный размер строки в байтах получается иной чем (CharCount + 1) * 3.

ориентируемся на UTF16:
1 символ - всегда 3 байта (16 бит - 3 байта), суррогатная пара на то и суррогатная в 1 символ не вмещается
2 символа - либо 6 байт, для простых символов, либо 4, если суррогатная пара

как можно заметить расчет по формуле всегда дает максимальны размер на 3 байта длиннее.

ориентируемся на UTF32:
1 символ - 6 байт, но это не точно, ведь это только для 31бита
2 символа - 12 байт

по формуле только размер 1 символа совпадает, дальше же он с каждым разом все больше и больше отстаёт.

Я прошу показать где я ошибся в расчетах.
5 окт 17, 16:55    [20845991]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
MKZM
Member

Откуда:
Сообщений: 5136
А в чем проблема?
5 окт 17, 17:04    [20846036]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
s62
Member

Откуда: Жуковский
Сообщений: 686
Праздный интерес,
в тексте с .NET этого нет, но может дело в BOM. 3 байта для UTF8, 2 байта для UTF-16. Как раз получается, как в функциях.
5 окт 17, 17:10    [20846070]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
Праздный интерес
Няшик,
ориентируемся на UTF16:
1 символ - всегда 3 байта (16 бит - 3 байта), суррогатная пара на то и суррогатная в 1 символ не вмещается
2 символа - либо 6 байт, для простых символов, либо 4, если суррогатная пара
Месье надо подтянуть матчасть
Суррогатная пара - это и есть ОДИН символ, который в UTF16 кодируется четырьмя байтами (два WideChar), а в UTF8 шестью байтами
5 окт 17, 18:06    [20846209]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 2426
white_nigger
Суррогатная пара - это и есть ОДИН символ, который в UTF16 кодируется четырьмя байтами (два WideChar), а в UTF8 шестью байтами

Суррогатная пара и в UTF-8 кодируется четырьмя байтами (максимальный кодпоинт юникода 10FFFF). Теоретически схема кодирования UTF-8 допускает 6-байтовые последовательности, но стандартом закреплены только 4-байтовые максимум.
5 окт 17, 19:20    [20846351]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
Kazantsev Alexey
Суррогатная пара и в UTF-8 кодируется четырьмя байтами (максимальный кодпоинт юникода 10FFFF). Теоретически схема кодирования UTF-8 допускает 6-байтовые последовательности, но стандартом закреплены только 4-байтовые максимум
Ну так мелкомягкие и пишут интересно:
сначала "Characters would be # of characters + 1 in case left over high surrogate", что их может быть два, а потом
не парясь " Max 3 bytes per char."
Хотя и замечают, как ты сказал "(4 bytes per 2 chars for surrogates)"

Я так понимаю, что никто не парится, раз допускается - значит max считают = 6
5 окт 17, 19:49    [20846390]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
alekcvp
Member

Откуда:
Сообщений: 403
white_nigger
Я так понимаю, что никто не парится, раз допускается - значит max считают = 6

Нет, они не парятся и за Max считают = 3...
5 окт 17, 19:55    [20846398]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 2426
white_nigger
Я так понимаю, что никто не парится, раз допускается - значит max считают = 6

Я не понял из чего ты делаешь вывод о 6. У них, как раз, расчёт делается на то что, один кодпоинт из BMP это всегда 3 байта, а суррогатная пара представленная двумя такими кодпоинтами и кодирующаяся 4 байтами по любому влезет в 6 байт для двух обычных кодпоинтов.

// Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback

Вот это, мне кажется, вообще ошибка. Тут, насколько я понимаю, говорится о возможном наличии одиночного старшего суррогата в конце строки (разделённая суррогатная пара) из-за чего будет задействоваться фолбек, который, как они считают (судя по комментарию), всегда 3 байта.
Но тут возникает пара вопросов:
1. Если max fallback принят за 3 байта (а дефолтный replacement char в UTF-8 представляется именно 3 байтами), то нафига делать +1, ведь и нормальный кодпоинт из BMP по максимуми кодируется 3 байтами.
2. Какого фига max fallback принят за 3 байта, когда EncoderReplacementFallback можно инициализировать любой строкой, и он будет возвращать столько байт сколько хочется.
В общем, или это ошибка или я не понимаю механизм работы фолбека в дотнете.

p.s. Ну а дельфийские енкодерописатели тупо собезьянили дотнетовский код, вот и всё объяснение (потеряв фолбеки по пути).
5 окт 17, 20:15    [20846421]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
Kazantsev Alexey
Я не понял из чего ты делаешь вывод о 6

Думаю чтобы полностью кодировать UCS-4
Kazantsev Alexey
p.s. Ну а дельфийские енкодерописатели тупо собезьянили дотнетовский код, вот и всё объяснение (потеряв фолбеки по пути).
Именно! (аналоги фолбеков пришлось писать для нашего рича)
PS:
Юникодная таблица вещь весьма непостоянная. Если в неё добавляют таккую хню как алхимические символы, то возможно когда-нить будет мало диаппазона 0-10FFFF
5 окт 17, 20:35    [20846465]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
А может и правда MS облажалась, а не думала о совместимости с будущим UNICODE и максимально возможной последовательности для UTF8
5 окт 17, 20:41    [20846477]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 2426
white_nigger
Думаю чтобы полностью кодировать UCS-4

UCS-4 это та же UTF-32, то есть форма представления юникода, а он ограничен 0-10FFFF.

white_nigger
Именно! (аналоги фолбеков пришлось писать для нашего рича)

Аналогичная фигня...

white_nigger
то возможно когда-нить будет мало диаппазона 0-10FFFF

Это вряд ли. UTF-16 не сможет кодировать всё что выше этого, а на неё слишком много всего завязано.
5 окт 17, 20:47    [20846487]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
И всё таки они убеждены
MaxByteSequenceLen = 6; // max bytes per character
Это из реализации ридера Xml .NET Framework
5 окт 17, 20:55    [20846492]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 2426
white_nigger
MaxByteSequenceLen = 6; // max bytes per character

Которая, если верить рефлектору, нигде не используется :)
5 окт 17, 21:07    [20846509]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 2426
Kazantsev Alexey
...если верить рефлектору

Хотя, это же константа...
5 окт 17, 21:20    [20846524]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
Kazantsev Alexey
Которая, если верить рефлектору, нигде не используется :)
Фи.. рефлектор.. Проще в репозитории, в сырцах глянуть. Там используется в паре мест в методе ReadData
5 окт 17, 21:27    [20846537]     Ответить | Цитировать Сообщить модератору
 Re: TEncoding и его потомки  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1537
Короче предлагаю оставить это на их совести и продолжать с этим жить
5 окт 17, 21:29    [20846541]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить