Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Firebird, InterBase Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Здравствуйте!

Перевожу пример 10.backup.cpp на Pascal (Delphi XE10). Возникли проблемы с функцией printInfo. Функцию isc-vax-integer нашел этой теме: https://www.sql.ru/forum/1325822/isc-vax-integer-i-iattachment но не могу понять, подходит ли PortableInteger для этой ситуации.

Наивная трансляция получилась следующая:
+

//by _Vasilisk_ 
function PortableInteger(APtr: Pointer; ASize: Integer): Int64;
type
  TValue = record
  case Byte of
    1: (v1: ShortInt);
    2: (v2: SmallInt);
    4: (v4: Integer);
    8: (v8: Int64);
    255: (reserved: array[0..7] of ShortInt);
  end;
var
  LValue: ^TValue absolute APtr;
  Li: integer;
begin
  case ASize of
    SizeOf(LValue^.v1): Result := LValue^.v1;
    SizeOf(LValue^.v2): Result := LValue^.v2;
    SizeOf(LValue^.v4): Result := LValue^.v4;
    SizeOf(LValue^.v8): Result := LValue^.v8;
  else
    if LValue^.reserved[ASize - 1] < 0 then
      Result := -1
    else
      Result := 0;
    for Li := ASize - 1 downto 0 do
      Result := (Result shl 8) or (LValue^.reserved[Li] and $FF);
  end;
end;

function PrintLine(var p: BytePtr; var outBuffer: string): boolean;
var
  Length: word;
begin
  Length := word(PortableInteger(p, sizeof(word)));
  p := BytePtr(NativeUInt(p) + sizeof(word));
  if Length > 0 then
    outBuffer := outBuffer + Format('%s'#13#10, [PAnsiChar(p)]);
  p := BytePtr(NativeUInt(p) + Length);
  Result := Length > 0;
end;

function PrintInfo(p: BytePtr; pSize: cardinal; var outBuffer: string): boolean;
var
  pEnd: BytePtr;
begin
  Result := False;
  pEnd := BytePtr(NativeUInt(p) + pSize);
  while ((NativeUInt(p) < NativeUInt(pEnd)) and (p^ <> isc_info_end)) do begin
    case p^ of
      isc_info_svc_line: begin
        Result := PrintLine(p, outBuffer);
        break;
      end;
      isc_info_truncated: begin
        outBuffer := outBuffer + #13#10'<<< truncated >>>'#13#10;
        Result := True;
        break;
      end;
      isc_info_svc_timeout, isc_info_data_not_ready: begin
        Result := True;
        break;
      end
      else begin
        outBuffer := outBuffer + Format('Unknown item 0x%x in received buffer'#13#10, [NativeUInt(p) - 1]);
        break;
      end;
    end;
  end;
end;

...
      repeat
        svc.query(st, 0, nil, sizeof(receiveItems2), @receiveItems2, sizeof(results), @results);
      until PrintInfo(@results, sizeof(results), outBuffer);
...


при выполнении ошибок не выдает, но в outBuffer записывается мусор.
13 янв 21, 16:28    [22262780]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804
Строки в буфере не нуль-терминированные.

И уж тем более - не юникодные.

Сообщение было отредактировано: 13 янв 21, 17:14
13 янв 21, 17:19    [22262819]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Dimitry Sibiryakov,

Я смотрел значение PAnsiChar(p) в отладчике, там проблемы с не-нуль-терминированностью еще нет. Проблема где-то гораздо раньше.
13 янв 21, 17:36    [22262831]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

nicholaos
Я смотрел значение PAnsiChar(p) в отладчике

Ну значит ты можешь в том же отладчике посмотреть где, когда и откуда в outBuffer попадает
мусор и не морочить нам хрустальные шары.

Posted via ActualForum NNTP Server 1.5

13 янв 21, 18:38    [22262857]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
nicholaos,

зачем изобретать велосипед, когда и isc_vax_integer, и isc_portable_integer экспортируются из fbclient.dll,
которая в любом случае загружена процессом ?
13 янв 21, 18:59    [22262867]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
nicholaos
 255: (reserved: array[0..7] of ShortInt);
ShortInt ? Это что, нынче 1 байт ?
13 янв 21, 19:00    [22262868]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
hvlad
ShortInt ? Это что, нынче 1 байт ?[/quote]Таки да, 1.
Странный выбор названия для этого типа.
Всегда short был 2 байта и tiny - 1 байт.
"Плюс" в карму тому, кто так поиздевался...
13 янв 21, 19:13    [22262876]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
hvlad,

Переделал PrintLine так:

+

function PrintLine(hLib: HMODULE; var p: BytePtr; var outBuffer: string): boolean;
var
  Length: long;
  s: string;
  ss: short;
  isc_vax_integer: function(Ptr: BytePtr; Length: short): long;
begin
  @isc_vax_integer := GetProcAddress(hLib, 'isc_vax_integer');
  ss := sizeof(word);
  Length := isc_vax_integer(p, ss);
  p := BytePtr(NativeUInt(p) + sizeof(word));
  if Length > 0 then begin
    s := PAnsiChar(p);
    outBuffer := outBuffer + Format('%s'#13#10, [s]);
  end;
  p := BytePtr(NativeUInt(p) + Length);
  Result := Length > 0;
end;



isc_vax_integer возвращает 0. Может неправильно объявил? Ориентировался на
SLONG API_ROUTINE isc_vax_integer(const SCHAR* input, SSHORT length)

PrintLine из вызывается PrintInfo (p в PrintLine - это @results):

Картинка с другого сайта.

т.е. данные в results есть и раз бэкап успешно создается, скорее всего правильные. Значение p - $18F054. Соответственно, p^ - 62.
14 янв 21, 09:54    [22263057]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
nicholaos
isc_vax_integer: function(Ptr: BytePtr; Length: short): long;
stdcall забыл
14 янв 21, 10:57    [22263090]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
hvlad,

Точно. Теперь isc_vax_integer вернул то же, что и PortableInteger - 62. В любом случае, строки по адресу p + sizeof(word) нет, любой длины.
14 янв 21, 11:45    [22263130]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
Идём дальше.
nicholaos
  p := BytePtr(NativeUInt(p) + sizeof(word));
Почему не Inc(p, 2) ?

nicholaos
  if Length > 0 then begin
    s := PAnsiChar(p);
Это не правильно - как минимум потому, что строки не терминируются нулями (как тут уже говорилось)

nicholaos
В любом случае, строки по адресу p + sizeof(word) нет, любой длины.
Конечно, на картинке p указывает на самое начало results - там находятся теги и только потом сами строки.
В данном случе в results лежит 62, 0, 0, 1, 0, 0, 0, 0...
62 - isc_info_svc_line
0, 0 - длина строки (0)
1 - isc_info_end
14 янв 21, 12:17    [22263159]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
hvlad,

Т.е. на самом деле никакой информации там нет? Я думал будет лог по типу того, что выдает gbak. Тогда проще вообще удалить PrintInfo.
14 янв 21, 13:39    [22263237]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Симонов Денис
Member

Откуда: Рязань
Сообщений: 11092
nicholaos,

это смотря с какими ты ключами gbak запускаешь (тегами в данном случае). Он может лог операций выдавать в буфер, если ты его не в лог файл пишешь
14 янв 21, 13:44    [22263243]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

nicholaos
Т.е. на самом деле никакой информации там нет? Я думал будет лог по типу того, что выдает
gbak.

Так gbak ничего и не выдаёт при тех же условиях запуска. Поэтому и от сервисов ты
получаешь то же самое ничего.

Posted via ActualForum NNTP Server 1.5

14 янв 21, 13:45    [22263246]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Симонов Денис, Dimitry Sibiryakov,

Точно тэг? Добавил spb2.insertTag(st, isc_action_svc_get_fb_log); получил ошибку
Internal error when using clumplet API: attempt to store 0 bytes in a clumplet, need 1

Если сделать так:
spb2.insertInt(st, isc_spb_options, isc_action_svc_get_fb_log);

ошибки нет, но и результата нет.
14 янв 21, 14:15    [22263277]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

Продолжайте случайный поиск. Через бесконечное количество лет вам удастся воспроизвести
второй том "Мёртвых душ".

Posted via ActualForum NNTP Server 1.5

14 янв 21, 14:21    [22263285]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
nicholaos
Я думал будет лог по типу того, что выдает gbak.
А ты его об этом попросил ?
hint: isc_spb_verbose

nicholaos
Тогда проще вообще удалить PrintInfo.
Проще вообще всё удалить.

nicholaos
Добавил ... spb2.insertInt(st, isc_spb_options, isc_action_svc_get_fb_log);
Это в тот же spb, в котором уже есть isc_action_svc_backup ?
Может API Guide почитать сначала ?

PS Инкремент p кто делать будет ?
nicholaos
    case p^ of
      isc_info_svc_line: begin
        Result := PrintLine(p, outBuffer);
14 янв 21, 14:26    [22263291]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
hvlad

Проще вообще всё удалить.


Я относительно примера 10.backup.cpp. Логично либо добавить isc_spb_verbose, либо вообще удалить printLine, если она всегда упирается в isc_info_end.

hvlad

Может API Guide почитать сначала ?


Вы имеете в виду https://www.ibase.ru/files/interbase/ib6/ApiGuide.pdf от Interbase 6?

hvlad

Инкремент p кто делать будет ?

Виноват. Добавил inc(p) после case.

Добавил spb2.insertTag(st, isc_spb_verbose);
ничего не поменялось.
14 янв 21, 15:10    [22263322]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
hvlad
Member

Откуда:
Сообщений: 11555
nicholaos
Я относительно примера 10.backup.cpp. Логично либо добавить isc_spb_verbose, либо вообще удалить printLine, если она всегда упирается в isc_info_end.
А result кто читать\показывать будет ?

nicholaos
hvlad
Может API Guide почитать сначала ?
Вы имеете в виду https://www.ibase.ru/files/interbase/ib6/ApiGuide.pdf от Interbase 6?
Да

nicholaos
Добавил inc(p) после case.

Добавил spb2.insertTag(st, isc_spb_verbose);
ничего не поменялось.
Ошибки проверяются ?
14 янв 21, 15:30    [22263339]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
В своей реализации я PrintLine удалил, в ней нет необходимости. Надеюсь, когда-нибудь все примеры из examples/interfaces переведут на Pascal в каноничной реализации.

В любом случае всем спасибо за участие.
14 янв 21, 17:27    [22263417]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
kdv
Member

Откуда: iBase.ru
Сообщений: 30261
nicholaos,

конечная цель-то какая?
14 янв 21, 17:31    [22263418]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
kdv,

Делать бэкап/рестор не через CreateProcess gbak.
14 янв 21, 17:50    [22263431]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

TIBBackupService/TIBRestoreService уже выпили из IBX, а TFDIBBackup/TFDIBRestore из FireDAC?..

Posted via ActualForum NNTP Server 1.5

14 янв 21, 18:01    [22263436]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Dimitry Sibiryakov,

Да, они и используются. Но раз в FB3 добавили новый OO API, хотел проверить как получится на нем.
14 янв 21, 18:08    [22263446]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

nicholaos
Но раз в FB3 добавили новый OO API, хотел проверить как получится на нем.

Проверка провалилась: уровень API тебе пока не по зубам, вернись к киданию мышкой готовых
компонент.

Posted via ActualForum NNTP Server 1.5

14 янв 21, 18:29    [22263453]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Вернулся к задачке. Работающий вариант выглядит так:

+ Вызов svc.query

....
dpb2.insertTag(st, isc_action_svc_backup);
dpb2.insertString(st, isc_spb_dbname, PDBName);
dpb2.insertString(st, isc_spb_bkp_file, PBackupFilePath));
dpb2.insertTag(st, isc_spb_verbose);

svc.start(st, dpb2.getBufferLength(st), dpb2.getBuffer(st));

receiveItems[0] := isc_info_svc_server_version;
receiveItems2[0] := isc_info_svc_line;

repeat
    svc.query(st, 0, nil, sizeof(receiveItems2), @receiveItems2, sizeof(results), @results);
until not PrintInfo(@results, sizeof(results), outBuffer);

....



+ PrintInfo

function PrintInfo(p: BytePtr; pSize: cardinal; var outBuffer: string): boolean;
var
  pEnd: BytePtr;
begin
  Result := False;
  pEnd := p;
  Inc(pEnd, pSize);
  while (NativeUInt(p) < NativeUInt(pEnd)) and (p^ <> isc_info_end) do begin
    case p^ of
      isc_info_svc_line: begin
        Inc(p);
        Result := PrintLine(p, outBuffer);
      end;
      isc_info_truncated: begin
        Inc(p);
        Result := True;
      end;
      isc_info_svc_timeout, isc_info_data_not_ready: begin
        Inc(p);
        Result := True;
      end
      else Inc(p);
    end;
  end;
end;



+ PrintLine

function PrintLine(var p: BytePtr; var outBuffer: string): boolean;
var
  Length: word;
  Buffer: array of AnsiChar;
begin
  Length := word(PortableInteger(p, sizeof(word)));
  Inc(p, 2);
  if Length > 0 then begin
    SetLength(Buffer, Length);
    StrLCopy(PAnsiChar(@Buffer[0]), PAnsiChar(p), Length - 1);
    Buffer[Length - 1] := #0;
    outBuffer := outBuffer + Format('%s'#13#10, [PAnsiChar(@Buffer[0])]);
  end;
  Inc(p, Length);
  Result := Length > 0;
end;



Вдруг кому пригодится.
20 ноя 21, 19:16    [22398401]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Есть вопрос по команде isc_action_svc_validate. Аналогичным образом получаю лог проверки. В тексте есть предупреждения и ошибки.
Есть способ получить код возврата? Что-то вроде "есть предупреждения" или "есть ошибки"? Или только парсить лог?
20 ноя 21, 19:18    [22398402]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

nicholaos
        isc_info_truncated:begin
          Inc(p);
          Result := True;
        end;

Вот это - неправильный код. isc_info_truncated это терминирующий тэг и
после его получения должен быть немедленный выход из цикла.

Posted via ActualForum NNTP Server 1.5

20 ноя 21, 19:26    [22398405]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
nicholaos
Member

Откуда:
Сообщений: 104
Dimitry Sibiryakov,

Значит в 09.service.cpp/10.backup.cpp тоже ошибка?

К сообщению приложен файл. Размер - 16Kb
20 ноя 21, 19:34    [22398410]     Ответить | Цитировать Сообщить модератору
 Re: Пример 10.backup.cpp на Pascal  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54804

nicholaos
Значит в 09.service.cpp/10.backup.cpp тоже ошибка?

Да. Я с Алексом уже об этом говорил.

Posted via ActualForum NNTP Server 1.5

20 ноя 21, 19:37    [22398412]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Firebird, InterBase Ответить