Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Столкнулся с одной проблемой. Пытаюсь её решить уже 6 месяцев, но она была не столь важна.
Сейчас эта проблема является уже критичной.

Суть проблемы в следующем.
Есть торговый терминал QUIK. Он пишет сообщения о результатах поданных операций/сделок.
Есть Каше, который считывает эти операции из файла.

Я вижу текст нормально.
Каше видит его ненормально. Точнее он вообще его не видит.
Проблема даже не в кодировке, а глубже, т.к. не совпадает кол-во символов.
См вложенный файл.

Все настройки локали стоят по умолчанию = Русский язык.

К сообщению приложен файл. Размер - 114Kb
11 июл 16, 12:03    [19394229]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Проблема в том, что когда Каше создаёт файл, и делает в него записи, то все нормально. Я вижу нормально и КАШЕ видит нормально.
Но стоит только сделать одну запись о сделанной операции в QUIK в данный файл, то запись сделанная Каше - становится в изменённой кодировке (но не вопросительные знаки (разные квазебяки), а ко-во символов примерно равно содержанию текста)).
И при попытке считать - новую строку с записью - получается как на рисунке - одни знаки вопроса, вместо русской кодировки.

К сообщению приложен файл. Размер - 49Kb
11 июл 16, 12:03    [19394234]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
А вот так выглядит файл (первоначально), сгенирированный Cache

Звонил разработчикам софта.
У них настройки изменить нельзя. Кодировку они не знают, в которой пишется запись в файл,
но даже если бы и сказали, я вообще не представляю как можно в каше поменять раскладку кодировки в считываемом файле.

Вопрос. Кто нибуть сталкивался с таким чудом и если да, то как это можно обойти или решить.
Посимвольное считывание - ничего не даёт. Да и вообще вариантов 20 перепробовал - результат один и тот же.
Каше все русские буквы воспринимает как
символ №63 в (знак ?)

К сообщению приложен файл. Размер - 32Kb
11 июл 16, 12:09    [19394281]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
О-О-О,

Приложите небольшой файл с "неверными" данными и код как его читаете/пишете.
11 июл 16, 12:12    [19394309]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
DAiMor
Member

Откуда: Volzhsky -> Moscow -> CZ, Brno -> Moscow
Сообщений: 2717
О-О-О
Проблема в том, что когда Каше создаёт файл, и делает в него записи, то все нормально. Я вижу нормально и КАШЕ видит нормально.
Но стоит только сделать одну запись о сделанной операции в QUIK в данный файл, то запись сделанная Каше - становится в изменённой кодировке (но не вопросительные знаки (разные квазебяки), а ко-во символов примерно равно содержанию текста)).
И при попытке считать - новую строку с записью - получается как на рисунке - одни знаки вопроса, вместо русской кодировки.

Картинка с другого сайта.
Проблема в кодировке, каше пишет в UTF-8, а QUIK видимо в CP1251

решение, использовать одну кодировку, и судя по всему в вашем случае это CP1251
11 июл 16, 12:13    [19394316]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Создаваемый файл, куда потом будут записываться данные из QUIK
 // Обнуляем файл ZayavkiRezultat.tro (Файл с данными об успешно отправленных транзакциях)
 
Set QuikZayavka=##class(%FileCharacterStream).%New()
 
Set QuikZayavka.Filename="C:\ObmenVB\ZayavkiRezultat.tro"
 
Set QuikZayavkawww="Первая запись, иначе потом глюки"
 
do QuikZayavka.WriteLine(QuikZayavkawww)
 
do QuikZayavka.SaveStream()
 
А это кусок кода, который считывает данные из этого файла
      file=##class(%File).%New("C:\ObmenVB\ZayavkiRezultat.tro")
      
sc=file.Open("R")
      
while 'file.AtEnd
      
{
        
Set Stroka=file.ReadLine()
        
if (Stroka="")||(Stroka=" ")||(Stroka="Первая запись, иначе потом глюки"{Goto EndZaprosRTO}
        
if StrNr>0
          
{
          
Set id=$p(Stroka,";",1) // получаем TRANS_ID=2;
          
Set id2=$Extract(id,1,9) // получаем TRANS_ID=
          
if id2="TRANS_ID=" {Set id3=$Extract(id,10,100)// 2
          
if id3=QuitMojNomerZayavki
          
{
            
Set id=$p(Stroka,";",2) // получаем STATUS=0;
            
Set id2=$Extract(id,1,7) // получаем STATUS=
            
if id2="STATUS=" {Set id3=$Extract(id,8,100)// 3
            
if id3=0 
            
{
              
Set NomerMMVB=50
              
Set www=$ZT(aaa)_(($PIECE($ZTIMESTAMP,",",2))#1)_"  Заявка на сделку ("_QiukOPERATION_") отправлена по цене "_QuikPRICE_" в количестве "_KolvoZayavka_" шт"
            
do History.WriteLine(www)
            
do History.SaveStream()
            
}
            
if id3=4 // «4» - транзакция не выполнена торговой системой, код ошибки торговой системы будет указан в поле «DESCRIPTION», 
            
{
11 июл 16, 12:16    [19394327]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
DAiMor
Member

Откуда: Volzhsky -> Moscow -> CZ, Brno -> Moscow
Сообщений: 2717
пример кода с чтением в нужной кодировке
    set fs=##class(%Stream.FileCharacter).%New()
    
set fs.TranslateTable="CP1251"
    
set fs.Filename="c:/temp/quik.txt"
    
    
while 'fs.AtEnd {
        
set line=fs.ReadLine()
        
write !,line
    
}
11 июл 16, 12:16    [19394328]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
      file=##class(%File).%New("C:\ObmenVB\ZayavkiRezultat.tro")
      
sc=file.Open("R")
      
while 'file.AtEnd
      
{
        
Set Stroka=file.ReadLine()
        
if (Stroka="")||(Stroka=" ")||(Stroka="Первая запись, иначе потом глюки"{Goto EndZaprosRTO}
        
if StrNr>0
          
{
          
Set id=$p(Stroka,";",1) // получаем TRANS_ID=2;
          
Set id2=$Extract(id,1,9) // получаем TRANS_ID=
          
if id2="TRANS_ID=" {Set id3=$Extract(id,10,100)// 2
          
if id3=QuitMojNomerZayavki
          
{
            
Set id=$p(Stroka,";",2) // получаем STATUS=0;
            
Set id2=$Extract(id,1,7) // получаем STATUS=
            
if id2="STATUS=" {Set id3=$Extract(id,8,100)// 3
            
if id3=0 
            
{
              
Set NomerMMVB=50
              
Set www=$ZT(aaa)_(($PIECE($ZTIMESTAMP,",",2))#1)_"  Заявка на сделку ("_QiukOPERATION_") отправлена по цене "_QuikPRICE_" в количестве "_KolvoZayavka_" шт"
            
do History.WriteLine(www)
            
do History.SaveStream()
            
}
            
if id3=4 // «4» - транзакция не выполнена торговой системой, код ошибки торговой системы будет указан в поле «DESCRIPTION», 
            
{
              
Set NomerMMVB=4500
              
.........
11 июл 16, 12:17    [19394344]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
DAiMor,
Вы мой спаситель.
Про TranslateTable я читал в инструкции, пробовал, но ничего не получалось.
11 июл 16, 12:25    [19394400]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
О-О-О
DAiMor,
Вы мой спаситель.
Про TranslateTable я читал в инструкции, пробовал, но ничего не получалось.


К сообщению приложен файл. Размер - 108Kb
11 июл 16, 12:26    [19394407]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1566
Не буду открывать новый топик: хочу лишь немного обобщить. Сам столкнулся с подобным явлением, пытаясь добиться обмена двоичными данными между Cache-8-бит и Cache-Unicode через файлы.

Сделал тщетную попытку передавать их, используя RAW-формат, создавая файлы стандартными средствами Cache (пробовал и команду Write, и даже высокоуровневый %Stream.FileBinary). Не получилось: если в Cache-Unicode файл открыт с таблицей RAW, любой записываемый символ с кодом >127 превращается в "?". По-видимому, причина этого явления - нестандартность внутренней кодировки Unicode в Cache; Cache как бы "сопротивляется" переносу её во внешние файлы.

Файл должен быть в одной из стандартных кодировок, которую понимает Cache (перечень есть в определении локали). Что касается двоичных данных, которые нельзя подвергать кодовым преобразованиям (т.к. в Cache-8-бит и Cache-Unicode они будут закодированы/декодированы по-разному), то для них похоже нет другого варианта, кроме предварительного ("неразрушающего") кодирования в Base64, передачу в любой кодировке (разумное решение - в UTF8) и декодирования из Base64 на другом конце.

Коллеги, поправьте плиз, если я что-то проглядел.
11 июл 16, 12:32    [19394445]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
О-О-О,

Files and Character Encoding

Также кодировку (K\name\) можно указать непосредственно при открытии файла: 4251944, 8130087 (примеры)
 file=##class(%File).%New("C:\ObmenVB\ZayavkiRezultat.tro")
 
sc=file.Open("RK\CP1251\")
11 июл 16, 12:43    [19394514]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
servit
О-О-О,

Files and Character Encoding

Также кодировку (K\name\) можно указать непосредственно при открытии файла: 4251944, 8130087 (примеры)
 file=##class(%File).%New("C:\ObmenVB\ZayavkiRezultat.tro")
 
sc=file.Open("RK\CP1251\")


Да, и он также работает.
Но как я понял, каше стал больше переходить на работу с %Stream. и его производными.
Ваш вариант (вариант 'Servit') оптимален при работе с версиями где в коде используется class(%File), а не ##class(%Stream.
Именно при попытке совместить class(%File)+file.TranslateTable и была ошибка.
Поэтому или работаете с форматом ##class(%Stream. и применяете Set file.TranslateTable

или работаете с классом #class(%File) НО тогда используете код s sc=file.Open("RK\CP1251\"). Это скользкий момент, который приводил в моем случае к неработоспособности кода по преобразованию кодировок.

Вариант, указанный 'Servit' подходит тем, у кого код написан еще через #class(%File)
11 июл 16, 14:07    [19395057]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Да, раз пошла такая тема.

Эти два варианта открытия и обработки внешнего файла
через класс class(%File)
и класс class(%Stream.ххх)
СУЩЕСТВЕННО ОТЛИЧАЮТСЯ ПО СКОРОСТИ
Буквально неделю назад перешёл с class(%File) на class(%Stream.ххх) и проверил скорость обработки.
Код был идентичен, только строчки из внешнего файла открывал по разному.
Через class(%File) обработка длилась 10,7-10,8 сек
а через class(%Stream.File...) тот же код уже обрабатывался за 8,2-8,3 сек.
В общем, разница была около 30% и ТОЛЬКО ЗА СЧЕТ ИЗМЕНЕНИЯ 2-Х строчек в коде!
11 июл 16, 14:18    [19395122]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
И ещё одно.
через class(%File) нельзя открывать большие файлы (подвисают)
а с помощью class(%Stream.ххх) запросто можно обрабатывать файлы с данными под 80 Мб (более крыпных файлов не было),
тогда как class(%File) уже на 4 Мб начинает жутко капризничать.
11 июл 16, 14:22    [19395154]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
О-О-О
И ещё одно.
через class(%File) нельзя открывать большие файлы (подвисают)
Можно. Жили же как-то до этого. И скорость будет не меньше, если писать код оптимально.
Более того новые классы любезно используют класс %File, а все вместе - вполне себе ламповые open/use/close.
11 июл 16, 14:39    [19395258]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
Alexey Maslov
Сам столкнулся с подобным явлением, пытаясь добиться обмена двоичными данными между Cache-8-бит и Cache-Unicode через файлы.
Кое-что исправили в 2016.2: CDS2714 - Correct I/O translation of variable length records

С этим патчем уже можно пробовать мой предыдущий пример (19116165) для сравнения обоих подходов.
11 июл 16, 15:31    [19395586]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1566
servit
Кое-что исправили в 2016.2: CDS2714 - Correct I/O translation of variable length records
...
С этим патчем уже можно пробовать мой предыдущий пример (19116165) для сравнения обоих подходов.
Этот патч, судя по всему, решает несколько иную проблему; на эти грабли тоже наступал (знаем, плавали :).

Моя ситуация несколько иная: я работаю с файлами, открывая их как "UK\table\", т.е.:
- не пользуюсь кашовскими записями (ни "S", ни "V"), организую всё это хозяйство сам;
- перекодировку текстовых строк в/из UTF8 тоже делаю сам ($zcvt(...));
- а вот двоичные данные хотел бы передавать как есть (RAW).

В таких условиях для передачи файлов между системами с разной "битностью" (8 бит vs Unicode) представляется естественным использовать table="RAW"; ан нет, не работает, хотя бы потому, что Cache-Unicode, как оказалось, пишет в этом случае "?" вместо любого символа с кодом > 127.
11 июл 16, 16:01    [19395783]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
Alexey Maslov
В таких условиях для передачи файлов между системами с разной "битностью" (8 бит vs Unicode) представляется естественным использовать table="RAW"; ан нет, не работает, хотя бы потому, что Cache-Unicode, как оказалось, пишет в этом случае "?" вместо любого символа с кодом > 127.
Скорее всего дело во внутреннем представлении строки.
Если двухбайтную строку предварительно преобразовать в однобайтную, то RAW перестаёт заменять на "?" вместо любого символа с кодом > 127.

Например:
w $zv,!
s=$zcvt("Cach%E9%20%2B%20%u0437%u0430%u043F%u0440%u043E%u0441%20%2B%20%u0103%EE%u015F%u0163%E2","I","URL")
;или s s="Caché + запрос + ăîşţâ"

zzdump s

i="RAW","SAME" n=$zcvt(s,"O",izzdump !,$$$quote(i),": ",$$$quote(n),!
i="","RAW","BIN","SAME","Unicode","UTF8","CP1251","CP866","KOI8R" n=$zcvt(s,"O",i/*zzdump n*/ !,$$$quote(i)," : ",$zcvt(n,"I",i)=$zcvt($zcvt(n,"I","RAW"),"I",i)

USER>^test
Cache for Windows (x86-64) 2016.3 (Build xxxU)

0000: 0043 0061 0063 0068 00E9 0020 002B 0020 Caché +
0008: 0437 0430 043F 0440 043E 0441 0020 002B запрос +
0010: 0020 0103 00EE 015F 0163 00E2 ăîşţâ

0000: 43 61 63 68 E9 20 2B 20 3F 3F 3F 3F 3F 3F 20 2B Caché + ?????? +
0010: 20 3F EE 3F 3F E2 ?î??â
"RAW": "Caché + ?????? + ?î??â"

0000: 43 00 61 00 63 00 68 00 E9 00 20 00 2B 00 20 00 C.a.c.h.é. .+. .
0010: 37 04 30 04 3F 04 40 04 3E 04 41 04 20 00 2B 00 7.0.?.@.>.A. .+.
0020: 20 00 03 01 EE 00 5F 01 63 01 E2 00 ...î._.c.â.
"SAME": "Caché + 70?@>A + î_câ"

"" : 1
"RAW" : 1
"BIN" : 1
"SAME" : 1
"Unicode" : 1
"UTF8" : 1
"CP1251" : 1
"CP866" : 1
"KOI8R" : 1
В 8-битной версии Caché строки и так уже однобайтные, поэтому "RAW" там работает без лишних телодвижений.

Возможно для Unicode Вам вместо "RAW" подойдёт "SAME"?
11 июл 16, 16:56    [19396108]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1566
servit,

спасибо за BIN - не знал о её существовании - в чём её "физический смысл"?

В вашем примере "RAW" применяется к строке, которая уже содержит искажённые данные (замены на "?"). Если тупо сравнивать исходную строку с результатом обратной перекодировки, результат будет иным:
+
write !,$zv,! set s=$zcvt("Cach%E9%20%2B%20%u0437%u0430%u043F%u0440%u043E%u0441%20%2B%20%u0103%EE%u015F%u0163%E2","I","URL") f i="","RAW","BIN","SAME","Unicode","UTF8" s n=$zcvt(s,"O",i) w !,i," : ",s=$zcvt(n,"I",i) zzdump n

Cache for Windows (x86-64) 2015.1.4 (Build 803_0_16388U) Fri May 13 2016 15:16:38 EDT

: 0
0000: 43 61 63 68 E9 20 2B 20 3F 3F 3F 3F 3F 3F 20 2B Caché + ?????? +
0010: 20 3F EE 3F 3F E2 ?î??â
RAW : 0
0000: 43 61 63 68 E9 20 2B 20 3F 3F 3F 3F 3F 3F 20 2B Caché + ?????? +
0010: 20 3F EE 3F 3F E2 ?î??â
BIN : 0
0000: 43 61 63 68 E9 20 2B 20 3F 3F 3F 3F 3F 3F 20 2B Caché + ?????? +
0010: 20 3F EE 3F 3F E2 ?î??â
SAME : 1
0000: 43 00 61 00 63 00 68 00 E9 00 20 00 2B 00 20 00 C.a.c.h.é. .+. .
0010: 37 04 30 04 3F 04 40 04 3E 04 41 04 20 00 2B 00 7.0.?.@.>.A. .+.
0020: 20 00 03 01 EE 00 5F 01 63 01 E2 00 ...î._.c.â.
Unicode : 1
0000: 43 00 61 00 63 00 68 00 E9 00 20 00 2B 00 20 00 C.a.c.h.é. .+. .
0010: 37 04 30 04 3F 04 40 04 3E 04 41 04 20 00 2B 00 7.0.?.@.>.A. .+.
0020: 20 00 03 01 EE 00 5F 01 63 01 E2 00 ...î._.c.â.
UTF8 : 1
0000: 43 61 63 68 C3 A9 20 2B 20 D0 B7 D0 B0 D0 BF D1 Caché + запÑ
0010: 80 D0 BE D1 81 20 2B 20 C4 83 C3 AE C5 9F C5 A3 .оÑ. + Ä.îÅ.Å£
0020: C3 A2 â
12 июл 16, 11:23    [19398700]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
Alexey Maslov
В вашем примере "RAW" применяется к строке, которая уже содержит искажённые данные (замены на "?")
Я знаю.
Смысл был в том, чтобы показать, что RAW не портит именно однобайтные строки в какой бы кодировке они ни были.

А изначальная строка именно что двухбайтная:
USER>set s2=$zcvt("Cach%E9%20%2B%20%u0437%u0430%u043F%u0440%u043E%u0441%20%2B%20%u0103%EE%u015F%u0163%E2","I","URL"),s1=$zcvt(s2,"O","SAME")

USER>zzdump s2,$c(0),s1
0000: 0043 0061 0063 0068 00E9 0020 002B 0020 Caché +
0008: 0437 0430 043F 0440 043E 0441 0020 002B запрос +
0010: 0020 0103 00EE 015F 0163 00E2 ăîşţâ
0000: 00 .
0000: 43 00 61 00 63 00 68 00 E9 00 20 00 2B 00 20 00 C.a.c.h.é. .+. .
0010: 37 04 30 04 3F 04 40 04 3E 04 41 04 20 00 2B 00 7.0.?.@.>.A. .+.
0020: 20 00 03 01 EE 00 5F 01 63 01 E2 00 ...î._.c.â.

USER>w $l(s2),": ",s2,!,$l(s1),": ",s1
22: Caché + запрос + ăîşţâ
44: Caché + 70?@>A + î_câ
Соответственно:
USER>r2=$zcvt(s2,"O","RAW"),r1=$zcvt(s1,"O","RAW"zzdump r2,$c(0),r1 !!,$l(r2),": ",r2,!,$l(r1),": ",r1

0000: 43 61 63 68 E9 20 2B 20 3F 3F 3F 3F 3F 3F 20 2B Caché + ?????? +
0010: 20 3F EE 3F 3F E2 ?î??â
0000: 00 .
0000: 43 00 61 00 63 00 68 00 E9 00 20 00 2B 00 20 00 C.a.c.h.é. .+. .
0010: 37 04 30 04 3F 04 40 04 3E 04 41 04 20 00 2B 00 7.0.?.@.>.A. .+.
0020: 20 00 03 01 EE 00 5F 01 63 01 E2 00 ...î._.c.â.

22: Caché + ?????? + ?î??â
44: Caché + 70?@>A + î_câ
12 июл 16, 11:54    [19398945]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
Alexey Maslov
спасибо за BIN - не знал о её существовании - в чём её "физический смысл"?
Это историческое название для RAW. Оставлено для совместимости с legacy-кодом у некоторых заказчиков.

Что касается RAW для Unicode, то мои предположения подтвердились: RAW для перевода двухбайтной строки в однобайтную не подходит.
Для максимальной совместимости экспорта/импорта глобалов между 8-битной и Unicode версиями производителем рекомендуется использовать UTF8, который нечувствителен к порядку следования байт (04 37 или 37 04) и экономичнее Unicode.

Документация относительно поведения RAW в 8-битной и Unicode версиях будет в скором времени уточнена.
21 июл 16, 12:53    [19435741]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1566
servit,

спасибо за продолжение обсуждения.
servit
RAW для перевода двухбайтной строки в однобайтную не подходит
Это было ясно изначально (e.g. $char(1040) => $char(63)).

Насчёт UTF8 пришёл к тому же выводу: вполне подходит для передачи текстовых данных между 8-bit и Unicode "туда и обратно" (обратно, конечно, с очевидными ограничениями).

Двоичные данные проще всего распаковать в текстовые перед передачей и снова запаковать в двоичные после неё.
Без такого преобразования возможна лишь передача "чисто двоичных" однобайтных данных в формате RAW, но такая возможность представляет лишь академический интерес, т.к. в составе того или иного глобала почти всегда есть текстовые поля (которые при передаче без перекодировки портятся).

На случай, если это обсуждение интересно кому-то ещё, кроме нас двоих: простейший пример смешанных данных - список, e.g.
 set lsA=$lb($tr($j("",32760)," ","А"))
В Cache 8-bit его внутренний формат (показан заголовок и первые байты первого элемента):
USER>zzdump $e(lsA,1,4+6)

0000: 00 F9 7F 01 C0 C0 C0 C0 C0 C0 .щ..АААААА
В Cache Unicode:
USER>zzdump $e($lb(lsA),1,4+12)

0000: 00 F1 FF 02 10 04 10 04 10 04 10 04 10 04 10 04 .ñÿ.............
Если передавать в UTF8, испортится заголовок списка (первые 4 байта). Если передавать в RAW, список сохранит корректность, но в неверной кодировке придут данные.
21 июл 16, 15:19    [19437093]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3119
Блог
Alexey Maslov
servit
W для перевода двухбайтной строки в однобайтную не подходит
Это было ясно изначально (e.g. $char(1040) => $char(63)).
Ясно что?
Что не подходит согласно дизайну (так изначально задумано) или быть может это просто баг, который нужно исправить?
В итоге оказалось что так и было задумано. Поэтому-то документацию обновят, чтобы в дальнейшем не возникало вопросов.
Alexey Maslov
Если передавать в UTF8, испортится заголовок списка (первые 4 байта). Если передавать в RAW, список сохранит корректность, но в неверной кодировке придут данные.
У меня на версии Cache for Windows (x86-64) 2016.3 (Build 000U) обе кодировки ничего не портят:
+ Код:
!,"------- RAW -----------",!!
listOutRAW=$lb("Caché","запрос","ăîşţâ")
"Before:"
zzdump listOutRAW

fOutRAW=##class(%Stream.FileBinary).%New()
fOutRAW.Filename="c:\temp\listRAW.txt"

fOutRAW.Write(listOutRAW)
fOutRAW.%Save()

fInRAW=##class(%Stream.FileBinary).%New()
fInRAW.Filename="c:\temp\listRAW.txt"

listInRAW=fInRAW.Read()
!!,"After:"
zzdump listInRAW

!!,$lts(listInRAW)," : ",$ll(listInRAW),!

!,"------- UTF8 -----------",!!
listOutUTF8=$lb("Caché","запрос","ăîşţâ")
"Before:"
zzdump listOutUTF8

fOutUTF8=##class(%Stream.FileCharacter).%New()
fOutUTF8.Filename="c:\temp\listUTF8.txt"
fOutUTF8.TranslateTable="UTF8"

fOutUTF8.Write(listOutUTF8)
fOutUTF8.%Save()

fInUTF8=##class(%Stream.FileCharacter).%New()
fInUTF8.Filename="c:\temp\listUTF8.txt"
fInUTF8.TranslateTable="UTF8"

listInUTF8=fInUTF8.Read()
!!,"After:"
zzdump listInUTF8

!!,$lts(listInUTF8)," : ",$ll(listInUTF8),!
+ Результат:
USER>^test

------- RAW -----------

Before:
0000: 07 01 43 61 63 68 E9 0E 02 37 04 30 04 3F 04 40 ..Caché..7.0.?.@
0010: 04 3E 04 41 04 0C 02 03 01 EE 00 5F 01 63 01 E2 .>.A.....î._.c.â
0020: 00 .

After:
0000: 07 01 43 61 63 68 E9 0E 02 37 04 30 04 3F 04 40 ..Caché..7.0.?.@
0010: 04 3E 04 41 04 0C 02 03 01 EE 00 5F 01 63 01 E2 .>.A.....î._.c.â
0020: 00 .

Caché,запрос,ăîşţâ : 3

------- UTF8 -----------

Before:
0000: 07 01 43 61 63 68 E9 0E 02 37 04 30 04 3F 04 40 ..Caché..7.0.?.@
0010: 04 3E 04 41 04 0C 02 03 01 EE 00 5F 01 63 01 E2 .>.A.....î._.c.â
0020: 00 .

After:
0000: 07 01 43 61 63 68 E9 0E 02 37 04 30 04 3F 04 40 ..Caché..7.0.?.@
0010: 04 3E 04 41 04 0C 02 03 01 EE 00 5F 01 63 01 E2 .>.A.....î._.c.â
0020: 00 .

Caché,запрос,ăîşţâ : 3
Размер: listRAW.txt = 33 байта, listUTF8.txt = 36 байт.
21 июл 16, 17:06    [19437839]     Ответить | Цитировать Сообщить модератору
 Re: Несовместимость кодировок.  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1566
servit
У меня на версии Cache for Windows (x86-64) 2016.3 (Build 000U) обе кодировки ничего не портят
Правильно, потому что и пишет, и читает - Unicode-версия.
Если записать $lb(мой, с длинной кириллической строкой) в Cache 8-бит, а читать в Cache Unicode, вариантов нет - что-нибудь да испортится: либо заголовок элемента списка, либо данные в элементе списка.
21 июл 16, 17:24    [19437918]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить