TDbf и ОЕМ кодировка

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

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

Сообщение SAK » 18.02.2006 01:39:25

Имеется-ли возможность работать в TDbf с таблицами в DOS кодировке, если да, то где это включается?
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение STAKANOV » 18.02.2006 11:43:52

По-моему это никак не контролируется. Я работал с tdbf в Linux и записывал в поля типа ftString данные, открыв файл в Windows, я обнаружил, что у меня все записано в кодировке KOI8-R :D
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение Guest » 18.02.2006 21:04:52

хе млять...
хоть кто-то еще с этим столкнулся...
я долго парился с этими кодировками...
потом зделал тупо, взял функцию которая преобразовывает win1251 -> koi8-r и наоборот... ну и для остальных кодировок тоже есть...
в понедельник если интересно смогу дать эти функции...
Guest
 

Сообщение STAKANOV » 18.02.2006 21:17:53

в понедельник если интересно смогу дать эти функции...

у меня есть, я сейчас как раз программулинку пишу которая текстовые файлы перекодирует

хотя остальные кодировки это какие?
а то тут только win,koi8r,dos и какой-то iso

я взял от сюда - <a href='http://pascal.sources.ru/text/coder.zip' target='_blank'>http://pascal.sources.ru/text/coder.zip</a>
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение Janus » 18.02.2006 21:30:20

Вот универсальная функция:
Код: Выделить всё
   function  convert_cyr_string(str : string; from, to_ : char) : string;
 var
   i       : integer;
   p       : integer;
   c       : char;
   fromstr : string;
   tostr   : string;
 begin
   case from of
     'w' : fromstr := 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
     'd' : fromstr :=  #160#161#162#163#164#165#241#166#167#168#169#170#171#172#173#174#175#224#225#226#227#228#229#230#231#232#233#234#235#236#237#238#239#128#129#130#131#132#133#240#134#135#136#137#138#139#140#141#142#143#144#145#146#147#148#149#150#151#152#153#154#155#156#157#158#159;
     'k' : fromstr := 'БВЧЗДЕJЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСбвчздеjцъйклмнопртуфхжигюыэящшьас';
   else
           fromstr := 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
   end;
   case to_ of
     'w' : tostr := 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
     'd' : tostr :=  #160#161#162#163#164#165#241#166#167#168#169#170#171#172#173#174#175#224#225#226#227#228#229#230#231#232#233#234#235#236#237#238#239#128#129#130#131#132#133#240#134#135#136#137#138#139#140#141#142#143#144#145#146#147#148#149#150#151#152#153#154#155#156#157#158#159;
     'k' : tostr := 'БВЧЗДЕJЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСбвчздеjцъйклмнопртуфхжигюыэящшьас';
   else
           tostr := 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
   end;

   for i := 1 to length(str) do
   begin
     c := str[i];
     p := pos(c, fromstr);
     if p <> 0 then
     begin
       c      := tostr[p];
       str[i] := c;
     end;
     str[i] := c;
   end;

   convert_cyr_string := str;
 end;

Конечно, можно еще немного оптимизировать, но работает.

from (из) и to_ (в) показывают направление кодировки:
w - ANSI
d - ASCII
k - KOI8R
Janus
постоялец
 
Сообщения: 134
Зарегистрирован: 07.11.2005 17:06:49

Сообщение STAKANOV » 19.02.2006 11:52:56

учитывая что tdbf работае с форматами(задается в TableLevel)
3 dBase III+
4 dBase IV
7 Visual dBase VII
25 FoxPro


то по-умолчанию всегда надо использовать cp1251 для хранения данных.
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение SAK » 19.02.2006 15:42:30

Вчера посмотрел исходники и обнаружил там функцию TDbf.Translate.
Которая, как я понимаю, задумывалась как раз для перекодировки, но почему-то не применяется при чтении/записи данных полей базы, но зато используется для перекодирования Memo полей, что в общем случае делать нельзя, т.к. там может быть не только текст, но и двоичные данные. Либо я не понял назначения этой функции, либо она очень криво построена.

Пока ограничился изменением 2-х функций:
Код: Выделить всё
function TDbf.GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; {overload; override;}
begin
 // pretend nativeformat is true
 Result := inherited GetFieldData(Field, Buffer, True);
 if (Field.DataType = ftString)and(Buffer<>nil) then
   OemToCharBuff(Buffer, Buffer, Field.DataSize);
end;

procedure TDbf.SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); {overload; override;}
var buf: array[0..1024]of char;
begin
 if (Field.DataType = ftString)and(Buffer<>nil) then
  begin
    CharToOemBuff(Buffer, Buf, Field.DataSize);
    Buffer:=@buf
  end;
 // pretend nativeformat is true
 inherited SetFieldData(Field, Buffer, True);
end;


Для полноценной работы с разными кодировками, как мне кажется, придется хорошенько порыться в исходнике.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение Джентельмен » 20.02.2006 13:38:27

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

Сообщение wellx » 20.02.2006 14:07:45

А может как-то с UTF-8 можно завязаться? Ну, чтобы потом не мучиться.
wellx
новенький
 
Сообщения: 67
Зарегистрирован: 06.05.2005 14:01:07

Сообщение STAKANOV » 20.02.2006 14:41:28

А может как-то с UTF-8 можно завязаться? Ну, чтобы потом не мучиться.


Честно говоря мне лично сейчас не совсем понятно кто устанавливает стандарт (де факто) для DBF. Это же не изобретение сообщества OpenSource ;)

DBF вроде подерживается, но не не уверен, что развивается.

Что-то у нас спецы по БД молчат...
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение SAK » 20.02.2006 20:11:22

Мне кажется там и развиваться-то некуда, достоинство этого формата в его документированности и наличия большого количества программ для просмотра/редактирования и исправления ошибок. Кроме того надо писать программы и к уже существующим базам.

Если ближе к теме, то судя по документации в Delphi функция TDataset.Translate действительно предназначена для перекодировки строковых полей и вызывается из TStringField.GetValue. В Lazarus в TStringField такой вызов не предусмотрен, вот и получается функция есть, но не используется.
Что касается стандартов, то если в заголовке DBF по смещению 29 не указана кодировка, то подразумевается OEM, в противном случае указанная (например cp1251).
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение STAKANOV » 20.02.2006 23:27:55

Что касается стандартов, то если в заголовке DBF по смещению 29 не указана кодировка, то подразумевается OEM, в противном случае указанная (например cp1251).


хм...это меняет дело
я тут заглянул в исходники - в классе TDBF есть свойство CodePage:cardinal

Судя по описанию взятому мною с <a href='http://tdbf.sourceforge.net/' target='_blank'>http://tdbf.sourceforge.net/</a> он как раз и содержит значение кодовой страницы данных. Правда я еще пока не совсем понимаю как это можно использовать... :unsure:

но похоже автоматом оно точно не используется

и какие константы использовать как значения тоже не ясно... :unsure:
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение SAK » 21.02.2006 22:18:37

Я не знаю насколько эта информация верна, но некоторые коды упоминаются здесь <a href='http://www.gotdotnet.ru/Forums/Common/155460.aspx' target='_blank'>http://www.gotdotnet.ru/Forums/Common/155460.aspx</a>

А вот Database Desktop понимает следующие коды:
dBASE RUS cp866 = $26
Windows (ANSI) = $57
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение Alexey » 02.03.2006 17:44:55

Две простые строки

dbfTarget.LanguageID := DbfLangId_RUS_866;
dbfTarget.TableLevel := 4;

где dbfTarget: TDbf;

а здесь возможные unit Dbf_Lang;
Alexey
 

Сообщение STAKANOV » 02.03.2006 19:18:11

Две простые строки


действительно ...

т.е. я должен сам прочитать/установить dbfTarget.LanguageID и в дальнейшем иметь это ввиду?
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru