Описание функций работы с BLOB-объектами

Большой двоичный объект (Binary large Object - BLOB) - это буфер в памяти компьютера. При создании буфера с ним связывается атом, в список свойств которого добавляется стандартный флаг BLOB. Будем называть этот атом идентификатором BLOB-а. Используя идентификатор BLOB-а, как ссылку, HomeLisp позволяет выполнять различные действия с буфером: загружать в него данные из двоичных файлов(FILGETBLOB), выгружать данные в файл на диске (FILPUTBLOB), менять данные внутри буфера и т.д.) Использование BLOB-ов позволяет, например, сделать на HomeLisp-е компилятор с какого-либо языка непосредственно в машинный код. Дело за желающими!

Работа с BLOB-ом начинается с создания BLOB-а вызовом функции BLOCREATE. С полученным BLOB-ом можно выполнять различные операции, а перед завершением работы все созданные BLOB-ы желательно уничтожить вызовом функции BLODESTROY.

Функции работы с BLOB-ами недоступны при работе WEB-компоненты.

Ниже перечислены все функции работы с BLOB-ами в алфавитном порядке. Функции FILGETBLO и FILPUTBLO описаны в разделе, посвященном действию с файлами.


Имя функции К-во аргументов Тип аргументов Выполняемое действие
  BIT2BLO 4 1-BLOB;
2-BITS;
3-FIXED;
4-FIXED (1, 2, 3 или 4)
Занести в BLOB, заданный ПЕРВЫМ аргументом, битовую шкалу, заданную ВТОРЫМ аргументом с позиции, заданной ТРЕТЬИМ аргументом. Размер шкалы задается значением ЧЕТВЕРТОГО аргумента (может быть 1, 2, 3 или 4 байта)
  BLO2BIT 3 1-BLOB;
2-FIXED;
3-FIXED (1, 2, 3 или 4)
Извлечь из BLOBа, заданного ПЕРВЫМ аргументом, битовую шкалу с позиции, заданной ВТОРЫМ аргументом. Размер шкалы задается значением ТРЕТЬЕГО аргумента (может быть 1, 2 или 4 байта)
  BLO2FIXED 3 1-BLOB;
2-FIXED;
3-FIXED (1, 2, 3 или 4)
Извлечь из BLOBа, заданного ПЕРВЫМ аргументом, число типа FIXED с позиции, заданной ВТОРЫМ аргументом. Размер числа задается значением ТРЕТЬЕГО аргумента (может быть 1, 2, 3 или 4 байта)
  BLO2FLO 3 1-BLOB;
2-FIXED;
3-FIXED (4 или 8)
Извлечь из BLOBа, заданного ПЕРВЫМ аргументом, число типа FLOAT с позиции, заданной ВТОРЫМ аргументом. Размер числа задается значением ТРЕТЬЕГО аргумента (может быть 4 или 8 байтов)
  BLO2STR 3 1-BLOB;
2-АТОМ;
3-FIXED
Извлечь из BLOBа, заданного ПЕРВЫМ аргументом, строку (STRING) с позиции, заданной ВТОРЫМ аргументом. Размер строки задается значением ТРЕТЬЕГО аргумента.
  BLOCOPY 2-5 1-BLOB;
2-BLOB;
[ 3-FIXED (1);
4-FIXED (1);
5-FIXED (длина BLOB-1)]
Копировать содержимое 1-го BLOBа во второй с позиции, заденной значением ТРЕТЬЕГО аргумента (по умолчанию с начала) в позицию во втором BLOBе, заданную значением ЧЕВЕРТОГО аргумента. Копируется размер BLOBа, заданный значением последнего аргумента (по умолчанию - весь исходный BLOB).
  BLOCREATE 2 1-Атом;
2-FIXED
Создать BLOB с длиной, заданной значением второго аргумента. Атом, стоящий на месте 1-го аргумента, получит в список свойств индикатор BLOB.
  BLODESTROY 1 1-BLOB Уничтожить BLOB
  BLODUMP* 4 [1-STREAM];
2-BLOB;
[3-FIXED(1);
4-FIXED (длина BLOB) ]
Выполняется дамп BLOBа, с позиции, заданной значением ТРЕТЬЕГО аргумента (по умолчанию - с начала). Дампируется размер BLOBа, заданный значением ЧЕТВЕРТОГО аргумента (по умолчанию - весь BLOB). Если задан первый аргумент (STREAM, открытый в режиме INPUT), то дамп попадает в соответствующий файл.
  BLOEQ 2 1-BLOB;
2-BLOB;
Сравнить два BLOBа на полное совпадение
  BLOFBLO 3 1-BLOB;
2-FIXED;
3-BLOB;
Найти в BLOB-е, заданным первым аргументом, положение BLOB-а, заданного третьим аргументом. Поиск начинается с позиции, заданной вторым аргументом.
  BLOFBYT 3 1-BLOB;
2-FIXED;
3-FIXED;
Найти в BLOB-е байт, заданный третьим аргументом. Поиск начинается с позиции, заданной вторым аргументом.
  BLOFFLO 3 1-BLOB;
2-FIXED;
3-FLOAT;
Найти в BLOB-е число с плавающей точкой (double), заданное третьим аргументом. Поиск начинается с позиции, заданной вторым аргументом.
  BLOFILL 2 1-BLOB;
2-FIXED;
Заполнить BLOB символом-заполнителем, заданного значением ВТОРОГО аргумента.
  BLOFINT 3 1-BLOB;
2-FIXED;
3-FIXED;
Найти в BLOB-е короткое (двухбайтовое) целое, заданный третьим аргументом. Поиск начинается с позиции, заданной вторым аргументом.
  BLOFLNG 3 1-BLOB;
2-FIXED;
3-FIXED;
Найти в BLOB-е длинное (четырехбайтовое) целое, заданное третьим аргументом. Поиск начинается с позиции, заданной вторым аргументом.
  BLOFSTR 3 1-BLOB;
2-FIXED;
3-STRING;
Найти положение строки, заданной ТРЕТЬИМ аргументом в BLOBе, заданным первым аргументом. Поиск начинается с позиции, заданной значением ВТОРОГО аргумента (по умочанию - с начала).
  BLOREPLACE 4 1-BLOB;
2-FIXED;
3-STRING;
4-STRING
Заменяет в BLOBе (заданным ПЕРВЫМ аргументом) все вхождения строки, заданным ТРЕТЬИМ аргументом, на строку, заданную ЧЕТВЕРТЫМ аргументом. Замена начинается со смещения, заданного ВТОРЫМ (необязательным) аргументом. Если он опущен - замена выполняется с начала BLOBa.
  FIX2BLO 4 1-BLOB;
2-FIXED;
3-FIXED;
4-FIXED
Заносит в BLOB, заданный ПЕРВЫМ аргументом, число типа FIXED, значение которого задано значением ВТОРОГО аргумента c позиции, заданной ТРЕТЬИМ аргументом. Длина числа (1, 2 или 4 байта) задается значением ЧЕТВЕРТОГО аргумента.
  FLO2BLO 4 1-BLOB;
2-FLOAT;
3-FIXED;
4-FIXED
Заносит в BLOB, заданный ПЕРВЫМ аргументом, число типа FLOAT, значение которого задано значением ВТОРОГО аргумента c позиции, заданной ТРЕТЬИМ аргументом . Длина числа (4 или 8 байтов) задается значением ЧЕТВЕРТОГО аргумента.
  STR2BLO 3 1-BLOB;
2-STRING;
3-FIXED
Занести в BLOB, заданный ПЕРВЫМ аргументом, строку (STRING), значение которой задано значением ВТОРОГО аргумента c позиции, заданной ТРЕТЬИМ аргументом.
BIT2BLO  

Функция BIT2BLO принимает четыре аргумента: идентификатор BLOBa, битовую шкалу, и два значения типа FIXED. Функция заносит битовую шкалу (значение 2-го аргумента) в тело BLOBa, заданного идентификатором. Смещение от начала, BLOBа, куда будет заноситься битовая шкала, Задается третьим параметром, а размер битовой шкалы (1, 2 или 4 байта) - последним, четвертым параметром. Вот подробный пример вызова функции BIT2BLO:


(blocreate 'buf 50)

==> buf

(bit2blo 'buf &H12 5 1)

==> T

(bloDump* 'buf)

00000001 | 00 00 00 00 12 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00                   |                         | ..               |

==> T

(bit2blo 'buf &H1234 23 2)

==> T

(bloDump* 'buf)

00000001 | 00 00 00 00 12 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 00 00 00 00 12 34 | 00 00 00 00 00 00 00 00 | ......4......... |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00                   |                         | ..               |

==> T

Здесь создается BLOB размером 50 байтов, а затем в него заносится байт &H12 со смещением пять. После этого BLOB дампируется. Занесенный байт отчетливо виден.

Затем в тот же BLOB заностися двухбайтовая битовая шкала &H1234 со смещения 23. После повторного дампирования все становится ясным.

BLO2BIT  

Функция BLO2BIT принимает три аргумента: идентификатор BLOBa, и два значения типа FIXED. Функция извлекает из тела BLOBa битовую шкалу со смещения, заданного значением 2-го аргумента и длиной, заданной значением 3-го аргумента. Длина может принимать значения 1, 2, 3 или 4. Если смещение начала или конца извлекаемой битовой шкалы выходит за пределы BLOBа, выдается сообщение об ошибке. Вот подробный пример вызова функции BLO2BIT:


(blocreate 'buf 50)

==> buf

(blofill 'buf 0)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00                   |                         | ..               |

==> T

(bit2blo 'buf &H123456 7 3)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 00 00 12 34 | 56 00 00 00 00 00 00 00 | .......4V....... |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00                   |                         | ..               |

==> T

(blo2bit 'buf 8 3)

==> &H345600

Здесь создается BLOB размером 50 байтов, а затем в него заносится трехбайтовая шкала &H123456 со смещением семь. После этого BLOB дампируется. Далее, со смещения 8 извлекается трехбайтовая шкала. Получается, естественно, &H345600.

BLO2FIXED  

Функция BLO2FIXED принимает три аргумента: идентификатор BLOBa, и два значения типа FIXED. Функция извлекает из тела BLOBa число типа FIXED со смещения, заданного значением 2-го аргумента и длиной, заданной значением 3-го аргумента. Длина может принимать значения 1, 2 или 4. Если смещение начала или конца извлекаемого числа выходит за пределы BLOBа, выдается сообщение об ошибке. Вот подробный пример вызова функции BLO2FIXED:


(bloCreate 'buf 48)

==> buf

(fix2blo 'buf 2211 3 2)

==> T

(blodump* 'buf)

00000001 | 00 00 A3 08 00 00 00 00 | 00 00 00 00 00 00 00 00 | ..Ј............. |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |

==> T

(blo2Fixed 'buf 3 2)

==> 2211

Здесь создается BLOB размером 48 байтов, а затем в него заносится целое число 2211 со смещением 3. После этого BLOB дампируется. Далее, со смещения 3 извлекается двухбайтовое целое. Получается, естественно, 2211.

Пусть читатель обратит внимание на то, что хотя десятичное число 2211 в шестнадцатеричном виде равно 08A3, внутри BLOB-а байты имеют обратный порядок, т.е. число хранится в виде A308. Это связано с особенностью интеловских микропроцессоров. А вот для битовых шкал HomeLisp порядок байтов не меняет (см. описание функции BIT2BLO).

BLO2FLO  

Функция BLO2FLO принимает три аргумента: идентификатор BLOBa, и два значения типа FIXED. Функция извлекает из тела BLOBa число типа FLOAT со смещения, заданного значением 2-го аргумента и длиной, заданной значением 3-го аргумента. Длина может принимать значения 4 или 8. Если смещение начала или конца извлекаемого числа выходит за пределы BLOBа, выдается сообщение об ошибке. Вот подробный пример вызова функции BLO2FLO:


(bloCreate 'buf 46)

==> buf

(flo2blo 'buf 12.34 6 4)

==> T

(blo2flo 'buf 6 4)

==> 12.34

(blodump* 'buf)

00000001 | 00 00 00 00 00 A4 70 45 | 41 00 00 00 00 00 00 00 | .....¤pEA....... |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00       | ..............   |

==> T

(flo2blo 'buf 12.34 17 8)

==> T

(blo2flo 'buf 17 8)

==> 12.34

(blodump* 'buf)

00000001 | 00 00 00 00 00 A4 70 45 | 41 00 00 00 00 00 00 00 | .....¤pEA....... |
00000017 | AE 47 E1 7A 14 AE 28 40 | 00 00 00 00 00 00 00 00 | ®Gбz.®(@........ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00       | ..............   |

==> T

Здесь создается BLOB размером 46 байтов, а затем в него заносится число 12.34 со смещением 6 как короткое число с плавающей точкой (длиной 4 байта). Затем занесенное число извлекается. Далее, в этот же BLOB заносится то же число, но в формате длинного числа с плавающей точкой. Следует обратить внимание на то, что одно и то же число в разных форматах во внутреннем представлении не имеют ничего общего!

BLO2STR  

Функция BLO2STR принимает три аргумента: идентификатор BLOBa, и два значения типа FIXED. Функция извлекает из тела BLOBa строку со смещения, заданного значением 2-го аргумента и длиной, заданной значением 3-го аргумента. Если смещение начала или конца извлекаемого числа выходит за пределы BLOBа, выдается сообщение об ошибке. Вот подробный пример вызова функции BLO2STR:


(bloCreate 'buf 35)

==> buf

(str2blo 'buf "Проба пера" 5)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 CF F0 EE E1 | E0 20 EF E5 F0 E0 00 00 | ....Проба пера.. |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00                |                         | ...              |

==> T

(blo2str 'buf 5 10)

==> "Проба пера"

(blo2str 'buf 5 8)

==> "Проба пе"

Здесь создается BLOB размером 35 байтов, а затем в него заносится строка Проба пера со смещением 5. Затем занесенная строка извлекается.

BLOCOPY  

Функция BLOCOPY обеспечивает копирование BLOB-ов . Первый аргумент задает BLOB -источник, второй - BLOB -приемник. Эти два аргумента обязательны. У функции BLOCOPY есть еще три необязательных аргумента. При вызове функции с двумя аргументами производится попытка полного копирования содержимого BLOB-а -источника в BLOB -приемник. BLOB -источник копируется в начало BLOB-а -приемника. Если при этом оказывается, что BLOB -приемник не в состоянии принять весь BLOB -источник, возникает ошибка и копирование не выполняется.

Необязательные аргументы функции BLOCOPY должны иметь тип FIXED. Третий аргумент функции BLOCOPY задает смещение от начала источника, с которого выполняется копирование. Четвертый аргумент задает смещение от начала приемника, куда выполняется копирование. Последний, пятый параметр задает размер копируемого блока. Если копируемый блок, заданный необязательными параметрами, выходит за пределы источника или приемника, то возникает ошибка и копирование не выполняется.

Вот развернутые примеры вызова функции BLOCOPY:


(bloCreate 'b1 50)

==> b1

(bloCreate 'b2 200)

==> b2

(blofill 'b1 102)

==> T

(blodump* 'b1)

00000001 | 66 66 66 66 66 66 66 66 | 66 66 66 66 66 66 66 66 | ffffffffffffffff |
00000017 | 66 66 66 66 66 66 66 66 | 66 66 66 66 66 66 66 66 | ffffffffffffffff |
00000033 | 66 66 66 66 66 66 66 66 | 66 66 66 66 66 66 66 66 | ffffffffffffffff |
00000049 | 66 66                   |                         | ff               |

==> T

(blocopy 'b1 'b2 1 12 16)

==> T

(blodump* 'b2)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 66 66 66 66 66 | ...........fffff |
00000017 | 66 66 66 66 66 66 66 66 | 66 66 66 00 00 00 00 00 | fffffffffff..... |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000065 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000081 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000097 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000113 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000129 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000145 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000161 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000177 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000193 | 00 00 00 00 00 00 00 00 |                         | ........         |

==> T

(bloCopy 'b2 'b1)

bloCopy: область копии выходит за пределы приемника
==> ERRSTATE

Здесь создаются два BLOB-а: первый - размером 50 байтов, второй - размером 200 байтов. Первый BLOB заполняется кодом &H66. Для наглядности первый BLOB дампируется. Затем участок первого BLOB-а со смещения 1 длиной 16 байтов копируется во второй BLOB со смещения 12. Дамп BLOB-а-приемника подтверждает, что копия выполнена успешно. И, наконец, делается попытка скопировать второй BLOB в первый. Поскольку размер области копирования (весь второй BLOB - 200 байтов) больше размера приемника, выдается сообщение об ошибке.

BLOCREATE  

Функция BLOCREATE создает BLOB. Первым параметром этой функции должен быть атом, не имеющим в своем списке свойств никаих стандартных флагов (если это не так, выдается сообщение об ошибке). Вторым параметром вызова должно быть значение типа FIXED - размер будущего BLOB-а. В случае удачи, BLOB создается и ссылка на него возвращается в качестве результата. Можно запросить список свойств атома-идентификатоа BLOB-а и убедиться, как все основные характеристики BLOB-а хранятся в его списке свойств:


(bloCreate 'b 3000)

==> b

(proplist 'b)

==> (BLOB Size 3000 BLOBHANDLE 1)

(bloCreate 'b 700)

BLOB b уже существует
==> ERRSTATE

(bloCreate _pi 200)

bloCreate: недопустимый флаг у первого аргумента
==> ERRSTATE

(putprop 'b 'Size 4000)

Попытка модификации списка свойств BLOBa
==> ERRSTATE

В списке свойств созданного BLOB-а виден его размер и т.н. Хэндл - номер BLOB-а во внутренней таблице BLOB-ов. Повторная попытка создания BLOB-а с одним и тем же атомом-идентификатором не допускается. Ошибкой закончится также использование в качестве опорного атома с любым стандартным флагом.

Попытка модифицировать список свойств BLOB-а завершается аварийно - список свойств защищен от модификации.

Следует обратить внимание на то, что даже если атом-идентификатор BLOB-а не участвует ни в одном из загруженных S-выражений, он не будет уничтожаться при сборке мусора. Этому препятствует установка стандартного флага BLOB.

BLODESTROY  

Функция BLODESTROY уничтожает BLOB. Единственным параметром этой функции должен быть идентификатор BLOB-а. Уничтожение заключается в том, что освобождается буфер BLOB-а и очищается список свойств атома-идентификатора. После чего атом-идентификатор бывшего BLOB-а попадает под действие программы сборки мусора: если с этим атомом не связано никаких S-выражений, то при вызове мусорщика атом будет исключен из списка объектов.

При успехе функция BLODESTROY возвращает T. Ниже приводятся примеры вызова функции BLODESTROY.


bloCreate 'buf 100)

==> buf

(proplist 'buf)

==> (BLOB Size 100 BLOBHANDLE 1)

(bloDestroy 'buf)

==> T

(proplist 'buf)

==> NIL

(bloDestroy 'buf)

Аргумент у bloDestroy не имеет тип BLOB
==> ERRSTATE

Отчетливо видно, что список свойств атома-идентификатора очистился. Именно поэтому повторная попытка удаления BLOB-а вызывает ошибку.

BLODUMP*  

Функция BLODUMP* выполняет дампирование BLOB-a. Дампирование заключается в формирования текстово - шестнадцатеричной картинки BLOB-a (эта форма представления давно стала негласным стандартом отображения двоичной информации). У функции BLODUMP* может быть до четырех аргументов. Первый (необязательный) - идентификатор открытого текстового потока (режим открытия должен быть _OUTPUT или _APPEND). Второй (обязательный) - идентификатор BLOB-a. Третий и четвертый параметры (типа FIXED) являются необязательными - третий задает смещение в BLOB-e, с которого начинается дампирование. Четвертый параметр задает длину дампируемого участка. Если третий и четвертый параметры опущены, выполняется дампирование всего BLOB-a. Если задан только третий параметр, то дампирование выполняется с задаваемого этим параметром смещения и до конца BLOB-a. При успехе функция возвращает T.

Если первый параметр (выходной файл) задан, то дамп помещается в этот файл, в противном случае дамп выводится в область вывода среды разработки.

Кстати, по имеющимся у автора сведениям, ни в одном из "расхожих" языков программирования нет аналога функции BLODUMP* - эти действия нужно программировать самому. Пользователь HomeLisp-а может без труда "заглядывать" в любые файлы (включая двоичные)!


(bloCreate 'buf 36)

==> buf

(bloFill 'buf 65)

==> T

(bloDump* 'buf)

00000001 | 41 41 41 41 41 41 41 41 | 41 41 41 41 41 41 41 41 | AAAAAAAAAAAAAAAA |
00000017 | 41 41 41 41 41 41 41 41 | 41 41 41 41 41 41 41 41 | AAAAAAAAAAAAAAAA |
00000033 | 41 41 41 41             |                         | AAAA             |

==> T

(filOpen 'fo ".\o.out" _OUTPUT)

==> fo

(bloDump* 'fo 'buf)

==> T

(filClose 'fo)

==> T

(fix2blo 'buf 112233 7 4)

==> T

(blodump* 'buf 7)

00000007 | 69 B6 01 00 41 41 41 41 | 41 41 41 41 41 41 41 41 | i¶..AAAAAAAAAAAA |
00000023 | 41 41 41 41 41 41 41 41 | 41 41 41 41 41 41       | AAAAAAAAAAAAAA   |

==> T

Здесь создается BLOB размером 36 байтов. Затем он заполняется кодом "A", после чего выполняется полный дамп BLOB-а с помещением картинки в область вывода. Далее открывается выходной файл и дамп повторяется с указанием приемного файла первым параметром, после чего файл закрывается. Можно убедиться, что в текущей директории создался файл o.out с соответствующим содержимым. Затем в BLOB заносится 4-х байтовое целое 112233 (&H1B669) со смещения 7 и BLOB дампируется со смещения 7 до конца.

BLOEQ  

Функция BLOEQ сравнивает содержимое двух BLOB-ов на полное совпадение. У функции два праметра, оба типа BLOB. Функция возвращает T если оба BLOB-ов имеют одинаковую длину и содержимое. В противном случае возвращается Nil.

Следует отметить, что для сравнения BLOB-ов бессмысленно применять классическую функцию EQ. Ведь функция EQ сравнивает атомы на совпадение. Применение функции EQ к двум разным BLOB-ам (даже одинаковой длины и идентичного содержимого) всегда будет давать Nil (ведь атомы-идентификаторы у BLOB-ов разные). И только вызов (EQ 'b1 'b1) даст в результате T. Ниже приводятся примеры вызова BLOEQ:


(bloCreate 'b1 40)

==> b1

(bloCreate 'b2 40)

==> b2

(bloeq 'b1 'b2)

==> T

(eq 'b1 'b2)

==> Nil

(bloCreate 'b3 45)

==> b3

(bloeq 'b1 'b3)

==> NIL

(fix2Blo 'b1 100 5 1)

==> T

(bloEq 'b1 'b2)

==> NIL

(fix2Blo 'b1 0 5 1)

==> T

(bloEq 'b1 'b2)

==> T

Создаются два BLOB-а размером по 40 байтов. Они сравниваются вызовом BLOEQ. Результат равен T, поскольку после создания BLOB-ы заполнены нулями. Попытка сравнить BLOB-ы вызовом EQ дает, естественно Nil.

Далее создается еще один BLOB размером 45 байтов. Сравнение его с первым BLOB-ом дает в результате Nil (из-за разности длин). Затем в BLOB b1 заносится байтовое значение 100. Теперь сравнение b1 и b2 дает в результате Nil, поскольку у BLOB-ов разное содержимое. Если заменить занчение 100 нулем, сравнение снова показывает идентичность.

BLOFILL  

Функция BLOFILL заполняет BLOB, заданный первым аргументом, кодом, равным значению второго аргумента (типа FIXED). Значение второго аргумента должно быть беззнаковым целым в диапазоне [0,255].

Если значение первого аргумента не является BLOB-ом или значение второго аргумента меньше нуля или больше 255, фиксируется ошибка. Все это выглядит так:


(bloCreate 'b3 45)

==>  b3

(bloFill 'b3 55)

==>  T

(bloDump* 'b3)

00000001 | 37 37 37 37 37 37 37 37 | 37 37 37 37 37 37 37 37 | 7777777777777777 |
00000017 | 37 37 37 37 37 37 37 37 | 37 37 37 37 37 37 37 37 | 7777777777777777 |
00000033 | 37 37 37 37 37 37 37 37 | 37 37 37 37 37          | 7777777777777    |

==> T

(bloFill 'b3 11)

==>  T

(bloDump* 'b3)

00000001 | 0B 0B 0B 0B 0B 0B 0B 0B | 0B 0B 0B 0B 0B 0B 0B 0B | ................ |
00000017 | 0B 0B 0B 0B 0B 0B 0B 0B | 0B 0B 0B 0B 0B 0B 0B 0B | ................ |
00000033 | 0B 0B 0B 0B 0B 0B 0B 0B | 0B 0B 0B 0B 0B          | .............    |

==>  T

(bloFill 'b3 1123)

bloFill: значение аргумента COD вне допустимого диапазона
==>  ERRSTATE

(bloFill 'b 1123)

bloFill: аргумент, задающий BLOB не является BLOBом
==>  ERRSTATE

Создается BLOB размером 45 байтов и заполняется кодом 55 (&H37). Дамп BLOB-а показывает, что заполнение прошло успешно. Далее BLOB заполняется кодом 11 (&H0B) и снова дампируется. В заключение приводятся два ошибочных обращения к функции BloFill

BLOFSTR  

Функция BLOFSTR выполняет поиск строки в BLOB-е. Функция ожидает три аргумента, из которых второй не обязателен. Первый аргумент, как всегда, задает BLOB. Второй (необязательный) аргумент задает смещение внутри BLOB-а, с которого начинается поиск. Третий аргумент задает строку поиска (значение типа STRING). Если строка поиска найдена, функция возвращает смещение этой строки от начала BLOB-а; в противном случае возвращается нуль.Вот развернутый пример использования Функции BLOFSTR:


(filOpen 'fi "testLisp.exe" _BINARY_READ)

==> fi

(bloCreate 'buf 300)

==> buf

(filGetBlob 'fi 'buf)

==> T

(bloDump* 'buf)

00000001 | 4D 5A 90 00 03 00 00 00 | 04 00 00 00 FF FF 00 00 | MZђ.........яя.. |
00000017 | B8 00 00 00 00 00 00 00 | 40 00 00 00 00 00 00 00 | ё.......@....... |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00 00 00 00 00 00 00 | 00 00 00 00 B8 00 00 00 | ............ё... |
00000065 | 0E 1F BA 0E 00 B4 09 CD | 21 B8 01 4C CD 21 54 68 | .є..ґ.Н!ё.LН!Th |
00000081 | 69 73 20 70 72 6F 67 72 | 61 6D 20 63 61 6E 6E 6F | is program canno |
00000097 | 74 20 62 65 20 72 75 6E | 20 69 6E 20 44 4F 53 20 | t be run in DOS  |
00000113 | 6D 6F 64 65 2E 0D 0D 0A | 24 00 00 00 00 00 00 00 | mode....$....... |
00000129 | 89 96 F9 DB CD F7 97 88 | CD F7 97 88 CD F7 97 88 | ‰–щЫНч—€Нч—€Нч—€ |
00000145 | 4E EB 99 88 CC F7 97 88 | 82 D5 9E 88 CC F7 97 88 | N뙈Мч—€‚Хћ€Мч—€ |
00000161 | C9 D4 9A 88 CC F7 97 88 | 52 69 63 68 CD F7 97 88 | ЙФљ€Мч—€RichНч—€ |
00000177 | 00 00 00 00 00 00 00 00 | 50 45 00 00 4C 01 03 00 | ........PE..L... |
00000193 | AA 12 82 47 00 00 00 00 | 00 00 00 00 E0 00 0F 01 | Є.‚G........а... |
00000209 | 0B 01 06 00 00 20 00 00 | 00 20 00 00 00 00 00 00 | ..... ... ...... |
00000225 | C8 11 00 00 00 10 00 00 | 00 30 00 00 00 00 40 00 | И........0....@. |
00000241 | 00 10 00 00 00 10 00 00 | 04 00 00 00 01 00 00 00 | ................ |
00000257 | 04 00 00 00 00 00 00 00 | 00 50 00 00 00 10 00 00 | .........P...... |
00000273 | FA 0C 01 00 02 00 00 00 | 00 00 10 00 00 10 00 00 | ъ............... |
00000289 | 00 00 10 00 00 10 00 00 | 00 00 00 00             | ............     |

==> T

(blofstr 'buf "MZ")

==> 1

(blofstr 'buf "PE")

==> 185

(blofstr 'buf "DOS")

==> 109

(blofstr 'buf 120 "DOS")

==> 0

(blofstr 'buf (strCat (strchr 12) (strchr 1)))

==> 274

Здесь двоичный файл (формата EXE) открывается на чтение. Создается 300-байтовый буфер и в него читается первые 300 байт EXE-файла. Для наглядности BLOB дампируется. Затем делается попытка найти строки "MZ" (она, естественно, располагается в самом начале) и "PE" (она находится по смещению 185. Строка "DOS" находится по смещению 109. Попытка повторного поиска строки "DOS", начиная со смещения 120, возвращает нуль.

Следует отметить, что если требуется найти строку, состоящую из неграфических символов, то ее следует предварительно сформировать, используя строковые функции strCat и strChr (как показано в последнем примере). Из дампа буфера хорошо видно, что строка байтов 0C 01 действительно располагается по смещению 274.

BLOREPLACE  

Функция BLOREPLACE выполняет глобальную замену в BLOB-е одной строки на другую. У функции четыре аргумента: первый аргумент задает BLOB, второй (необязательный, типа FIXED) - смещение в BLOB-е, с которой начинается замена. Третий аргумент (STRING) задает заменяемую строку, а последний аргумент (STRING) - заменяющую строку. Если заменяемая строка не найдена, BLOB не меняется. Если длины заменяемой и замещающей строк разные, происходит изменение размеров самого BLOB-а. Все это выглядит так:


(bloCreate 'b 40)

==> b

(proplist 'b)

==> (BLOB Size 40 BLOBHANDLE 1)

(str2blo 'b "**" 39)

==> T

(bloDump* 'b)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 2A 2A |                         | ......**         |

==> T

(str2blo 'b "zz" 19)

==> T

(bloDump* 'b)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 7A 7A 00 00 00 00 | 00 00 00 00 00 00 00 00 | ..zz............ |
00000033 | 00 00 00 00 00 00 2A 2A |                         | ......**         |

==> T

(bloReplace 'b "zz" "22222222")

==>  T

(bloDump* 'b)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000017 | 00 00 32 32 32 32 32 32 | 32 32 00 00 00 00 00 00 | ..22222222...... |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 2A 2A       | ............**   |

==>  T

(proplist 'b)

==>  (BLOB Size 46 BLOBHANDLE 1)

Здесь создается 40-байтовый BLOB. Запрашивается его список свойств; видно, что размер BLOB равен 40. Далее в два последних байта заносится строка "**", а в середину - строка "zz". И, наконец, производится замена строки "zz" строкой "22222222" (замещающая строка на 6 байтов длинее заменяемой). Последующий дамп показывает успешность замены строки и сопутствующее увеличение длины BLOB-а на 6 байтов. Обращение к списку свойств подтверждает увеличение размеров BLOB-а.

FIX2BLO  

Функция FIX2BLO заносит число типа FIXED в BLOB. Функция имеет четыре обязательных аргумента. Первый, как обычно, идентификатор BLOB-а. Второй аргумент задает число типа FIXED, которое будет заноситься в BLOB. Третий аргумент задает смещение, начиная с которого будет заноситься число. Последний аргумент задает длину в байтах, которую будет занимать заносимое значение. Этот аргумент может принимать значения 1, 2 или 4 (соответственно число будет занимать один байт, два или четыре байта). При занесении одного байта значение второго аргумента должно быть в диапазоне [0,255]; для двухбайтовой величины значение второго аргумента должно принадлежать диапазону [-32768,32767], а для четырехбайтовой величины значение второго аргумента должно принадлежать диапазону [-2147483647,2147483647]. При удачном завершении операции функция возвращает значение T. Вот примеры вызова Функции FIX2BLO:


(bloCreate 'buf 60)

==> buf

(fix2blo 'buf 45 12 1)

==> T

(fix2blo 'buf 455 32 1)

blo2fixed: значение 2-го аргумента вне диапазона, заданного 4-м аргументом
==> ERRSTATE

(fix2blo 'buf -55 32 1)

blo2fixed: значение 2-го аргумента вне диапазона, заданного 4-м аргументом
==> ERRSTATE

(fix2blo 'buf -55 32 2)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 00 00 00 00 | 00 00 00 2D 00 00 00 00 | ...........-.... |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 C9 | ...............Й |
00000033 | FF 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | я............... |
00000049 | 00 00 00 00 00 00 00 00 | 00 00 00 00             | ............     |

==> T

Здесь создается BLOB длиной 60 байтов. Затем в BLOB заносится байтовая величина 45 по смещению 12. Две последующие попытки заканчиваются неудачей - предлагаемое значение оказывается вне допустимого диапазона. После замены размера области, отводимого под число, операция завершается успешно.

После дампирования видно, как заносимая информация располагается внутри BLOB-а. Следует обратить внимание на то, что отрицательные целые хранятся в дополнительном коде. Кроме того, целые числа любого знака хранятся с инверсным порядком байтов (от младщего к старшему).

FLO2BLO  

Функция FLO2BLO заносит число типа FLOAT в BLOB. Функция имеет четыре обязательных аргумента. Первый, как обычно, идентификатор BLOB-а. Второй аргумент задает число типа FLOAT, которое будет заноситься в BLOB. Третий аргумент задает смещение, начиная с которого будет заноситься число. Последний аргумент задает длину в байтах, которую будет занимать заносимое значение. Этот аргумент может принимать значения 4 или 8. Соответственно число будет занимать четыре байта (короткое целое) или восемь байтов (длинное целое). При удачном завершении операции функция возвращает значение T. Вот примеры вызова Функции FLO2BLO:


(bloCreate 'buf 60)

==> buf

(flo2blo 'buf 0.5 2 4)

==> T

(flo2blo 'buf 456.789 12 8)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 3F 00 00 00 | 00 00 00 B4 C8 76 BE 9F | ....?......ґИvѕџ |
00000017 | 8C 7C 40 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Њ|@............. |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00 00 00 00 00 00 00 | 00 00 00 00             | ............     |

==> T

После дампирования видно, как заносимая информация располагается внутри BLOB-а. Знакомые с внутренним числа с плавающей точкой, могут убедиться, что числа представлены верно.

STR2BLO  

Функция STR2BLO заносит в BLOB строку. Функция имеет три обязательных аргумента. Первый, как обычно, идентификатор BLOB-а. Второй аргумент задает строку (STRING), которая будет заноситься в BLOB. Третий аргумент задает смещение, начиная с которого будет заноситься строка. При удачном завершении операции функция возвращает значение T. Вот примеры вызова Функции STR2BLO:


(bloCreate 'buf 60)

==> buf

(str2blo 'buf "Проба пера" 6)

==> T

(blodump* 'buf)

00000001 | 00 00 00 00 00 CF F0 EE | E1 E0 20 EF E5 F0 E0 00 | .....Проба пера. |
00000017 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000033 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | ................ |
00000049 | 00 00 00 00 00 00 00 00 | 00 00 00 00             | ............     |

==> T

После дампирования видно, как заносимая информация располагается внутри BLOB-а.

Сайт создан в системе uCoz