Форум: "Прочее";
Текущий архив: 2014.09.14;
Скачать: [xml.tar.bz2];
ВнизРазбираемся в кодировках Найти похожие ветки
← →
DevilDevil © (2014-01-30 17:03) [80]> Вот тут примерно то же самое
> http://blog.barrkel.com/2010/09/virtual-method-interception.html
понятно
← →
DevilDevil © (2014-01-30 17:18) [81]Ребят, это полный ахтунг!!!!!!!!!!!
Под ведроидом не то что Utf8String нет, там ни AnsiString нет, ни даже AnsiChar
как так?
что за фигня?
← →
Kerk © (2014-01-30 17:20) [82]Доброе утро. Ты в спячке чтоль был? Там один тип строк - string, он же UnicodeString.
Для всего остального есть TBytes.
← →
Kerk © (2014-01-30 17:22) [83]Предупреждая следующий шок - строки на андроиде и ios индексируются не с единицы, а с нуля.
← →
Kerk © (2014-01-30 17:22) [84]Короче вот тебе слайды (минутка самопиара:)
http://www.slideshare.net/VLDCORP/ios-android-delphi
← →
DVM © (2014-01-30 17:36) [85]
> DevilDevil © (30.01.14 17:02) [79]
> И функционала как "зарегистрировать" кодировку - просто
> нет
Достаточно наследников насоздавать от TEncoding и все. В принципе даже и в TEncoding можно добавить недостающие поля - class helper можно сделать.
> Код GetBufferEncoding заточен только на UTF8, UCS2 и UCSbe
Метод виртуальный же
← →
DVM © (2014-01-30 17:39) [86]
> Kerk © (30.01.14 17:20) [82]
А указатели там есть, надеюсь?
← →
Kerk © (2014-01-30 17:46) [87]Есть указатели, куда они денутся.
← →
DevilDevil © (2014-01-30 17:50) [88]Я в шоке по нескольким причинам
Настолько подавлен, что не могу структурированно изложить мысли
Но сейчас постараюсь
1) Кроссплатформ RAD Studio - гуд
2) Мобильное направление RAD Studio - вэри гуд
3) Slow compile and big binary size - вэри бэд
4) Кинул на форму Memo и пару кнопок. По нажатию одной кнопки сделал Memo1.Lines.Text := "Тестовая строка". Запустил, поиграл пару секунд, получил Exception. Это полный п.
5) Рассогласованность компиляторов на уровне типов и доступа к строкам - это полное зло
6) Полный отказ от поддержки не-UCS2 строк бессмыслен
7) Подсчёт ссылок - подход привлекательный, но надеюсь его уберут
8) Мне на 55% нравится, куда идёт Эмбар. Но есть вещи, которые бьют меня прямо в сердце
P.S. я думал в RTL всё сводится к UnicodeString, но поддержка сохраняется. Оказалось нет. Про остальное знал. А презентация действительно хорошая!
← →
DevilDevil © (2014-01-30 17:52) [89]> Метод виртуальный же
class function static
> Достаточно наследников насоздавать от TEncoding и все. В
> принципе даже и в TEncoding можно добавить недостающие поля
> - class helper можно сделать.
Memo1.Lines.LoadFromFile() в конечном счёте вызывает TEncoding.GetBufferEncoding, с которым ты уже ничего не сделаешь
← →
DVM © (2014-01-30 18:01) [90]
> DevilDevil © (30.01.14 17:52) [89]
> class function static
посмотрел, да, точно не виртуальный.
← →
Kerk © (2014-01-30 18:03) [91]
> Рассогласованность компиляторов на уровне типов и доступа
> к строкам - это полное зло
Пошли по пути Python"а. Там тоже 5 лет назад произошло то же самое. Ничем хорошим не закончилось, правда. До сих пор большинство на полностью юникодную версию не перешло. Посмотрим как это получится в Embarcadero.
Мне по большому счету пофиг, но не вижу причин почему было не оставить AnsiString, кому оно мешала-то.
> P.S. я думал в RTL всё сводится к UnicodeString, но поддержка
> сохраняется. Оказалось нет.
Юмор в том, что все наоборот. Глубоко внутри RTL есть разные типы строк, а снаружи только UnicodeString. В сети описывали хаки, позволяющие получить доступ к разным типам строк и из обычного кода.
← →
DVM © (2014-01-30 18:10) [92]
> DevilDevil © (30.01.14 17:52) [89]
> Memo1.Lines.LoadFromFile() в конечном счёте вызывает TEncoding.
> GetBufferEncoding, с которым ты уже ничего не сделаешь
GetBufferEncoding будет же вызываться только тогда, когда явно не указана кодировка, и он будет искать преамбулы для нескольких известных ему кодировок, пытаясь определить какая. Но если кодировка указана, то он будет использовать ее метод GetPreamble, который у каждой кодировки может быть свой. По-моему все нормально.
← →
DevilDevil © (2014-01-30 18:15) [93]посмотрел чем инициализируется DefaultSystemCodePage в ведроиде
1251 :)
блин, а где он инициализируется?
← →
vuk © (2014-01-30 18:54) [94]to Kerk © (30.01.14 18:03) [91]:
> Юмор в том, что все наоборот. Глубоко внутри RTL есть разные
> типы строк, а снаружи только UnicodeString. В сети описывали
> хаки, позволяющие получить доступ к разным типам строк и
> из обычного кода.
Напомнило старые добрые времена. Компилятор Delphi 1 умел собирать exe-шники под DOS, у Borland был RTL, но они его никому не давали, хотя сами пользовались. Но путем срещивания RTL от BP, Delphi 1 и некоторого ручного кодинга можно было получать вполне живущие приложения под DOS.
← →
ТНЕ картман (2014-01-30 19:52) [95]
> DevilDevil © (30.01.14 17:02) [79]
> Но вот беда
> Код GetBufferEncoding заточен только на UTF8, UCS2 и UCSbe
> И функционала как "зарегистрировать" кодировку - просто
> нет
предположу, что это сделано исключительно в целях уменьшения размера экзешника))
ЗЫ. если не затруднит, приведи пример чего-нибудь идеального.
← →
DevilDevil © (2014-01-30 21:21) [96]> DVM © (30.01.14 18:10) [92]
> GetBufferEncoding будет же вызываться только тогда, когда
> явно не указана кодировка, и он будет искать преамбулы для
> нескольких известных ему кодировок, пытаясь определить какая.
> Но если кодировка указана, то он будет использовать ее
> метод GetPreamble, который у каждой кодировки может быть
> свой. По-моему все нормально.
При всём уважении, не могу понять, зачем ты споришь. Этого функционала нет. Универсального подбора преамбулы для TEncoding нет. Базовые кодировки объявлены, но GetBufferEncoding их не проверяет. К тому же объявлены они как strict private и доступа к ним тоже нет. Складывается впечатление, что этот класс разрабатывал ты - и сейчас защищаешь свой труд от моих нападок. Слишком забавно :)
← →
DevilDevil © (2014-01-30 21:23) [97]> ТНЕ картман (30.01.14 19:52) [95]
Текущий вопрос - каким именно способом и где Delphi определяет DefaultSystemCodePage в не-Windows ОС.
Философствовать могут все, но это сейчас нужно меньше всего. Давай придерживаться объявленных вопросов. Если конечно тема кодировок тебе интересна
← →
ТНЕ картман (2014-01-30 21:48) [98]
> DevilDevil © (30.01.14 21:23) [97]
>
> > ТНЕ картман (30.01.14 19:52) [95]
>
> Текущий вопрос - каким именно способом и где Delphi определяет
> DefaultSystemCodePage в не-Windows ОС.
это у тебя он текущий, у меня же натек совсем другой: если человек вполне искренне считает верными два или более взаимоисключающих утверждения - следствием чего это может быть?
← →
DevilDevil © (2014-01-30 21:56) [99]Тогда создай другую ветку и не гадь в мою
← →
DVM © (2014-01-30 22:05) [100]
> DevilDevil © (30.01.14 21:21) [96]
> При всём уважении, не могу понять, зачем ты споришь. Этого
> функционала нет. Универсального подбора преамбулы для TEncoding
> нет. Базовые кодировки объявлены, но GetBufferEncoding их
> не проверяет.
Я тут не вижу предмета для спора. Я не понимаю о чем ты говоришь. Да, базовые кодировки объявлены. И GetBufferEncoding вызывает поочередно их метод GetPreamble, получая их преамбулу и сравнивает с тем что есть. Вот же. Проверяет все кодировки которые реализованы и которые имеют преамблу в принципе. Их всего 3 там таких:
if AEncoding = nil then
begin
// Find the appropraite encoding
if ContainsPreamble(Buffer, TEncoding.UTF8.GetPreamble) then
AEncoding := TEncoding.UTF8
else if ContainsPreamble(Buffer, TEncoding.Unicode.GetPreamble) then
AEncoding := TEncoding.Unicode
else if ContainsPreamble(Buffer, TEncoding.BigEndianUnicode.GetPreamble) then
AEncoding := TEncoding.BigEndianUnicode
else
begin
AEncoding := ADefaultEncoding;
Exit; // Don"t proceed just in case ADefaultEncoding has a Preamble
end;
Result := Length(AEncoding.GetPreamble);
end
Единственное, что плохо, так это то, что просто так не добавить в список кодировок, преамбула которых сравнивается с текущей еще свою собственную. Про преамбулу UTF-7 (которая тоже реализована) не забыли, а намеренно не стали делать, т.к. она не одна, а их четыре.
← →
DVM © (2014-01-30 22:25) [101]
> DevilDevil © (30.01.14 21:23) [97]
> > ТНЕ картман (30.01.14 19:52) [95]
>
> Текущий вопрос - каким именно способом и где Delphi определяет
> DefaultSystemCodePage в не-Windows ОС.
В модуле System.pas определена же функция
function GetACP: Cardinal;
Для Posix систем.
И соответственно DefaultSystemCodePage := GetACP;
← →
DevilDevil © (2014-01-30 22:44) [102]> DVM © (30.01.14 22:05) [100]
Давай рассуждать последовательно
1) TEncoding - неплохо спроектированный класс, предназначенный для разруливания ситуаций, связанных с переконвертированием кодировок, коих очень много
2) Теоретически поддерживаются чуть ли не все кодировки. И юникодовые, и Ansi, и OEM, и Маковские, и однобайтовые, и мультибайтовые... Причём поддерживать эти кодировки не сложно. TEncoding лишь является враппером над WideCharToMultibyte/libiconv/ICU.
3) Создание кодировок потокобезопасно и без блокировок (lock-free), что разумеется плюс
4) Для определения(создания) кодировки существует классовая функция GetBufferEncoding, которая анализирует BOM
5) Идентификация BOM происходит универсальным способом - путём вызова виртуальной функции GetPreamble() по каждой кодировке и её сравнения с буфером
6) Текстовые классы типа TStrings при загрузке из Stream/Файла вызывают универсальную TEncoding.GetBufferEncoding() - что правильно
7) Внутри класса уже объявлены ANSIEncoding, ASCIIEncoding, BigEndianUnicodeEncoding, UnicodeEncoding, UTF7Encoding, UTF8Encoding
8) BOM проверяется только по 3м из них. В то время как BOM может указывать и на ряд других кодировок:
http://ru.wikipedia.org/wiki/Маркер_последовательности_байтов
http://www.w3.org/TR/REC-xml/#sec-guessing
9) UTF-32, как и UTF-8, если не ошибаюсь, является стандартной кодировкой в POSIX. Но в классе TEncoding он не отражён
10) Не существует практической возможности "научить" TEncoding понимать другие BOM-ы
Bonus:
Я конечно не профи по UTF-7, но по моему его можно определить по последовательности 2B 2F 76
← →
DevilDevil © (2014-01-30 22:46) [103]> DVM © (30.01.14 22:25) [101]
> В модуле System.pas определена же функция
> function GetACP: Cardinal;
> Для Posix систем.
> И соответственно DefaultSystemCodePage := GetACP;
Хорошо если так
Меня сегодня по этой функции перенаправляли в Windows :)
Завтра посмотрю
Спасибо :)
← →
ТНЕ картман (2014-01-30 23:03) [104]
> 10) Не существует практической возможности "научить" TEncoding
> понимать другие BOM-ы
как это не существует?
← →
DVM © (2014-01-30 23:12) [105]
> DevilDevil ©
Ты я смотрю по всем фронтам атакуешь:
http://www.sql.ru/forum/1072968/razbiraemsya-v-kodirovkah
Кстати, вот может пригодится (TUTF32Encoding):
https://code.google.com/p/delphi-foundations/source/browse/trunk/Book/05.+String+handling/TEncoding/CCR.Encodings.pas?r=32
← →
DevilDevil © (2014-01-30 23:22) [106]> Ты я смотрю по всем фронтам атакуешь:
> http://www.sql.ru/forum/1072968/razbiraemsya-v-kodirovkah
Ну да :)
А что ещё остаётся :)
> Кстати, вот может пригодится (TUTF32Encoding):https://code.
> google.com/p/delphi-foundations/source/browse/trunk/Book/05.
> +String+handling/TEncoding/CCR.Encodings.pas?r=32
Неплохое решение
Но то, что там есть мне уже известно
Завтра по плану мучать ведроид и разбираться с UTF-7
Смысла его поддерживать особого нет. Но каприз у меня такой. Пока хочется
← →
DevilDevil © (2014-01-31 11:46) [107]Кстати про лок-фри
Как дифайнами определить, поддерживаются ли атомики типа AtomicCmpExchange?
← →
Kerk © (2014-01-31 12:33) [108]Что конкретно определять-то?
Версию компилятора?{$IF CompilerVersion >= XXX}
{$IFEND}
Винду?{$IFDEF MSWINDOWS}
{$ENDIF}
← →
DevilDevil © (2014-01-31 12:42) [109]А винда то здесь причём?
AtomicCmpExchange это интринсинк
По идее можно отталкиваться от версии компилятора, но какой?
Кроме того... в FPC есть этот интринсинк?
← →
DVM © (2014-01-31 13:21) [110]
> Кроме того... в FPC есть этот интринсинк?
есть, под всеми платформами есть.
← →
DevilDevil © (2014-01-31 14:13) [111]Круто
Осталось понять, с какой версии CompilerVersion они появились в Delphi :)
> DVM © (31.01.14 13:21) [110]
> есть, под всеми платформами есть.
Получается Emba спёрла из FPC?
Круто чё :)
А синтаксис то такой же?
← →
DVM © (2014-01-31 14:52) [112]
> DevilDevil © (31.01.14 14:13) [111]
> Получается Emba спёрла из FPC?
> Круто чё :)
Чего сперла? InterlockedXXX функции? Они там давным давно есть. Причем они есть как в Windows (в kernel32), так и самописные (TInterlocked).
Из FPC:
function InterLockedIncrement (var Target: longint) : longint; public name "FPC_INTERLOCKEDINCREMENT";
function InterLockedDecrement (var Target: longint) : longint; public name "FPC_INTERLOCKEDDECREMENT";
function InterLockedExchange (var Target: longint;Source : longint) : longint; public name "FPC_INTERLOCKEDEXCHANGE";
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; public name "FPC_INTERLOCKEDEXCHANGEADD";
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; public name "FPC_INTERLOCKEDCOMPAREEXCHANGE";
{$ifdef cpu64}
function InterLockedIncrement64 (var Target: int64) : int64; public name "FPC_INTERLOCKEDINCREMENT64";
function InterLockedDecrement64 (var Target: int64) : int64; public name "FPC_INTERLOCKEDDECREMENT64";
function InterLockedExchange64 (var Target: int64;Source : int64) : int64; public name "FPC_INTERLOCKEDEXCHANGE64";
function InterLockedExchangeAdd64 (var Target: int64;Source : int64) : int64; public name "FPC_INTERLOCKEDEXCHANGEADD64";
function InterlockedCompareExchange64(var Target: int64; NewValue: int64; Comperand: int64): int64; public name "FPC_INTERLOCKEDCOMPAREEXCHANGE64";
{$endif cpu64}
{ Pointer overloads }
{$ifdef cpu64}
function InterLockedIncrement (var Target: Pointer) : Pointer; external name "FPC_INTERLOCKEDINCREMENT64";
function InterLockedDecrement (var Target: Pointer) : Pointer; external name "FPC_INTERLOCKEDDECREMENT64";
function InterLockedExchange (var Target: Pointer;Source : Pointer) : Pointer; external name "FPC_INTERLOCKEDEXCHANGE64";
function InterLockedExchangeAdd (var Target: Pointer;Source : Pointer) : Pointer; external name "FPC_INTERLOCKEDEXCHANGEADD64";
function InterlockedCompareExchange(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer; external name "FPC_INTERLOCKEDCOMPAREEXCHANGE64";
{$else cpu64}
function InterLockedIncrement (var Target: Pointer) : Pointer; external name "FPC_INTERLOCKEDINCREMENT";
function InterLockedDecrement (var Target: Pointer) : Pointer; external name "FPC_INTERLOCKEDDECREMENT";
function InterLockedExchange (var Target: Pointer;Source : Pointer) : Pointer; external name "FPC_INTERLOCKEDEXCHANGE";
function InterLockedExchangeAdd (var Target: Pointer;Source : Pointer) : Pointer; external name "FPC_INTERLOCKEDEXCHANGEADD";
function InterlockedCompareExchange(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer; external name "FPC_INTERLOCKEDCOMPAREEXCHANGE";
{$endif cpu64}
{ unsigned overloads }
function InterLockedIncrement (var Target: cardinal) : cardinal; external name "FPC_INTERLOCKEDINCREMENT";
function InterLockedDecrement (var Target: cardinal) : cardinal; external name "FPC_INTERLOCKEDDECREMENT";
function InterLockedExchange (var Target: cardinal;Source : cardinal) : cardinal; external name "FPC_INTERLOCKEDEXCHANGE";
function InterLockedExchangeAdd (var Target: cardinal;Source : cardinal) : cardinal; external name "FPC_INTERLOCKEDEXCHANGEADD";
function InterlockedCompareExchange(var Target: cardinal; NewValue: cardinal; Comperand: cardinal): cardinal; external name "FPC_INTERLOCKEDCOMPAREEXCHANGE";
{$ifdef cpu64}
function InterLockedIncrement64 (var Target: qword) : qword; external name "FPC_INTERLOCKEDINCREMENT64";
function InterLockedDecrement64 (var Target: qword) : qword; external name "FPC_INTERLOCKEDDECREMENT64";
function InterLockedExchange64 (var Target: qword;Source : qword) : qword; external name "FPC_INTERLOCKEDEXCHANGE64";
function InterLockedExchangeAdd64 (var Target: qword;Source : qword) : qword; external name "FPC_INTERLOCKEDEXCHANGEADD64";
function InterlockedCompareExchange64(var Target: qword; NewValue: qword; Comperand: qword): int64; external name "FPC_INTERLOCKEDCOMPAREEXCHANGE64";
{$endif cpu64}
← →
DevilDevil © (2014-01-31 14:59) [113]> DVM © (31.01.14 14:52) [112]
Не Interlocked, а Atomic
Это inline-функция (интринсинк), который на x86/x64 выдаёт lock cmpxchg
← →
DVM © (2014-01-31 15:07) [114]
> DevilDevil © (31.01.14 14:59) [113]
> Не Interlocked, а Atomic
А есть разница?
class function TInterlocked.CompareExchange(var Target: Pointer; Value: Pointer; Comparand: Pointer): Pointer;
{$IFDEF X64ASM}
asm
.NOFRAME
MOV RAX,R8
LOCK CMPXCHG [RCX],RDX
end;
{$ELSE !X64ASM}
{$IFDEF X86ASM}
asm
XCHG EAX,EDX
XCHG EAX,ECX
LOCK CMPXCHG [EDX],ECX
end;
{$ENDIF X86ASM}
{$ENDIF !X64ASM}
← →
DevilDevil © (2014-01-31 15:46) [115]> DVM © (31.01.14 15:07) [114]
Конечно есть разница
Atomic это инлайн, а в FPC обычная функция :)
Ну а если серьёзно - в коде я буду вызывать функцию AtomicCmpExchange
Следовательно если ещё в ЯП нет - то её нужно эмулировать
Вот я и думаю, через какие опции компилятора это делается
Раз ты говоришь про Interlocked - делаю предположение, что Atomic в FPC тоже нет
← →
DVM © (2014-01-31 15:53) [116]
> DevilDevil © (31.01.14 15:46) [115]
> > DVM © (31.01.14 15:07) [114]
>
> Конечно есть разница
> Atomic это инлайн, а в FPC обычная функция :)
В твоем случае какая разница? И то и другое позволит создать класс кодировки потокобезопасно и без блокировок.
Тебе ж ее один раз вызвать и забыть, какая разница инлайн - не инлайн?
В делфи кстати некоторые Interlocked тоже инлайн. Правда в делфи иногда такой инлайн получается - лучше бы его не было.
← →
DVM © (2014-01-31 15:57) [117]
> Раз ты говоришь про Interlocked - делаю предположение, что
> Atomic в FPC тоже нет
Я не нашел, я Interlocked имел в виду
← →
DevilDevil © (2014-01-31 16:00) [118]Ну там типа смайл был потому, что это шутка
Но не без доли правды :)
Разницы конечно нет
Разница лишь в том, что Atomic под FPC не скомпилируется. Как и под старыми версиями Delphi. И с этим надо что-то делать
Я спросил, на какой дифайн заложиться
Кто знает, в какой версии Delphi они появились?
← →
DVM © (2014-01-31 16:03) [119]
> Кто знает, в какой версии Delphi они появились?
AtomicCmpExchange? В XE3 по всей видимости, так там она есть, а в XE2 нету.
Но я не исключаю, что и раньше была, просто название другое было.
← →
DevilDevil © (2014-01-31 17:09) [120]Вот что получилось :)
(кому надо){$if Defined(FPC) or (CompilerVersion < 24)}
function AtomicCmpExchange(var Target: Pointer; NewValue: Pointer; Comparand: Pointer): Pointer;
{$if (not Defined(CPUX86)) and (not Defined(CPUX64))}
begin
{$if Defined(FPC) or Defined(MSWINDOWS)}
Result := InterlockedCompareExchange(Target, NewValue, Comparand);
{$else}
{$message warn "not thread safety"}
Result := Target;
if (Result = Comparand) then Target := NewValue;
{$ifend}
end;
{$ifend}
{$ifdef CPUX86}
asm
xchg eax, ecx
lock cmpxchg [ecx], edx
end;
{$endif}
{$ifdef CPUX64}
asm
mov rax, r8
lock cmpxchg [rcx], rdx
end;
{$endif}
{$ifend}
Страницы: 1 2 3 4 вся ветка
Форум: "Прочее";
Текущий архив: 2014.09.14;
Скачать: [xml.tar.bz2];
Память: 0.7 MB
Время: 0.022 c