Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DataSet to JSon и обратно (mormot) / 8 сообщений из 8, страница 1 из 1
05.10.2021, 13:44
    #40102083
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
Созданию текстовое представление Поля типа binary и longvarbinary.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
uses
  SynTable, SynCommons, Uni, UniProvider, ODBCUniProvider, System.NetEncoding;

procedure TForm13.Button1Click(Sender: TObject);
var w: TJSONWriter;
    f: integer;
    blob: TRawByteStringStream;
    LBytes : TArray<byte>;
    LString: string;
    bfs: TBufferedFileStream;

begin
  bfs := TBufferedFileStream.Create( 'c:\temp\xxx.json', fmCreate);
  w := TJSONWriter.Create(bfs, True, False);
  try
    while not UniQuery1.Eof do begin
        for f := 0 to UniQuery1.FieldCount - 1 do begin
          with UniQuery1.Fields[f] do
            case DataType of
            ftBytes: begin
              LBytes := AsBytes;
              LString := TEncoding.UTF8.GetString(LBytes);
              w.WrBase64(pointer(LString), length(LString), true);
            end;
            ftVarBytes, ftBlob: begin
              blob := TRawByteStringStream.Create;
              try
                (UniQuery1.Fields[f] as TBlobField).SaveToStream(blob);
                w.WrBase64(pointer(blob.DataString), length(blob.DataString), True);
              finally
                blob.Free;
              end;
            end;
          end;
        UniQuery1.Next;
      end;
      w.CancelLastComma;
      w.FlushFinal;
    end;
  finally
    w.Free;
    bfs.Free;
  end;
end;


Так получается для значения 0x123456 строка вида "￰￰EjRW" (первый символ квадратик, он тут не получился).

Как мне обратно получить из этой строки обратно binary? Получается какой-то мусор.
ВОт пример тоже:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
var 
  Data: variant;
  t: string;
  field: TField;
  ss: TStringStream;
  sm: TMemoryStream;

 for field in UniQuery.Fields do begin
      case field.DataType of
        ftBoolean:
          field.AsBoolean := VarToStr(Data).ToBoolean;
        ftInteger, ftSmallint, ftShortint, ftLongWord, ftWord, ftByte:
          field.AsInteger := StrToIntDef(Data, 0);
        ftFloat, ftCurrency:
          field.AsCurrency := StrToCurr(Data);
        ftBytes:
          begin
            ss := TStringStream.Create(VarToStr(Row.Value(i)));
            try
              ss.Position := 0;
              sm := TMemoryStream.Create;
              try
                TNetEncoding.Base64.Decode(ss, sm);
                SetString(t, PChar(sm.Memory), sm.Size div SizeOf(Char));
               finally
                sm.Free;
              end;
            finally
              ss.Free;
            end;
          end;

        ftBlob:
          begin
            ss := TStringStream.Create(VarToStr(Data);
            try
              ss.Position := 0;
              sm := TMemoryStream.Create;
              try
               [TNetEncoding.Base64.Decode(ss, sm);
//в какую переменную LoadFromStream(sm) ????
               finally
                sm.Free;
              end;
            finally
              ss.Free;
            end;
    end;



Заранее большое спасибо
...
Рейтинг: 0 / 0
05.10.2021, 13:49
    #40102085
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
bzums
Получается какой-то мусор.
у тебя какая-то ошибка.
я так думаю.
...
Рейтинг: 0 / 0
05.10.2021, 20:25
    #40102180
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
Я тоже так думаю :-)
Немного перефразирую вопрос
Простенький пример:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  LBytes: TArray<byte>;
  bytes: TBytes;
begin
//туда
  LBytes := UniQuery1.FieldByName('yyy').AsBytes;
  s1 := TEncoding.UTF8.GetString(LBytes);
  s2 := TNetEncoding.Base64.Encode(s1);


//обратно
  s3 := TNetEncoding.Base64.Decode(s2);
  //bytes := TEncoding.UTF8.GetBytes(s3);
  LBytes := TEncoding.UTF8.GetBytes(s3);


Этот код работает - из базы нормально тянет 0x123456 в текст "EjRW" и обратно.
Но я использую Mormot / Synopse, приблизительно так (код немного другой):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        ftBytes: begin
          LBytes := AsBytes;
          Lstring := TEncoding.UTF8.GetString(LBytes);
          W.WrBase64(pointer(LString), length(LString), true);
        end;
        ftBlob: begin
          blob := TRawByteStringStream.Create;
          try
            (Data.Fields[f] as TBlobField).SaveToStream(blob);
            W.WrBase64(pointer(blob.DataString), length(blob.DataString), true);
          finally
            blob.Free;
          end;
        end;


В целом работает,
но, что интересно, между ТУДА и ОБРАТНО строка "EjRW" в самом начале содержит $FFF0.
То есть этот метод WrBase64 в начало вставляет это.
В результате при обратном преобразовании я имею не $18 $52 и $86, а через один - $18 $00 $52 $00 $86 $00, но длина та же.

Как это победить?
Очень похоже на то, что то как поле базы данных binary посредством ODBC видится как ftBytes, а nlongvarbinary - ftBlob реализовано некорректно.

Надо чтоли явно указать как их рассматривать....
Или что-то еще придумать. Не пробовал, но если убрать из текмта этк добавку, то все будет нормально скорее всего.

Всем заранее спасибо за советы.
...
Рейтинг: 0 / 0
05.10.2021, 20:36
    #40102184
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
bzums
Код: sql
1.
2.
Lstring := TEncoding.UTF8.GetString(LBytes);
W.WrBase64(pointer(LString), length(LString), true);

Вы понимаете, что делают эти строки?
bzums
Код: sql
1.
 W.WrBase64(pointer(blob.DataString), length(blob.DataString), true);

А это, что за сюрреализм?
...
Рейтинг: 0 / 0
05.10.2021, 20:52
    #40102188
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
Не уверен, что понимаю, но это кусок кода из библиотеки. :-)
За сюрреализм не отвечаю тоже.
То есть кодирование так было уже сделано давным давно.

Моя задача - принять это все обратною

Хотя можно и поменять наверное, раз уж это является причиной всего этого чудачества...

Наверное формально можно сделать и вовсе без всякого кодирования - StrToBytes и BytesToStr.

Да, если убрать из начала FFF0 и оставить чисто строку 'EjRWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
то все нормально, получаю обратно то, что и было закодировано.

Спасибо.
...
Рейтинг: 0 / 0
05.10.2021, 21:48
    #40102195
Zelius
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
bzums,

не уверен, что там в LString, но разве не так - W.WrBase64(pointer(LString), length(LString) * 2 , true) ?
ну и base64 для кодирования байт уже, так что зачем из байт делать WideString и потом из него base64 - загадка...
...
Рейтинг: 0 / 0
05.10.2021, 22:23
    #40102201
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
Спасибо за инфу к размышлению.
Буду смотреть.
По правде говоря, кроме как об экономии места у меня никаких мыслей нет.


Есть ли какая разница, blob поле или простое binary?
Ну кроме размера конечно.
То есть модно ли из абсолютно одинаково рассматривать? ( То есть и импортировать и экспортировать ?)

И самое главное - если вовсе не производить кодирование? На что это влияет кроме размера?

Большое спасибо всем.
...
Рейтинг: 0 / 0
06.10.2021, 13:34
    #40102328
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataSet to JSon и обратно (mormot)
length(LString) * 2 - в точку
Но почему в выходном файле blob получается через раз 00?
И как мне избавиться от этих четных байтов?

Спасибо
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DataSet to JSon и обратно (mormot) / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]