Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.09.14;
Скачать: CL | DM;

Вниз

Разбираемся в кодировках   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.73 MB
Время: 0.013 c
15-1392064202
Юрий
2014-02-11 00:30
2014.09.14
С днем рождения ! 11 февраля 2014 вторник


15-1390565775
DevilDevil
2014-01-24 16:16
2014.09.14
Разбираемся в кодировках


2-1381930351
[ВладОшин]
2013-10-16 17:32
2014.09.14
Combobox/Strings, спозиционироваться на строке


15-1390751141
Дмитрий СС
2014-01-26 19:45
2014.09.14
Пользуетесь ли вы absolute?


2-1381983486
i2e
2013-10-17 08:18
2014.09.14
Shift = [ssCtrl]; А если нажато несколько?