|
|
Описание функций работы с 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 принимает четыре аргумента:
идентификатор 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 принимает три аргумента:
идентификатор 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 принимает три аргумента:
идентификатор 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 принимает три аргумента:
идентификатор 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 принимает три аргумента:
идентификатор 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 обеспечивает копирование 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 создает 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 уничтожает 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* выполняет дампирование 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 сравнивает содержимое двух
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 заполняет 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 выполняет поиск строки в
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 выполняет глобальную замену в
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 заносит число типа 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 заносит число типа 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 заносит в 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-а.
|
|
|
|