Как стать автором
Обновить

Комментарии 38

Мне кажется, что для полноты картины не хватает эксперимента с использованием словаря (Dictionary<key,value>).
вы это серьезно? switch — это жутко оптимизированный, предсгенерированный dictionary
(Вы меня немного не так поняли. я ответил ниже)
А если по поводу еще большей оптимизации, тогда использование массива вместо switch:
char[] utf8 = new {'\u0000','\u0001'… '\u02D9'};

sb[i] = utf8[bytes[i + start]];

разве не скажется положительно на производительности?
Ой. Немного выпал из темы. Это уже было.
Если это не сарказм, то очевидно что в случае со словарём мы получим ещё более низкие результаты ;)
Я же не говорил, что словарь будет быстрее. =)
«Для полноты картины» — Я имел ввиду именно для сравнения.
      var charArray = new char[count];

      for (int i = start, c = 0; c < count; c++, i++)
        charArray[c] = chars[bytes[i]];

      return new string(charArray);


* This source code was highlighted with Source Code Highlighter.


имхо это будет работать быстрее, chars — это массив из первого примера
да, действительно работает быстрее (примерно раза в полтора). к сожалению, обратное преобразование в байты придётся оставить на switch-е
Для latin1 еще можно попробовать
var chars = new char[bytes.Length];
Array.Copy(bytes, chars, bytes.Length);
return new string(chars);
сейчас попробую вынести latin1 и us-ascii (то же самое, только первые 128 символов) в специальные случаи
Уж не знаю почему (нет времени докапываться до истины), но Array.Copy отрабатывает даже медленнее StringBuilder’a
для таких копирований есть System.Buffer BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count);

а вообще если вы хотите так сделать то правильнее будет задействовать конструктор с char*, если вам позволят
Buffer.BlockCopy не умеет приводить типы, так что для перевода из байтов в чары от него пользы мало.

А в Silverlight unsafe-инструкции запрещены, насколько я помню.
да, фокус с буфером не пройдет. забыл что чары двухбайтовые
Вероятно, потому, что боксирует байты, приводит к IConvertible и переводит в чары :)
НЛО прилетело и опубликовало эту надпись здесь
Тема понравилась, но она все же скорее относится к ".NET", а не к «Silverlight».
Для latin1 вроде можно же просто sb[i] = (char) bytes[i+offset] написать.
Для cp1251 символы до 128 тоже прямое соответствие имеют, для остальных нужно прописывать коды символов.
Для 1251 примерно такой изврат выходит, дальше думать лениво :)
    public static string GetString(byte[] bytes, int offset, int length)
    {
      if (bytes == null)
        throw new ArgumentNullException("bytes");
      if (offset < 0 || offset >= bytes.Length)
        throw new ArgumentException("offset");
      if (length < 0 || offset + length > bytes.Length)
        throw new ArgumentException("length");

      var sb = new char[length];
      length += offset;
      
      for (var i = offset; i < length; i++)
      {
        byte b = bytes[i];
        if (b < 128)
        {
          sb[i] = (char)b;
        }
        else if (b >= 192)
        {
          sb[i] = (char)(848 + b);
        }
        else
        {
          switch (b)
          {
            case 128: sb[i] = '\u0402'; break;
            case 129: sb[i] = '\u0403'; break;
            case 130: sb[i] = '\u201A'; break;
            case 131: sb[i] = '\u0453'; break;
            case 132: sb[i] = '\u201E'; break;
            case 133: sb[i] = '\u2026'; break;
            case 134: sb[i] = '\u2020'; break;
            case 135: sb[i] = '\u2021'; break;
            case 136: sb[i] = '\u20AC'; break;
            case 137: sb[i] = '\u2030'; break;
            case 138: sb[i] = '\u0409'; break;
            case 139: sb[i] = '\u2039'; break;
            case 140: sb[i] = '\u040A'; break;
            case 141: sb[i] = '\u040C'; break;
            case 142: sb[i] = '\u040B'; break;
            case 143: sb[i] = '\u040F'; break;
            case 144: sb[i] = '\u0452'; break;
            case 145: sb[i] = '\u2018'; break;
            case 146: sb[i] = '\u2019'; break;
            case 147: sb[i] = '\u201C'; break;
            case 148: sb[i] = '\u201D'; break;
            case 149: sb[i] = '\u2022'; break;
            case 150: sb[i] = '\u2013'; break;
            case 151: sb[i] = '\u2014'; break;
            case 152: sb[i] = '\u0098'; break;
            case 153: sb[i] = '\u2122'; break;
            case 154: sb[i] = '\u0459'; break;
            case 155: sb[i] = '\u203A'; break;
            case 156: sb[i] = '\u045A'; break;
            case 157: sb[i] = '\u045C'; break;
            case 158: sb[i] = '\u045B'; break;
            case 159: sb[i] = '\u045F'; break;
            case 160: sb[i] = '\u00A0'; break;
            case 161: sb[i] = '\u040E'; break;
            case 162: sb[i] = '\u045E'; break;
            case 163: sb[i] = '\u0408'; break;
            case 164: sb[i] = '\u00A4'; break;
            case 165: sb[i] = '\u0490'; break;
            case 166: sb[i] = '\u00A6'; break;
            case 167: sb[i] = '\u00A7'; break;
            case 168: sb[i] = '\u0401'; break;
            case 169: sb[i] = '\u00A9'; break;
            case 170: sb[i] = '\u0404'; break;
            case 171: sb[i] = '\u00AB'; break;
            case 172: sb[i] = '\u00AC'; break;
            case 173: sb[i] = '\u00AD'; break;
            case 174: sb[i] = '\u00AE'; break;
            case 175: sb[i] = '\u0407'; break;
            case 176: sb[i] = '\u00B0'; break;
            case 177: sb[i] = '\u00B1'; break;
            case 178: sb[i] = '\u0406'; break;
            case 179: sb[i] = '\u0456'; break;
            case 180: sb[i] = '\u0491'; break;
            case 181: sb[i] = '\u00B5'; break;
            case 182: sb[i] = '\u00B6'; break;
            case 183: sb[i] = '\u00B7'; break;
            case 184: sb[i] = '\u0451'; break;
            case 185: sb[i] = '\u2116'; break;
            case 186: sb[i] = '\u0454'; break;
            case 187: sb[i] = '\u00BB'; break;
            case 188: sb[i] = '\u0458'; break;
            case 189: sb[i] = '\u0405'; break;
            case 190: sb[i] = '\u0455'; break;
            case 191: sb[i] = '\u0457'; break;
          }
        }
      }

      return new string(sb);
    }


* This source code was highlighted with Source Code Highlighter.
Причем, случай с кейсом будет достаточно редок.
как оказалось, практически все кодировки в первых 128 байтах именно такие
НЛО прилетело и опубликовало эту надпись здесь
А не проще было бы допилить код библиотеки, чтобы она использовала юникод? 2009 год на дворе, как-никак.
Как вы это себе представляете?
Если требовалось взять с клиентской машины уже имеющийся там (и судя по всему созданный довольно давно файл), и прочитать контент в браузере.
Как я понимаю, исходный текст библиотеки у вас есть…
Если проблема состоит в вычитке файла с клиента в старой кодировке, тогда, конечно, это не поможет и придется писать перекодировку самому.
проблема именно в том, что входные файлы в старой кодировке.
iconv -i cp1251 -f UTF-8 file > file8 религия сделать не позволила…
ну да, как вы представляете такой вариант: хочет пользователь воспользоваться нашим сервисом, а мы ему в ответ: «а фиг тебе, сначала скачай иконв, а потом отконвертируй файлы сам»
Зачем качать иконв, когда он уже есть :)

Я так понял, что там у клиента какая-то прога, так вот туда перекодировщик нельзя было встроить?
вы вообще похоже не в теме…
Silverlight у нас где исполняется? иконв там по-умолчанию есть?
Я забыл поставить тег ирония.

Не верю, что в таком огромной дотнете нет программы перевода из одной кодировки в другую.
ссылку в начале поста посмотрите
Червёртая ссылка в гугле на запрос «c# codepage conversion» выдёт msdn:

msdn.microsoft.com/ru-ru/library/cc488003.aspx

Класс system.encoding, как это не было бы странно.
вы почитайте внимательно первый абзац и поймите суть проблемы прежде чем давать дурацкие ответы.
Тогда остаётся посочувствовать ёжикам.
Ещё есть дополненное руководство: Java: Русские буквы и не только.... Оно расширяет область применения ранее описанных решений на фреймворки Java.
Спасибо! Удобнее было бы только генерить сразу BCL Encoding, т.к. нехватает всего пары строк, да и использовать его, например в StreamReader можно будет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории