Danube read-only SDK
Бесплатное издание библиотеки для чтения контейнеров .adn: C-фасад,
динамический модуль и один заголовок. Модуль только читает — вызовов записи в нём нет, поэтому
его можно встроить в любой продукт, включая коммерческий.
версия 3.3.0 Поставка — контейнер
.adn, распаковка командой dan -method EXTRACT. Внутри — это же
руководство в HTML: SDK.html (русский) и SDK.en.html (английский).
Распаковать, слинковать, прочитать
Поставка выбирается по системе и загрузчику; модуль несёт движки сжатия внутри, отдельных зависимостей ставить не нужно. Пароль передаётся при открытии, для незашифрованного контейнера — пустая строка.
Контейнер, зашифрованный публичным ключом (выпуск 3.3.0), читалка открывает сама:
перебирает каталог ключей по умолчанию (~/.dan/keys, в Windows
%APPDATA%\danube\keys) и сверяет отпечатки с блоком получателей. Свой каталог
и пароль приватного ключа фасад пока не принимает — защищённый ключ нужно разблокировать
заранее или положить рядом копию без пароля. Без подходящего ключа danube_ro_open
отвечает DANUBE_RO_BAD_PASS, а причина остаётся в журнале.
Linux и macOS
dan -method EXTRACT -danube danube-ro-3.3.0_Linux_glibc_amd64.adn -dest . cc -Iinclude example.c -Llib -ldanube_ro -o example LD_LIBRARY_PATH=$PWD/lib ./example photos.adn # macOS: DYLD_LIBRARY_PATH
Windows
:: распаковка контейнера dan -method EXTRACT -danube danube-ro-3.3.0_Windows_x86_64_mingw.adn -dest . :: MinGW-w64 gcc -Iinclude example.c -Llib -ldanube_ro -o example.exe :: MSVC, из командной строки разработчика cl /Iinclude example.c lib\danube_ro.lib
Сведения о контейнере и обход дерева
#include <stdio.h> #include <danube_read.h> int main(int argc, char ** argv){ danube_ro_t * session = NULL; danube_ro_info_t info; danube_ro_node_t nodes[64]; uint64_t filled = 0, i; if(argc < 2) return 2; /* Открываем контейнер: сессию закрываем при любом коде возврата */ danube_ro_error_t code = danube_ro_open(argv[1], "", "", &session); if(code != DANUBE_RO_OK){ char message[DANUBE_RO_TEXT] = {0}; danube_ro_message(session, message, sizeof(message)); fprintf(stderr, "open: %d (%s)\n", (int) code, message); danube_ro_close(session); return 1; } /* Сведения о контейнере: формат, узлы, объём, число частей */ danube_ro_info(session, &info); printf("format=%s nodes=%llu bytes=%llu parts=%llu\n", info.format, (unsigned long long) info.nodes, (unsigned long long) info.bytes, (unsigned long long) info.parts); /* Дети корня */ danube_ro_children(session, 0, 0, nodes, 64, &filled); for(i = 0; i < filled; i++) printf("%llu\t%s\t%llu\n", (unsigned long long) nodes[i].id, nodes[i].name, (unsigned long long) nodes[i].size); danube_ro_close(session); return 0; }
Всё, что ниже, добавляется к этой сессии: чтение байтов, извлечение, поиск, хранилка ключей.
Байты в память и файлы на диск
Чтение с перемоткой
danube_ro_node_t node; char buffer[65536]; size_t got = 0; danube_ro_node(session, 0, 0, "readme.txt", &node); /* Первые 64 КиБ и кусок с отметки 1 МиБ */ danube_ro_read(session, node.id, 0, sizeof(buffer), buffer, sizeof(buffer), &got); danube_ro_read(session, node.id, 1024 * 1024, 0, buffer, sizeof(buffer), &got);
Разбирается только тот кадр, в который попал запрос, поэтому вызов годится для просмотрщика. Запрос за концом данных — не отказ: код успеха и ноль прочитанных байт.
Извлечение на диск
/* Весь контейнер, затем один узел или перечень */ danube_ro_extract(session, "./out", NULL, 0); uint64_t ids[2] = {3, 7}; danube_ro_extract(session, "./out", ids, 2);
Контейнер-сейф извлечение отклоняет (DANUBE_RO_VAULT): его данные читаются только
в память. Ход работы подключается приёмом danube_ro_on_progress.
Семнадцать вызовов фасада
| Вызов | Что делает |
|---|---|
| danube_ro_open | открыть контейнер; сессия создаётся при любом исходе, кроме пустого адреса |
| danube_ro_close | закрыть сессию; указатель после вызова недействителен |
| danube_ro_message | объяснение последнего отказа |
| danube_ro_info | сведения: признаки, узлы, объём, части, даты, автор |
| danube_ro_version | версия собранного модуля |
| danube_ro_count | число детей каталога |
| danube_ro_children | перечислить детей постранично |
| danube_ro_node | сведения об узле по номеру или по имени в каталоге |
| danube_ro_path | полный путь узла внутри контейнера |
| danube_ro_search | поиск по имени, точный или частичный |
| danube_ro_read | чтение данных в память с перемоткой |
| danube_ro_extract | извлечение всего контейнера, узла или перечня |
| danube_ro_check | проверка целостности, доля верных данных в процентах |
| danube_ro_keys | перечислить ключи хранилки |
| danube_ro_keys_export | выгрузить ключи файлами в каталог |
| danube_ro_show | показывать значения ключей в последующих вызовах сессии |
| danube_ro_on_progress | подключить или снять приём хода работы |
Что означает отказ
| Код | Значение |
|---|---|
| DANUBE_RO_OK (0) | успех |
| DANUBE_RO_ERROR (1) | отказ, подробности в danube_ro_message |
| DANUBE_RO_NO_FILE (2) | контейнера нет по адресу |
| DANUBE_RO_BAD_PASS (3) | пароль не подошёл |
| DANUBE_RO_FORMAT (4) | формат не читается; для этого издания нужен 4.0.0 |
| DANUBE_RO_VAULT (5) | сейф: извлечение на диск запрещено |
| DANUBE_RO_DENIED (6) | действие недоступно |
| DANUBE_RO_NOT_FOUND (7) | узла или хранилки нет |
| DANUBE_RO_IO (8) | ошибка файловой системы |
| DANUBE_RO_SMALL (9) | буфера не хватает, значение обрезано и завершено нулём |
| DANUBE_RO_STOP (10) | работа остановлена вызывающим |
Поля фиксированной длины структур обрезаются молча — кода DANUBE_RO_SMALL
для них не бывает. Сессия не потокобезопасна: один поток — одна сессия.
Контейнер 4.0.0 и его части
Читаются контейнеры формата 4.0.0; архивы прежних выпусков отвергаются с
DANUBE_RO_FORMAT. Разбитый контейнер — это основной файл .adn и части
.pdn; часть опознаётся по заголовку (идентификатор архива и номер), поэтому её можно
переименовать, а часть чужого архива рядом не используется и не портится. Число частей отдаёт
danube_ro_info, число кусков внутри узла — danube_ro_node.
Внутри контейнера: lib/ — модуль, include/danube_read.h — фасад,
LICENSE — лицензия 1.1 с разделом 3.4, THIRD-PARTY-LICENSES.md,
README-SDK.txt — записка о ноге сборки, SDK.html и SDK.en.html —
это руководство.
Почему контейнер, а не архив: команда dan к этому моменту уже стоит в системе — иначе
SDK незачем скачивать. Заодно поставка показывает сам формат: её можно открыть тем же INFO,
проверить DIAGNOSTIC и распаковать штатным извлечением.
Условия поставки: издание свободно для любого использования, коммерческого
включительно; разрешены встраивание, связывание любого рода, распространение неизменённых копий
архива и сборка цели danube_ro из исходников. Пишущая часть библиотеки идёт по
коммерческой лицензии (раздел 3.1).
Сборки SDK
Семнадцать контейнеров под Windows, macOS, Linux, BSD, Solaris и illumos, x86_64 и ARM64.
dan -method EXTRACT -danube danube-ro-3.3.0_Linux_glibc_amd64.adn -dest .
| Система | Сборка | Архитектура | Файлы |
|---|---|---|---|
| Windowsваша система | MinGW-w64 (GCC) | x86_64 | adn |
| MinGW-w64 (clang) | ARM64 | adn | |
| MSVC | x86_64 | adn | |
| ARM64 | adn | ||
| macOSваша система | Apple Silicon | adn | |
| Linuxваша система | glibc | AMD64 | adn |
| ARM64 | adn | ||
| musl | AMD64 | adn | |
| FreeBSDваша система | AMD64 | adn | |
| ARM64 | adn | ||
| NetBSDваша система | AMD64 | adn | |
| ARM64 | adn | ||
| OpenBSDваша система | AMD64 | adn | |
| ARM64 | adn | ||
| DragonFly BSDваша система | AMD64 | adn | |
| Solarisваша система | Solaris 11.4 | AMD64 | adn |
| OpenIndiana (illumos) | AMD64 | adn |