powered by simpleCommunicator - 2.0.37     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DataSet to JSon и обратно (mormot)
8 сообщений из 8, страница 1 из 1
DataSet to JSon и обратно (mormot)
    #40102083
bzums
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Созданию текстовое представление Поля типа 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
DataSet to JSon и обратно (mormot)
    #40102085
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bzums
Получается какой-то мусор.
у тебя какая-то ошибка.
я так думаю.
...
Рейтинг: 0 / 0
DataSet to JSon и обратно (mormot)
    #40102180
bzums
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я тоже так думаю :-)
Немного перефразирую вопрос
Простенький пример:
Код: 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
DataSet to JSon и обратно (mormot)
    #40102184
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
DataSet to JSon и обратно (mormot)
    #40102188
bzums
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не уверен, что понимаю, но это кусок кода из библиотеки. :-)
За сюрреализм не отвечаю тоже.
То есть кодирование так было уже сделано давным давно.

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

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

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

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

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

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


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

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

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

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


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