powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / isc_vax_integer и IAttachment
19 сообщений из 19, страница 1 из 1
isc_vax_integer и IAttachment
    #39963317
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть код, по получению диалекта БД
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
function TIBDatabaseInfo.GetDBSQLDialect: Integer;
var
  local_buffer: array[0..IBLocalBufferLength - 1] of Byte;
  length: Integer;
  DatabaseInfoCommand: Byte;
begin
  DatabaseInfoCommand := Byte(isc_info_db_SQL_Dialect);
  Call(isc_database_info(StatusVector, @FDatabase.Handle, 1, @DatabaseInfoCommand,
                       IBLocalBufferLength, @local_buffer), True);
  if local_buffer[0] <> isc_info_db_SQL_dialect then
    result := 1
  else begin
    length := isc_vax_integer(@local_buffer[1], 2);
    result := isc_vax_integer(@local_buffer[3], length);
  end;
end;

Хочу перевести ее на новый API
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function GetSQLDialect(AStatus: IStatus; AAttachment: IAttachment): Integer;
var
  LBuf: array[0..15] of Byte;
  LLen: Integer;
  LCmd: Byte;
begin
  LCmd := isc_info_db_SQL_Dialect;
  AAttachment.getInfo(AStatus, 1, @LCmd, Length(LBuf), @LBuf[0]);
  if LBuf[0] <> isc_info_db_SQL_dialect then
    result := 1
  else begin
//    LLen := isc_vax_integer(@LBuf[1], 2);
//    result := isc_vax_integer(@LBuf[3], LLen);
  end;
end;

Вопрос: чем можно заменить isc_vax_integer? Или его вообще не нужно вызывать и просто использовать прямой каст?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963327
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ: заменить его нечем. И не вызывать его нельзя из-за переменной длины данных.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963338
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Ответ: заменить его нечем. И не вызывать его нельзя из-за переменной длины данных.
Спасибо. Я где-то так и подумал
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963339
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И чуть не забыл: isc_vax_integer() устарела и будут проблемы с 64-х разрядными значениями,
надо использовать isc_portable_integer(). Хотя конкретно для диалекта, это, конечно же,
всё равно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963343
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получилось так
Код: pascal
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.
function GetSQLDialect(AStatus: IStatus; AAttachment: IAttachment): Integer;
type
  TBuffer = packed record
    Cmd: Byte;
    case Len: SmallInt of
      1: (v1: ShortInt);
      2: (v2: SmallInt);
      4: (v4: Integer);
      8: (v8: Int64);
      -1: (reserved: array[0..12] of Byte);
  end;
var
  LBuf: TBuffer;
  LCmd: Byte;
  Li: Integer;
begin
  LCmd := isc_info_db_SQL_Dialect;
  AAttachment.getInfo(AStatus, 1, @LCmd, SizeOf(LBuf), @LBuf);
  if LBuf.Cmd <> isc_info_db_SQL_dialect then
    Result := 1
  else begin
    case LBuf.Len of
      SizeOf(LBuf.v1): Result := LBuf.v1;
      SizeOf(LBuf.v2): Result := LBuf.v2;
      SizeOf(LBuf.v4): Result := LBuf.v4;
      SizeOf(LBuf.v8): Result := LBuf.v8;
    else
      Result := 0;
      for Li := LBuf.Len - 1 downto 0 do
        Result := (Result shl 8) or LBuf.reserved[Li]
    end;
  end;
end;
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963345
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
надо использовать isc_portable_integer()
Это я знаю. Но isc_portable_integer все равно же в новом API нет
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963349
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Получилось так

Тебе будет большой сюрприз когда кто-нибудь пришлёт три байта. Или пять.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963370
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Тебе будет большой сюрприз
Почему?
_Vasilisk_
Код: pascal
1.
2.
3.
4.
    else
      Result := 0;
      for Li := LBuf.Len - 1 downto 0 do
        Result := (Result shl 8) or LBuf.reserved[Li]

...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963378
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, не заметил. Но там будет другой сюрприз, с отрицательными числами. Знак последнего байта надо расширять.
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963389
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Знак последнего байта надо расширять.
Так?
Код: pascal
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.
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]
  end;
end;
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963399
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Так?

Я бы написал немного иначе:
Код: pascal
1.
2.
3.
     Result := LValue^.reserved[ASize - 1];
     for Li := ASize - 2 downto 0 do
       Result := (Result shl 8) or LValue^.reserved[Li]


И надо бы обработать случай ASize = 0.

Ну и вообще я сомневаюсь, что весь case нужен. Подозреваю, что на переходы по его
вариантам уйдёт больше тактов, чем на просто цикл.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963408
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Ну и вообще я сомневаюсь, что весь case нужен
Он просто вреден, ибо не правилен.
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963409
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Я бы написал немного иначе
Да. Ты прав. Так лучше.
Dimitry Sibiryakov
И надо бы обработать случай ASize = 0.
Так тоже бывает? Учту. Спасибо
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963410
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
ибо не правилен
Чем? Порядок байт инвертируется корректно
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963411
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
hvlad
ибо не правилен
Чем? Порядок байт инвертируется корректно
Где он инвертируется ?
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963446
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Где он инвертируется ?
При касте
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
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;

procedure TForm1.Button1Click(Sender: TObject);
var
  LBuf: TValue;
begin
  LBuf.reserved[0] := 1;
  LBuf.reserved[1] := 2;
  LBuf.reserved[2] := 3;
  LBuf.reserved[3] := 4;
  ShowMessage(IntToHex(LBuf.v4));
end;
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39963471
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так где порядок байт инвертируется-то ? :)

Его же не надо инвертировать для LE - тут я промазал, признаюсь :)
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39964527
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Код: sql
1.
Result := (Result shl 8) or LValue^.reserved[Li]



Вот эту строчку надо бы потестить, потому что если знак расширится перед применением ИЛИ -
будет неприятный сюрприз.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_vax_integer и IAttachment
    #39965088
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Вот эту строчку надо бы потестить, потому что если знак расширится перед применением ИЛИ -
Ты прав. Нужно так
Код: sql
1.
Result := (Result shl 8) or (LValue^.reserved[Li] and $FF)


Dimitry Sibiryakov
Ну и вообще я сомневаюсь, что весь case нужен. Подозреваю, что на переходы по его вариантам уйдёт больше тактов, чем на просто цикл.
Проверил на миллиарде итераций для длин 1, 2, 4, 8 байт с case и только циклом. Получились такие времена
Код: plaintext
1.
Case: 1: 2312, 2: 2328, 4: 2312, 8: 2360, 
Loop: 1: 2344, 2: 4485, 4: 8484, 8: 16640, 
Так, что case смысл имеет
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / isc_vax_integer и IAttachment
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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