Anonymous | Login | Signup for a new account | 22-11-24 03:05 UTC |
All Projects | SAS.Планета | Домен, сайт, форум, багтрекер | Доработка карты (ZMP) | Переводы и локализации | Прочее |
My View | View Issues | Change Log | Roadmap | Search |
View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0002690 | SAS.Планета | Рефакторинг | public | 21-04-2015 09:28 | 07-11-2015 19:17 | ||||
Reporter | vdemidov | ||||||||
Assigned To | vdemidov | ||||||||
Priority | normal | Severity | minor | Reproducibility | have not tried | ||||
Status | resolved | Resolution | fixed | ||||||
Platform | OS | OS Version | |||||||
Product Version | 141212 | ||||||||
Target Version | 151111 | Fixed in Version | 151111 | ||||||
Summary | 0002690: Добавить определение кодировки ini-файлов при загрузке в ConfigDataProvider | ||||||||
Description | Сейчас программа при попытке загрузить ini-файл в юникодной кодировке, не загружает ничего. Нужно при загрузке использовать DetectUTFEncoding и конвертировать полученное в текущий тип String. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | |||||||||
Relationships | |||||||||||||||||||||
|
Notes | |
(0015647) vdemidov (manager) 22-04-2015 07:25 |
Я тут подумал, похоже оптимальным вариантом будет сделать по аналогии с парсером TKmlInfoSimpleParser. То есть при загрузке инишки проверяем ее кодировку и если надо конвертируем ее в UTF8. При загрузке/сохранении параметров-строк выполняем кодирование/декодирование в UTF8. Почти все содержимое ini это ANSI и только несколько строковых параметров может содержать какие-то другие символы (история поиска, пути, шаблоны имен для меток и категорий). |
(0015648) zed (manager) 22-04-2015 07:36 |
Сохранение в ini это отдельный вопрос. Если их перевести на utf8, то старые версии их резко перестанут понимать. И это, ещё до перехода на юникодную делфи. |
(0015650) vdemidov (manager) 22-04-2015 08:04 |
Можно сменить формат основного конфига на JSON c обязательной Utf-8 в качестве кодировки :) Еще можно попробовать, для начала, добавить детектирование наличия utf-8 строк в файле и если есть, то взводить флаг, который будет предписывать читать и сохранять строки в utf-8. В результате версии начиная с некоторой начнут понимать такие конфиги, но не будут принуждать к переходу так сказать. А после перехода на юникод, сделаем принудительное сохранение в utf-8. Но последние актуальные версии будут продолжать нормально работать с такими конфигами. |
(0015652) zed (manager) 22-04-2015 08:08 |
Вариант со сменой формата на json мне нравится. А ini можно оставить для обратной совместимости, только для чтения (если не найден json). Соответственно, и читать ini всегда как анси. |
(0015656) vdemidov (manager) 22-04-2015 10:06 |
Значит нужно делать реализацию IConfigDataWriteProvider с записью в JSON. |
(0015658) vasketsov (manager) 22-04-2015 10:42 |
>Вариант со сменой формата на json Ну, фактически это означает, что у EXE-хи будут разные конфиги (минимум ДВА), даже если две EXE-хи собирать в одну папку. То есть как бы _при_идентичных_настройках_ проверить наличие или отсутствие бага на другой версии компилятора уже не получится. Ну и ещё не нравится то, что редактирование его руками может быть весьма нетривиально. >взводить флаг, который будет предписывать читать и сохранять строки в utf-8 Вот такое поведение представляется куда более разумным. Тем более что при необходимости можно будет сделать флаг, что содержимое было unicode (в т.ч. LE) и сохранять его обратно также. Пример определения, чего за unicode подсунули (через IsTextUnicode), у меня есть в u_IocpServer.pas. Только что кстати его подправил на тему строк. |
(0015665) vdemidov (manager) 22-04-2015 10:57 |
>Ну, фактически это означает, что у EXE-хи будут разные конфиги (минимум ДВА), даже если две EXE-хи собирать в одну папку. Не, речь о переходе текущей обычной версии на новый формат конфига. То есть когда появится юникодная версия, актуальная обычная версия уже должна пользоваться новым форматом конфига. |
(0015668) vasketsov (manager) 22-04-2015 11:05 |
Так понял. Ну тогда это надо делать заведомо до следующего релиза. Только надо договориться, что в общие конфиги не будем совать сильно нетривиальные типы данных. Но я бы всё же предложил ещё сильно подумать насчёт json. У него отсутствует дуракоустойчивость. Лишняя скобка - и ппц. А поскольку конфиги правятся руками,... А также конфиг сильно распухнет (либо будет нечитаемым), что приведёт к задержке чтения его с диска. А поскольку та же фигня со всеми zmp, то время старта увеличится. А zmp делать нечитаемыми нельзя, они в репо падают с изменениями, так что там точно будет куча пробелов всяких. В общем, потенциально или тормознутое или неудобное решение. |
(0015684) vdemidov (manager) 23-04-2015 07:36 |
> У него отсутствует дуракоустойчивость. Убедил. Сейчас мне кажется оптимальным добавить поддержку utf-8 в ini-шки. Остается только придумать метод переключения режима. Возможные варианты: 1. Самый простой вариант завести в ini специальный ключ и проверять его сразу при загрузке, например в секции [SYSTEM]use_utf8=1 2. Пытаться читать все строки файла и определять есть ли там utf-8 или, наоборот, точно не utf-8 строки и в зависимости от этого решать как действовать дальше. 3. Просто забить на совместимость конфигов и перейти на utf-8 принудительно. |
(0015685) vasketsov (manager) 23-04-2015 08:17 |
>читать все строки файла и определять есть ли там utf-8 Я бы предложил так: а) при загрузке проверять на unicode и в этом случае в XE2 грузить как есть и сохранять как есть, а в 2007 молча приводить к utf-8 и сохранять потом в utf-8 (вряд ли имеет смысл сохранять в unicode в 2007); б) если не unicode то надо проверять, что буфер содержит валидную строку utf-8 или сразу по всему буферу (Pointer и Size есть), или лениво и построчно при чтении значения, лично мне кажется проще и быстрее первый вариант сразу, и без [SYSTEM]use_utf8=1 (которую никто и никогда не будет искать и менять в файле при его сохранении в блокноте руками); соответственно если конфиг валиден в смысле utf-8, то и сохранять его в таком же формате (важно для уменьшения размера в том числе, ибо желательно конечно универсальное решение и для конфигов и для zmp;); в) если не unicode и буфер не валидная utf-8 строка - значит Ansi, тут по желанию можно конвертнуться в utf-8 и сохраняться в нём, а можно оставить Ansi, если не будет сильно трудно. Это в теории. |
(0015693) vdemidov (manager) 23-04-2015 09:30 |
> в XE2 грузить как есть и сохранять как есть Как показала практика в XE2 как есть сохраняет и читает именно в Ansi и будут потери если строка не совпадают с текущей локалью. > а) при загрузке проверять на unicode и молча приводить к utf-8 и сохранять потом в utf-8 Это можно, но только на случай создания файла нотпадом. Сам САС ни в какой из версий сохранять utf-16 не будет. > если не unicode то надо проверять, что буфер содержит валидную строку utf-8 Вот в этом и вопрос. Как это правильно делать. Вариант с отдельным ключом хорош тем, что он позволит не перейти ненароком на utf-8 когда пользователь этого не хочет. Пример: 1. Есть старая версия, которая не понимает utf-8 но в конфиге нет не ansi строк. 2. Запускается версия с поддержкой utf-8, решает что это валидная utf-8 строка и новые строки сохраняет в utf-8, и вводится какое-то значение которое уже не ansi 3. Запускается старая версия и говорит WTF |
(0015708) vasketsov (manager) 23-04-2015 15:39 |
>позволит не перейти ненароком на utf-8 А, ну то есть параметр будет означать запрет изменения формата? Тогда в нём есть смысл. >сохраняет и читает именно в Ansi Это каким способом? TStringList.ReadFromStream/ReadFromFile? Потому что у меня есть сомнения насчёт этого в случае ReadFile сотоварищи, которые читают буфер с диска как есть и кладут его в строку не зная её тип, и наоборот пишут всю строку как есть на диск. >Как это правильно делать Первая же ссылка на хабре выдаёт пример, правда для веба, что-то типа php, не силён в этом, видел только что не perl. Я про то, где ещё стёб про корейцев. |
(0015710) vdemidov (manager) 23-04-2015 17:41 |
>>сохраняет и читает именно в Ansi >Это каким способом? TMeminifile.Create Там в XE2 уже есть проверка кодировки открываемого файла по существующему BOM. А по умолчанию используется Ansi >Первая же ссылка на хабре выдаёт пример, правда для веба, что-то типа php, не силён в этом, видел только что не perl. Я про то, где ещё стёб про корейцев. В том то и дело что стеб. А как правильно проверить файл я не знаю. Хотя для двух десятков килобайт и такой способ прокатит. |
(0015711) vasketsov (manager) 23-04-2015 18:48 |
>стеб Да я ж про комменты: // Returns true if $string is valid UTF-8 and false otherwise. function is_utf8($string) { // From w3.org/International/questions/qa-forms-utf-8.html return preg_match('%^(?: [\x09\x0A\x0D\x20-\x7E] # ASCII | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )*$%xs', $string); } // function is_utf8 А вот ещё: http://phpclub.ru/talk/threads/utf8-%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D0%BD%D0%B0-%D0%B2%D0%B0%D0%BB%D0%B8%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%8C.35808/ но всё php - я в нём не бельмеса. Может быть проще будет по определению из вики сделать: Символы UTF-8 получаются из Unicode следующим образом: Unicode UTF-8: 0x00000000 — 0x0000007F: 0xxxxxxx 0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx 0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Теоретически возможны, но не включены в стандарт также: 0x00200000 — 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 0x04000000 — 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx Короче, судя по всему, это вопрос или прямого однопроходного алгоритма, или регулярного выражения. |
(0015712) vasketsov (manager) 23-04-2015 18:58 |
Но вообще я бы плясал от IsTextUnicode https://msdn.microsoft.com/en-us/library/windows/desktop/dd318672(v=vs.85).aspx и сотоварищи MultiByteToWideChar WideCharToMultiByte возможно флаг WC_ERR_INVALID_CHARS и результат: The function returns 0 if it does not succeed. To get extended error information, the application can call GetLastError, which can return one of the following error codes: •ERROR_INSUFFICIENT_BUFFER. A supplied buffer size was not large enough, or it was incorrectly set to NULL. •ERROR_INVALID_FLAGS. The values supplied for flags were not valid. •ERROR_INVALID_PARAMETER. Any of the parameter values was invalid. •ERROR_NO_UNICODE_TRANSLATION. Invalid Unicode was found in a string. последнее может быть оно и есть? |
(0015714) vdemidov (manager) 23-04-2015 21:04 |
Ну регексп это перебор. А вот IsTextUnicode уже интереснее. Хотя мне все больше хочется повторить то что уже есть из коробки в версии XE2: проверяем BOM в том числе и для utf-8, отсутствие BOM считаем признаком ANSI, по результатам конвертим в текущий тип string. |
(0015716) vasketsov (manager) 24-04-2015 00:07 |
>отсутствие BOM считаем признаком ANSI Ничего подобного. Если нет BOM но залетели внутрь IsTextUnicode - значит прилетел WideString. См. что я залил себе в парсер kml, это кусок вставки меток из буфера обмена. Специально оставил как есть чтобы ещё немного поиграться. Пока строка из буфера обмена забиралась как WideString - Get для неё там отлично работал. Вернул забор в виде Ansi просто потому что мы её копируем в буфер обмена как UTF-8. |
(0015717) vasketsov (manager) 24-04-2015 04:26 |
Подумалось вот ещё. Может есть софт типа тоталкомандера или нотепада какого (в смысле, на дельфе и открытый), где решена проблема распознавания буфера и кодировок, проверки utf-8? Откуда это официально можно было бы спереть. Есть мысли на эту тему? |
(0015719) zed (manager) 24-04-2015 04:40 |
Можно сделать настройку: "Файлы без BOM распозновать как:" и список кодировок. По-умолчанию выставить системную или utf-8. |
(0015720) zed (manager) 24-04-2015 04:50 |
> Есть мысли на эту тему? Посмотри на Notepad++ (хоть там и с++) - умеет распозновать utf-8 без BOM. |
(0015722) vasketsov (manager) 24-04-2015 06:30 |
http://doublecmd.sourceforge.net/ Double Commander использует судя по всему Summary Charset Detector - as the name says - is a stand alone executable module for automatic charset detection of a given text. It can be useful for internationalisation support in multilingual applications such as web-script editors or Unicode editors. Given input buffer will be analysed to guess used encoding. The result can be used as control parameter for charset conversation procedure. Charset Detector can be compiled (and hopefully used) for MS Windows (as dll - dynamic link library) or Linux. Based on Mozilla's i18n component - http://www.mozilla.org/projects/intl/. -----------State Version 0.2.6 stable. The latest version can be found at http://chsdet.sourceforge.net. |
(0015723) vdemidov (manager) 24-04-2015 07:58 |
А мне кажется, что с этим можно вообще не заморачиваться. Версия скомпиленная в XE2 по-умолчанию все сохраняет в ANSI, то есть ровно так же как есть сейчас. Можно добавить в текущую версию проверку BOM и перекодировку, а со временем в юникодной версии установить принудительное сохранение в utf-8. И все будет работать в обычной версии ничуть не хуже чем сейчас, а в юникодной - лучше. |
(0015759) vdemidov (manager) 26-04-2015 11:34 |
Блин. Как лень делать работу, которая станет не нужно сразу после перехода на XE2. |
(0015760) vasketsov (manager) 26-04-2015 11:50 |
Ну тогда надо заранее приготовиться к потоку ссаных тряпок, доделать то что совсем уж не причёсано, и выпустить релиз под XE2. Тогда делать ненужную работу по переходу не придётся. Вся работа будет только нужной. |
(0015770) vdemidov (manager) 26-04-2015 13:34 |
Ну тогда давай конкретные примеры, когда юникодная версия работает хуже чем текущая. |
(0015773) zed (manager) 26-04-2015 13:39 |
Я думаю, если внезапно начать собирать ночнушку в XE2, багтрекер треснет от наплыва багов :) |
(0016509) zed (manager) 02-10-2015 19:51 |
Мне вот сейчас подумалось, что первым делом нам нужно перевести все zmp на юникод. Особенно, в свете того, что появился интерес со стороны французских товарищей и они сейчас могут захотеть писать в params.txt локализованные названия карт. И по-моему, проще всего это добавить флаг 'use_utf8' или положить файлик типа encoding.txt в zmp с актуальной кодировкой всех ini/txt. Причём, это имеет смысл делать уже сейчас, вне зависимости от того, каким мы компилятором пользуемся. |
(0016511) vdemidov (manager) 02-10-2015 20:43 |
Просто очень лень вручную делать то, что получим автоматом при переходе на новую версию компилятора. Там детектирование на основе BOM уже есть из коробки. |
(0016512) zed (manager) 02-10-2015 20:47 |
Не факт, что мы на эту новую версию ещё перейдём. Да и детектирование по bom не такой уж и надёжный способ. |
(0016513) vdemidov (manager) 02-10-2015 20:54 |
>Не факт, что мы на эту новую версию ещё перейдём. Это плохо. >Да и детектирование по bom не такой уж и надёжный способ. ИМХО он оптимален по соотношению затрачиваемых усилий на реализацию, затрачиваемых при работе ресурсов и полученному результату. |
(0016514) zed (manager) 02-10-2015 21:06 |
Я бы хотел, чтобы наш следующий релиз уже поддерживал юникод, хотя бы в params.txt. |
(0016515) vdemidov (manager) 02-10-2015 21:09 |
Я пасс. Я любую поддержку юникода буду добавлять только после перехода на юникодную делфи. |
(0016732) vdemidov (manager) 05-11-2015 07:51 |
Кажется придумал как добавить более менее вменяемую поддержку юникода в ини файлах в D2007. Делаем в Compatibility наследника TMemIniFile с таким же именем. И добавляем туда недостающее свойство Encoding, поддержку чтения файлов с юникодом и сохранение файла с использованием Encoding. В итоге все ограничится добавлением одного юнита в uses в нужных местах. Недостаток - при использовании одновременно юникодной и неюникодной версий - неюникодная версия будет портить символы не из основной локали. Но если их не будет, то все будет работать прозрачно. |
(0016736) vdemidov (manager) 05-11-2015 22:23 |
Вроде бы даже работает. Юникодные данные, конечно, теряются после открытия в неюникодной версии, но только те, которые не из текущей локали. То есть не хуже чем было, а по некоторым параметрам лучше. |
(0016738) vdemidov (manager) 06-11-2015 07:42 |
Осталось придумать по какому признаку сделать принудительное сохранение ini в utf в юникодной версии. Самый простой вариант, после выпуска релиза с поддержкой юникодных конфигов, юникодная версия будет форсировано сохранять в utf-8 или utf-16, а обычная просто будет сохранять существующую кодировку. |
Users who viewed this issue | |
User List | Anonymous (5226x), zed (16x), vdemidov (35x), gma (1x) |
Total Views | 5278 |
Last View | 22-11-2024 03:05 |
Issue History | |||
Date Modified | Username | Field | Change |
21-04-2015 09:28 | vdemidov | New Issue | |
21-04-2015 09:29 | vdemidov | Relationship added | child of 0002166 |
21-04-2015 09:29 | vdemidov | Status | new => confirmed |
22-04-2015 07:25 | vdemidov | Note Added: 0015647 | |
22-04-2015 07:36 | zed | Note Added: 0015648 | |
22-04-2015 08:04 | vdemidov | Note Added: 0015650 | |
22-04-2015 08:08 | zed | Note Added: 0015652 | |
22-04-2015 10:06 | vdemidov | Note Added: 0015656 | |
22-04-2015 10:42 | vasketsov | Note Added: 0015658 | |
22-04-2015 10:57 | vdemidov | Note Added: 0015665 | |
22-04-2015 11:05 | vasketsov | Note Added: 0015668 | |
23-04-2015 07:36 | vdemidov | Note Added: 0015684 | |
23-04-2015 08:17 | vasketsov | Note Added: 0015685 | |
23-04-2015 09:30 | vdemidov | Note Added: 0015693 | |
23-04-2015 15:39 | vasketsov | Note Added: 0015708 | |
23-04-2015 17:41 | vdemidov | Note Added: 0015710 | |
23-04-2015 18:48 | vasketsov | Note Added: 0015711 | |
23-04-2015 18:58 | vasketsov | Note Added: 0015712 | |
23-04-2015 21:04 | vdemidov | Note Added: 0015714 | |
24-04-2015 00:07 | vasketsov | Note Added: 0015716 | |
24-04-2015 04:26 | vasketsov | Note Added: 0015717 | |
24-04-2015 04:40 | zed | Note Added: 0015719 | |
24-04-2015 04:50 | zed | Note Added: 0015720 | |
24-04-2015 06:30 | vasketsov | Note Added: 0015722 | |
24-04-2015 07:58 | vdemidov | Note Added: 0015723 | |
26-04-2015 11:34 | vdemidov | Note Added: 0015759 | |
26-04-2015 11:50 | vasketsov | Note Added: 0015760 | |
26-04-2015 13:34 | vdemidov | Note Added: 0015770 | |
26-04-2015 13:39 | zed | Note Added: 0015773 | |
02-10-2015 19:51 | zed | Note Added: 0016509 | |
02-10-2015 20:43 | vdemidov | Note Added: 0016511 | |
02-10-2015 20:47 | zed | Note Added: 0016512 | |
02-10-2015 20:54 | vdemidov | Note Added: 0016513 | |
02-10-2015 21:06 | zed | Note Added: 0016514 | |
02-10-2015 21:09 | vdemidov | Note Added: 0016515 | |
04-10-2015 15:28 | vdemidov | Target Version | 151010 => 151111 |
09-10-2015 09:06 | vdemidov | Relationship replaced | parent of 0002166 |
13-10-2015 09:20 | vdemidov | Target Version | 151111 => 26xxxx |
28-10-2015 20:53 | vdemidov | Relationship added | child of 0002875 |
29-10-2015 11:05 | vdemidov | Relationship added | related to 0002877 |
30-10-2015 08:57 | vdemidov | Relationship added | child of 0002878 |
05-11-2015 07:51 | vdemidov | Note Added: 0016732 | |
05-11-2015 08:07 | vdemidov | Target Version | 26xxxx => 151111 |
05-11-2015 08:08 | vdemidov | Relationship replaced | child of 0002166 |
05-11-2015 22:23 | vdemidov | Note Added: 0016736 | |
06-11-2015 07:42 | vdemidov | Note Added: 0016738 | |
07-11-2015 19:17 | vdemidov | Status | confirmed => resolved |
07-11-2015 19:17 | vdemidov | Fixed in Version | => 151111 |
07-11-2015 19:17 | vdemidov | Resolution | open => fixed |
07-11-2015 19:17 | vdemidov | Assigned To | => vdemidov |
My View | View Issues | Change Log | Roadmap | Search |
Copyright © 2007 - 2024 SAS.Planet Team |