SASGIS - SAS.Планета
View Issue Details
0002877SAS.Планета[All Projects] Хотелкаpublic29-10-2015 11:0503-11-2015 10:55
vdemidov 
vdemidov 
normalminoralways
resolvedfixed 
151010 
151111151111 
0002877: Поддержка utf-8 и utf-16 при загрузке параметров карты в неюникодной версии программы
Юникодная версия программы получает возможность чтения params.txt в utf-8 и utf-16 за счет стандартной библиотеки. Нужно добавить такую поддержку для неюникодной версии для текстовых файлов которые используются в Read only режиме.
Для этого достаточно добавить в TConfigDataProviderByArchive.GetSubItem и TConfigDataProviderByFolder.GetSubItem перекодировку как это сделано в TKmlInfoSimpleParser.LoadFromStreamInternal только без кодирования в utf-8

Естественно это хозяйство нужно запихать в условную компиляцию, что бы оно даже не компилировалось для более новых компиляторов.
No tags attached.
related to 0002690resolved vdemidov Добавить определение кодировки ini-файлов при загрузке в ConfigDataProvider 
child of 0002166resolved zed Переход на версию Delphi с полной поддержкой юникода 
Issue History
29-10-2015 11:05vdemidovNew Issue
29-10-2015 11:05vdemidovRelationship addedrelated to 0002690
29-10-2015 11:05vdemidovRelationship addedchild of 0002166
29-10-2015 11:05vdemidovStatusnew => confirmed
29-10-2015 11:07vdemidovDescription Updatedbug_revision_view_page.php?rev_id=6764#r6764
30-10-2015 08:53vdemidovNote Added: 0016649
30-10-2015 08:54vdemidovNote Edited: 0016649bug_revision_view_page.php?bugnote_id=16649#r6766
30-10-2015 08:56vdemidovNote Edited: 0016649bug_revision_view_page.php?bugnote_id=16649#r6767
30-10-2015 08:58vdemidovTarget Version => 151111
30-10-2015 09:05zedNote Added: 0016650
30-10-2015 09:13vdemidovNote Added: 0016651
01-11-2015 11:13zedNote Added: 0016678
01-11-2015 21:37vdemidovNote Added: 0016679
03-11-2015 08:48vdemidovNote Added: 0016693
03-11-2015 08:48vdemidovStatusconfirmed => resolved
03-11-2015 08:48vdemidovFixed in Version => 151111
03-11-2015 08:48vdemidovResolutionopen => fixed
03-11-2015 08:48vdemidovAssigned To => vdemidov
03-11-2015 10:32zedNote Added: 0016698
03-11-2015 10:55vdemidovNote Added: 0016701

Notes
(0016649)
vdemidov   
30-10-2015 08:53   
(edited on: 30-10-2015 08:56)
Даже не знаю что делать. Городить свой огород, или воспользоваться набором совместимости от GunSmoker описанному в статье и сделать вид, что в старой делфи есть все, что и в новой.

(0016650)
zed   
30-10-2015 09:05   
А идею с флагом, который указывает на кодировку, уже похоронил? Мне она кажется самым надёжным вариантом - ведь BOM он такой, может быть, а может и нет. Особенно при ручном редактировании.
(0016651)
vdemidov   
30-10-2015 09:13   
Я всегда говорил, что считаю bom вполне достаточным. А флаг то для изменяемых ini, про него речь пока не идет.
(0016678)
zed   
01-11-2015 11:13   
В mORMot.SynCommons.pas есть функция для чтения текстовых файлов с детектированием кодировки:

/// get text File contents (even Unicode or UTF8) and convert it into a
// Charset-compatible AnsiString (for Delphi 7) or an UnicodeString (for Delphi
// 2009 and up) according to any BOM marker at the beginning of the file
// - before Delphi 2009, the current string code page is used (i.e. CurrentAnsiConvert)
function AnyTextFileToString(const FileName: TFileName; ForceUTF8: boolean): string;
var Map: TMemoryMap;
begin
  result := '';
  if Map.Map(FileName) then
  try
    if ForceUTF8 then
{$ifdef UNICODE}
      UTF8DecodeToString(PUTF8Char(Map.Buffer),Map.Size,result) {$else}
      result := CurrentAnsiConvert.UTF8BufferToAnsi(PUTF8Char(Map.Buffer),Map.Size)
{$endif} else
    case TextFileKind(Map) of
{$ifdef UNICODE}
    isUnicode:
      SetString(result,PWideChar(PtrInt(Map.Buffer)+2),(Map.Size-2) shr 1);
    isUTF8:
      UTF8DecodeToString(pointer(PtrInt(Map.Buffer)+3),Map.Size-3,result);
    isAnsi:
      result := CurrentAnsiConvert.AnsiToUnicodeString(Map.Buffer,Map.Size);
{$else}
    isUnicode:
      result := CurrentAnsiConvert.UnicodeBufferToAnsi(PWideChar(PtrInt(Map.Buffer)+2),(Map.Size-2) shr 1);
    isUTF8:
      result := CurrentAnsiConvert.UTF8BufferToAnsi(pointer(PtrInt(Map.Buffer)+3),Map.Size-3);
    isAnsi:
      SetString(result,PAnsiChar(Map.Buffer),Map.Size);
{$endif}
    end;
  finally
    Map.UnMap;
  end;
end;
(0016679)
vdemidov   
01-11-2015 21:37   
Ну, что-то подобное и сделал. Только чуть универсальнее.
(0016693)
vdemidov   
03-11-2015 08:48   
Вроде бы работает. Главное не забывать о ini файлах вообще и maps.ini в частности.
(0016698)
zed   
03-11-2015 10:32   
Т.е. не забывать?
(0016701)
vdemidov   
03-11-2015 10:55   
>Т.е. не забывать?
А то что юникодное название карты не из основной локали без проблем отобразится в юникодной версии. Но вот после перезапуска, благодаря Ansi-шности (пока) ini файлов и багу 0002047 это название превратится в знаки вопроса до удаления maps.ini