почему IsSingleByte Encoding использует GetByteCount для кодирования - PullRequest
2 голосов
/ 10 апреля 2011

Я проверил метод GetByteCount в AsciiEncoding. Это делает длинные вычисления, а не возвращает String.Length. Это не имеет никакого смысла для меня. У вас есть идея, почему?

Ответы [ 3 ]

3 голосов
/ 10 апреля 2011

РЕДАКТИРОВАТЬ: Я только что попытался воспроизвести это, и я не могу в настоящее время заставить ASCIIEncoding вместо того, чтобы иметь другую замену.Вместо этого я должен был бы использовать Encoding.GetEncoding, чтобы получить изменяемый.Так что для ASCIIEncoding я согласен ... но для других реализаций, где IsSingleByte возвращает true, у вас все еще может быть потенциальная проблема ниже.


Подумайте о попытке получить количество байтов строки, которая не просто содержит символы ASCII.Кодирование должно учитывать EncoderFallback, что может делать любое количество вещей, в том числе увеличивать счет на неопределенную величину.

Это может быть оптимизировано для случаягде резервный кодер является "значением по умолчанию", которое просто заменяет не-ASCII символы на "?"хотя.


Дальнейшее редактирование: я только что попытался перепутать это с суррогатной парой, надеясь, что она будет представлена ​​одним знаком вопроса.К сожалению, нет:

string text = "x\ud800\udc00y";
Console.WriteLine(text.Length); // Prints 4
Console.WriteLine(Encoding.ASCII.GetByteCount(text)); // Still prints 4!
1 голос
/ 10 апреля 2011

Для многобайтовой кодировки символов, такой как UTF8, этот метод имеет смысл, поскольку символы хранятся в 1-6 байтах. Я предполагаю, что этот метод также применяется для кодирования с фиксированным размером, такого как ASCII, где каждый символ хранится с 7 битами. Однако в реальной реализации "aaaaaaaa" будет составлять 8 байтов, поскольку символы в ASCII хранятся в 1 байте (8 бит), поэтому lenght hack будет работать в лучшем случае.

Предыдущие версии .NET Framework допускали подделку, игнорируя 8-й бит. Текущая версия была изменена, так что не кодовые точки ASCII отступают во время декодирования байтов.
Источник: MSDN

Я понимаю ваш вопрос как: Does worst case scenario exist for lenght hack?

        Encoding ae = Encoding.GetEncoding(
              "us-ascii",
              new EncoderReplacementFallback("[lol]"),
              new DecoderReplacementFallback("[you broke Me]"));

        Console.WriteLine(ae.GetByteCount("õäöü"));

Это вернет 20 в виде строки "õäöü" содержит 4 символа, все из которых выходят за пределы "us-ascii" набора символов ( U + 0000 до U + 007F .) , поэтому после кодировщика текст будет "[lol][lol][lol][lol]".

1 голос
/ 10 апреля 2011

Интересно, что моно среда выполнения , похоже, не включает такое поведение :

// Get the number of bytes needed to encode a character buffer.
public override int GetByteCount (char[] chars, int index, int count)
{
    if (chars == null) {
        throw new ArgumentNullException ("chars");
    }
    if (index < 0 || index > chars.Length) {
        throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
    }
    if (count < 0 || count > (chars.Length - index)) {
        throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
    }
    return count;
}

// Convenience wrappers for "GetByteCount".
public override int GetByteCount (String chars)
{
    if (chars == null) {
        throw new ArgumentNullException ("chars");
    }
    return chars.Length;
}

и далее вниз

[CLSCompliantAttribute(false)]
[ComVisible (false)]
public unsafe override int GetByteCount (char *chars, int count)
{
    return count;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...