Как перекодировать из 1251 в utf8 "на лету"?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как перекодировать из 1251 в utf8 "на лету"?

Сообщение tria » 05.06.2007 10:39:23

Подскажите пож. такую функцию...
Задача выглядит следующим образом. В БД Firebird данные лежат в 1251. С ней надо работать в Лазаре в Линуксе.
Решил попробовать GTK2, перекодируя перед выводом данные в utf8.
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Как перекодировать из 1251 в utf8 "на лету"?

Сообщение haword » 05.06.2007 14:42:54

tria писал(а):Подскажите пож. такую функцию...
Задача выглядит следующим образом. В БД Firebird данные лежат в 1251. С ней надо работать в Лазаре в Линуксе.
Решил попробовать GTK2, перекодируя перед выводом данные в utf8.

посмотри в нутри файла lconv.pas в LCL
haword
постоялец
 
Сообщения: 301
Зарегистрирован: 02.03.2006 11:34:40

Re: Как перекодировать из 1251 в utf8 "на лету"?

Сообщение tria » 05.06.2007 15:50:48

haword писал(а):посмотри в нутри файла lconv.pas в LCL


Посмотрел:
Код: Выделить всё
//Stupid code. Works anyway, but extra-slow
{$ifdef Unix}
  SL:=TStringList.Create;
  SL.Text:=s;
  FN1:=GetTempFileName;
  SL.SaveToFile(FN1);
  FN2:=GetTempFileName;
  Shell('iconv -f '+from+' -t '+toC+'<'+FN1+' >'+FN2);
  SL.LoadFromFile(FN2);
  if SL.Text<>'' then  Result:=SL.Text else Result:=s;
  DeleteFile(FN1);DeleteFile(FN2);
{$endif}

В моем случае этот метод ну никак не приемлем...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Сообщение Cheb » 05.06.2007 16:14:57

Вроде бы, во ФриПаскале есть встроенные конвертеры utf-16 в utf-8 и обратно.
Ну а utf-16 <-> cp1251 уже можно ручками вбить (там же не больше 128 символов).
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Джентельмен » 05.06.2007 17:33:28

ага... и вы столкнулись с проблемой... а я когда то поднимал эту тему... пол инета перелопатил... кучу функций перепробывал... ну да ладно... если не забуду, завтра принесу и сброшу функцию кодирования... как раз для ваших целей... и решит вашу проблему... хотя... а нифига с собой нет... если не забуду завтра выложу...
Джентельмен
постоялец
 
Сообщения: 162
Зарегистрирован: 16.10.2005 10:47:26
Откуда: Украина Донбасс Краматорск

Сообщение Sergei I. Gorelkin » 05.06.2007 17:50:44

1. Подключить модуль cwstring
2. если локаль 1251, то можно напрямую пользоваться AnsiToUtf8 и Utf8ToAnsi, иначе придется использовать модифицированный код из cwstring. Там, в общем, надо только передать iconv_open() нужные названия кодировок.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение tria » 05.06.2007 18:04:02

Джентельмен писал(а):ага... и вы столкнулись с проблемой... а я когда то поднимал эту тему... пол инета перелопатил... кучу функций перепробывал... ну да ладно... если не забуду, завтра принесу и сброшу функцию кодирования... как раз для ваших целей... и решит вашу проблему... хотя... а нифига с собой нет... если не забуду завтра выложу...


Буду очен, очень благода
Если функция не очень длинная - думаю, лучше выложить на форуме для всех
Если длинная - можно мне на мыло
pavel собач dt.ck.ua
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Сообщение Джентельмен » 06.06.2007 10:56:58

да на форуме выложу... если бы кто-то напомнил бы мне сутра смской... то я бы и сегодня её не забыл...
Джентельмен
постоялец
 
Сообщения: 162
Зарегистрирован: 16.10.2005 10:47:26
Откуда: Украина Донбасс Краматорск

Сообщение Джентельмен » 06.06.2007 11:00:51

радуйтесь...
и на емаил я тебе отправил юнит...
===============================================
Код: Выделить всё
unit Unit8;

{$mode objfpc}{$H+}

interface


const
BASE_CHAR = 192;
w2k : array[0..63] of Byte = (225, 226, 247, 231, 228, 229, 246, 250,
                               233, 234, 235, 236, 237, 238, 239, 240,
                               242, 243, 244, 245, 230, 232, 227, 254,
                               251, 253, 255, 249, 248, 252, 224, 241,
                               193, 194, 215, 199, 196, 197, 214, 218,
                               201, 202, 203, 204, 205, 206, 207, 208,
                               210, 211, 212, 213, 198, 200, 195, 222,
                               219, 221, 223, 217, 216, 220, 192, 209);
k2w : array[0..63] of Byte = (254, 224, 225, 246, 228, 229, 244, 227,
                               245, 232, 233, 234, 235, 236, 237, 238,
                               239, 255, 240, 241, 242, 243, 230, 226,
                               252, 251, 231, 248, 253, 249, 247, 250,
                               222, 192, 193, 214, 196, 197, 212, 195,
                               213, 200, 201, 202, 203, 204, 205, 206,
                               207, 223, 208, 209, 210, 211, 198, 194,
                               220, 219, 199, 216, 221, 217, 215, 218);
                               
                               
                               
                               
OTA = #$01#$02#$03#$04#$05#$06#$07#$08#$09#$0A#$0B#$0C#$0D#$0E#$0F#$10+
       #$11#$12#$13#$14#$15#$16#$17#$18#$19#$1A#$1B#$1C#$1D#$1E#$1F#$20+
       #$21#$22#$23#$24#$25#$26#$27#$28#$29#$2A#$2B#$2C#$2D#$2E#$2F#$30+
       #$31#$32#$33#$34#$35#$36#$37#$38#$39#$3A#$3B#$3C#$3D#$3E#$3F#$40+
       #$41#$42#$43#$44#$45#$46#$47#$48#$49#$4A#$4B#$4C#$4D#$4E#$4F#$50+
       #$51#$52#$53#$54#$55#$56#$57#$58#$59#$5A#$5B#$5C#$5D#$5E#$5F#$60+
       #$61#$62#$63#$64#$65#$66#$67#$68#$69#$6A#$6B#$6C#$6D#$6E#$6F#$70+
       #$71#$72#$73#$74#$75#$76#$77#$78#$79#$7A#$7B#$7C#$7D#$7E#$7F#$C0+
       #$C1#$C2#$C3#$C4#$C5#$C6#$C7#$C8#$C9#$CA#$CB#$CC#$CD#$CE#$CF#$D0+
       #$D1#$D2#$D3#$D4#$D5#$D6#$D7#$D8#$D9#$DA#$DB#$DC#$DD#$DE#$DF#$E0+
       #$E1#$E2#$E3#$E4#$E5#$E6#$E7#$E8#$E9#$EA#$EB#$EC#$ED#$EE#$EF+
       #$80#$81#$82+

       #124#124#124#124#43#43#124#124#43#43#43#43#43#43+
       #43#43#124#45#43#124#124#43#43#43#43#124#45#43#43#43+
       #43#43#43#43#43#43#43#43#43#43+

       #$9B#$9C#$A6#$CC#$9D+
       #$F0+
       #$F1#$F2#$F3#$F4#$F5#$F6#$F7#$F8#$F9#$FA#$FB#$FC#$FD#$FE#$FF#$A8+
       #$B8#$F7#$BE#$B6#$A7#$9F#$B8#$B0#$A8#$B7#$B9#$B3#$B2#$9E#$A0;

ATO = #$01#$02#$03#$04#$05#$06#$07#$08#$09#$0A#$0B#$0C#$0D#$0E#$0F#$10+
       #$11#$12#$13#$14#$15#$16#$17#$18#$19#$1A#$1B#$1C#$1D#$1E#$1F#$20+
       #$21#$22#$23#$24#$25#$26#$27#$28#$29#$2A#$2B#$2C#$2D#$2E#$2F#$30+
       #$31#$32#$33#$34#$35#$36#$37#$38#$39#$3A#$3B#$3C#$3D#$3E#$3F#$40+
       #$41#$42#$43#$44#$45#$46#$47#$48#$49#$4A#$4B#$4C#$4D#$4E#$4F#$50+
       #$51#$52#$53#$54#$55#$56#$57#$58#$59#$5A#$5B#$5C#$5D#$5E#$5F#$60+
       #$61#$62#$63#$64#$65#$66#$67#$68#$69#$6A#$6B#$6C#$6D#$6E#$6F#$70+
       #$71#$72#$73#$74#$75#$76#$77#$78#$79#$7A#$7B#$7C#$7D#$7E#$7F#$B0+
       #$B1#$B2#$B3#$B4#$B5#$B6#$B7#$B8#$B9#$BA#$BB#$BC#$BD#$BE#$BF#$C0+
       #$C1#$C2#$C3#$C4#$C5#$C6#$C7#$C8#$C9#$CA#$CB#$CC#$CD#$CE#$CF#$D0+
       #$D1#$D2#$D3#$D4#$D5#$D6#$D7#$F0#$D9#$DA#$DB#$DC#$DD#$DE#$DF#$F0+
       #$F1#$F2#$F3#$F4#$F5#$F6#$F7#$F1#$F9#$FA#$FB#$FC#$FD#$FE#$FF#$80+
       #$81#$82#$83#$84#$85#$86#$87#$88#$89#$8A#$8B#$8C#$8D#$8E#$8F#$90+
       #$91#$92#$93#$94#$95#$96#$97#$98#$99#$9A#$9B#$9C#$9D#$9E#$9F#$A0+
       #$A1#$A2#$A3#$A4#$A5#$A6#$A7#$A8#$A9#$AA#$AB#$AC#$AD#$AE#$AF#$E0+
       #$E1#$E2#$E3#$E4#$E5#$E6#$E7#$E8#$E9#$EA#$EB#$EC#$ED#$EE#$EF;
                               
                               
                               
                               
                               

function WinToK8R(const Text : String) : String;
function K8RToWin(const Text : String) : String;

function _ATO(SS: string): string; {Win1251 -  DOS866}
function _OTA(SS: string): string; {DOS866  - Win1251}


implementation
Uses
  Unit1, Unit2, Unit3, Unit4, Unit5, Unit6, Unit7, Unit9, Unit10;


function WinToK8R(const Text : String) : String;
var
  i : Integer;
begin
  Result := Text;
  for i := 1 to Length(Result) do
  if Result[i] >= Char(BASE_CHAR) then
  Result[i] := Char(w2k[Byte(Result[i])-BASE_CHAR]);
end;

function K8RToWin(const Text : String) : String;
var
  i : Integer;
begin
  Result := Text;
  for i := 1 to Length(Result) do
  if Result[i] >= Char(BASE_CHAR) then
  Result[i] := Char(k2w[Byte(Result[i])-BASE_CHAR]);
end;




function _ATO(SS: string): string;
var I: integer;
    SR: string;
begin
  SR:='';
  for I:=1 to Length(SS) do
    SR:=SR+ATO[Ord(SS[I])];
  Result:=SR;
end;

function _OTA(SS: string): string;
var I: integer;
    SR: string;
begin
  SR:='';
  for I:=1 to Length(SS) do
    SR:=SR+OTA[Ord(SS[I])];
  Result:=SR;
end;



end.
Джентельмен
постоялец
 
Сообщения: 162
Зарегистрирован: 16.10.2005 10:47:26
Откуда: Украина Донбасс Краматорск

Сообщение tria » 07.06.2007 10:31:53

Вчера отсутствовал. Сегодня изучил присланный код. Если я правильно понял, то:

Код: Выделить всё
function WinToK8R(const Text : String) : String; //1251->KOI8
function K8RToWin(const Text : String) : String; //KOI8->1251

function _ATO(SS: string): string; {Win1251 - DOS866}
function _OTA(SS: string): string; {DOS866 - Win1251}


А где же обещанная 1251 <-> UTF8?

:(
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Сообщение Attid » 07.06.2007 10:52:16

tria
В моем случае этот метод ну никак не приемлем...


посмотри как используется iconv тут

или посмотри что с перекодировкой есть тут
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение tria » 07.06.2007 12:14:37

Attid писал(а):посмотри как используется iconv тут

Смотрел я и здесь.
Код: Выделить всё
function iconv_open(__tocode:pchar; __fromcode:pchar):iconv_t;cdecl;external libiconvname name 'iconv_open';
function iconv(__cd:iconv_t; __inbuf:ppchar; __inbytesleft:psize_t; __outbuf:ppchar; __outbytesleft:psize_t):size_t;cdecl;external libiconvname name 'iconv';
function iconv_close(__cd:iconv_t):cint;cdecl;external libiconvname name 'iconv_close';
Этот вариант я хочу оставить на крайний случай. Мне кажется, что данные функции будут работать существенно медленнее, чем специализированная и написанная на FreePascal. Мне нужно конвертировать очень много данных.
Не очень хочется каждую строку преобразовывать в pchar и назад.

Attid писал(а):или посмотри что с перекодировкой есть тут

В CodeChanger присутствуют след. кодировки:
(ctOem, ctWin1251, ctKoi8R, ctIso, ctUtf16, ctMac)
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Сообщение Attid » 07.06.2007 14:04:53

ну доделай пример Джентельмена до 1251 <-> UTF8 используя код CodeChanger
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение debi12345 » 07.06.2007 15:08:55

Пинайте команду FPC. Методы перекодировки UTF8 from/to "произвольная кодовая страница", а не только ANSI - нужны позарез.

Кстати, а у сервера+клиента - нет настройки типа CLIENT_ENCODING ? Что всю работу по перекодировке перепоручить серверу. Обычно так и делается.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5752
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Джентельмен » 07.06.2007 15:38:46

я когда на заводе ПО писал под линуксом в лазарусе а под виндой в базе были иероглифы... этими функциями все перекодиловалось идеально... и сейчас у меня в DBF и FireBird иероглифы получались... и этими функциями перекодирует все идеально... насколько я понимаю у тебя такая же проблема... или подобная... не читай функции... просто попробуй... _ATO и _OTA... помогут однозначно... или вышли мне на емаил пример своей записи которую надо перекодировать... я тебе подберу функцию... ну вот перечитал вопрос... ситуация как у меня... все там работает...
шли на емаил базу... будем кодировать...

alexey@nikron.krm.net.ua
Джентельмен
постоялец
 
Сообщения: 162
Зарегистрирован: 16.10.2005 10:47:26
Откуда: Украина Донбасс Краматорск

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30

Рейтинг@Mail.ru