Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
2-1381816621
aka
2013-10-15 09:57
2014.09.14
JSON русские символы


2-1381834603
v1.0
2013-10-15 14:56
2014.09.14
множество


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


15-1392191970
Пятница 13
2014-02-12 11:59
2014.09.14
Delphi + NEXTGEN (LLVM) = крах!


2-1381918147
aka
2013-10-16 14:09
2014.09.14
IdHTTP работа с сессиями





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский