Comments 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 и переводит в чары :)
UFO landed and left these words here
Тема понравилась, но она все же скорее относится к ".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 байтах именно такие
UFO landed and left these words here
А не проще было бы допилить код библиотеки, чтобы она использовала юникод? 2009 год на дворе, как-никак.
Как вы это себе представляете?
Если требовалось взять с клиентской машины уже имеющийся там (и судя по всему созданный довольно давно файл), и прочитать контент в браузере.
Как я понимаю, исходный текст библиотеки у вас есть…
Если проблема состоит в вычитке файла с клиента в старой кодировке, тогда, конечно, это не поможет и придется писать перекодировку самому.
проблема именно в том, что входные файлы в старой кодировке.
ну да, как вы представляете такой вариант: хочет пользователь воспользоваться нашим сервисом, а мы ему в ответ: «а фиг тебе, сначала скачай иконв, а потом отконвертируй файлы сам»
Зачем качать иконв, когда он уже есть :)

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

Не верю, что в таком огромной дотнете нет программы перевода из одной кодировки в другую.
вы почитайте внимательно первый абзац и поймите суть проблемы прежде чем давать дурацкие ответы.
Спасибо! Удобнее было бы только генерить сразу BCL Encoding, т.к. нехватает всего пары строк, да и использовать его, например в StreamReader можно будет.
Only those users with full accounts are able to leave comments. Log in, please.