Библиотека S-Lang упрощает процесс добавления цветов в приложения. Она позволяет использовать палитру, состоящую из 256 элементов [171] , каждый из которых определяет цвет переднего плана и фона. В большинстве приложений используется элемент палитры для одного визуализируемого объекта, например, рамки окна или пункта списка. Настроить
цвета палитры можно с помощью функции
SLtt_set_color
.
171
Со временем эта цифра может возрасти, однако маловероятно, что это когда-нибудь будет необходимо.
Первый параметр определяет модифицируемый элемент палитры. Параметр
name
в настоящий момент игнорируется и должен быть равен
NULL
. Два последних элемента задают новые цвета переднего плана и фона для данного элемента палитры. В табл. 24.2 приведен список цветов, которые поддерживает библиотека S-Lang;
fg
и
bg
должны представлять строки, содержащие имя используемого цвета. Все цвета в левой колонке таблицы могут использоваться как для переднего плана, так и для фона. Цвета в правой колонке таблицы могут служить только в качестве цветов переднего плана. Попытка использования этих цветов для фона может привести к непредсказуемым результатам [172] .
172
В частности, в некоторых системах это может привести к мерцанию текста.
Таблица 24.2. Цвета в S-Lang
Передний план и фон
Передний план
black
gray
red
brightred
green
brightgreen
brown
yellow
blue
brightblue
magenta
brightmagenta
cyan
brightcyan
lightgray
white
Запись на экран осуществляется с применением текущего элемента палитры, который можно задать с помощью функции
Slsmg_set_color
.
void SLsmg_set_color(int entry);
Эта функция задает текущий элемент палитры по определенному элементу. Цвета, определяемые этим элементом, будут использоваться при последующих записях на экран.
Хотя приложение может вызывать функции для работы с цветом на терминале любого типа, возможность отображения того или иного цвета будет определяться некоторыми факторами. Глобальная переменная
SLtt_Use_Ansi_Colors
контролирует отображение цветов. Если эта переменная будет иметь нулевое значение, цвета не используются, а если любое другое значение — то используются.
Функция
SLtt_get_terminfo
пытается предположить, будет ли цвет доступен на текущем терминале. К сожалению, многие базы данных termcap и terminfo в этом отношении несовершенны. Если будет задана переменная среды
COLORTERM
, то S-Lang установит переменную
SLtt_Use_Ansi_Colors
независимо от того, что отражено в базе данных терминала.
Большинство приложений, обеспечивающих поддержку цветов, также предлагают опцию командной строки, позволяя избирательно разрешать поддержку цветов. Указание этой опции приводит к явной установке переменной
SLtt_Use_Ansi_Colors
в приложении.
Глава 25
Библиотека хешированных баз данных
Приложениям часто необходимо хранить некоторую разновидность бинарных данных в файлах. Хранение таких данных, когда во главу угла ставится задача эффективного их извлечения, отличается сложностью и слабой устойчивостью к ошибкам. Существует несколько библиотек, которые предлагают простые API-интерфейсы для хранения информации в файлах. В системах семейства Unix одной из
первых использовалась библиотека
dbm
(впоследствии она была повторно реализована как
ndbm
), что привело затем к появлению библиотек Berkley db и
gdbm
проекта GNU. Все эти библиотеки обеспечивали простой доступ к файлам, организованным в виде хеш-таблиц, с двоичным ключом, который обеспечивал доступ к области бинарных данных [173] .
173
Библиотека Berkley db была существенно расширена, и сейчас включает реализацию B-деревьев и весь спектр работы с транзакциями.
Несмотря на то что
gdbm
и Berkley db широко доступны в системах Linux, лицензии, сопровождаемые их, снижают удобство их коммерческого использования [174] . Библиотека
gdbm
во многом похожа на другие библиотеки, но подпадает под действие лицензии LGPL, что делает ее более привлекательной для большинства разработчиков. Базовый API-интерфейс каждой из этих библиотек похож на остальные, поэтому переносить код между библиотеками несложно.
174
В настоящее время Berkley db разрабатывается некоммерческой организацией, которая продает альтернативные лицензии для своей библиотеки, поэтому на них вполне можно ориентироваться при разработке определенного рода приложений.
Полный исходный код и документацию по библиотеке
gdbm
можно найти на Web-сайте по адресуВ этой главе будут описаны все функции, которые большинство приложений должны использовать для
qdbm
(каждая из них имеет близкие аналоги в Berkley db,
adbm
и
ndbm
). Доступны также и другие функции API, описание которых можно найти на Web-сайте
qdbm
.
25.1. Обзор
qdbm
предлагает несколько различных API-интерфейсов. Самый основной из них, Depot, является низкоуровневым API, который мы и рассмотрим в этой главе. Интерфейс
Curia
позволяет разбивать базу данных на несколько файлов (для повышения масштабируемости или с целью работы в файловой системе с ограничениями), а функции
Villa
предлагают две модели: модель B-деревьев и модель транзакций. API-интерфейс
Odeon
позволяет работать с инвертированными индексами [175] . Два последних API,
Relic
и
Hovel
, предлагают реализацию таких интерфейсов, как
ndbm
и
qdbm
.
175
Инвертированные индексы представляют собой структуры данных, предназначенные для полнотекстового поиска.
Функции
Depot
обеспечивают выполнение основных операций по схеме "ключ-значение", при этом ключ используется для извлечения значения. Ключ и значение представляют собой произвольные бинарные потоки, размер которых передается отдельно от данных; библиотеке ничего не нужно знать об их структуре. Однако у интерфейса
Depot
имеется пара функциональных средств, благодаря которым применение строк в качестве ключей и элементов данных становится более удобным. Во-первых, всякий раз при передаче размера ключа или элемента данных в библиотеку вместо них может быть передано значение
– 1
, на основании которого
Depot
будет использовать функцию
strlen
для вычисления используемого размера. Во-вторых, большинство функций чтения ключей и элементов данных автоматически добавляют к возвращаемому значению байт
0
. Этот дополнительный символ не включается в возвращаемый размер, поэтому его можно проигнорировать, если значение не является строкой. Если же это строка, то возвращаемое значение может быть обработано как строка, и приложению не нужно будет завершать ее с помощью
NULL
.
Depot
использует глобальную целочисленную переменную
dpecode
для хранения кодов ошибок. Когда функции
Depot
возвращают сбой,
dpecode
сообщает о том, что произошло (это почти то же самое, что и в случае с переменной
errno
, которая относится к системным вызовам и библиотеке С). За текстовые сообщения об ошибках отвечает функция