Crisper
RU

Danube read-only SDK

The free edition of the library for reading .adn containers: a C surface, a shared module and one header. The module only reads — there are no writing calls in it — so it can be embedded in any product, commercial ones included.

version 3.3.0 The delivery is an .adn container, unpacked with dan -method EXTRACT. Inside sits this same guide as HTML: SDK.html (Russian) and SDK.en.html (English).

01 Quick start

Unpack, link, read

Pick the delivery by system and loader; the module carries the compression engines inside, so no extra dependencies are needed. The password is passed on open; an empty string for an unencrypted container.

A container encrypted with a public key (release 3.3.0) is opened by the reader on its own: it walks the default keys folder (~/.dan/keys, in Windows %APPDATA%\danube\keys) and compares fingerprints with the recipient block. The facade cannot set another folder or a private-key password yet — unlock the key beforehand or put an unprotected copy next to it. Without a matching key danube_ro_open returns DANUBE_RO_BAD_PASS, and the reason stays in the log.

Linux and 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

:: unpack the container
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, from a developer command prompt
cl /Iinclude example.c lib\danube_ro.lib
02 First example

Container details and a tree walk

#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;
	/* Open the container: close the session on any result code */
	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;
	}
	/* Container details: format, nodes, bytes, parts */
	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);
	/* Children of the root */
	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;
}

Everything below builds on this session: reading bytes, extraction, search and the keys store.

03 Read and extract

Bytes into memory and files to disk

Reading with seeking

danube_ro_node_t node;
char buffer[65536];
size_t got = 0;

danube_ro_node(session, 0, 0, "readme.txt", &node);
/* The first 64 KiB and a chunk from offset 1 MiB */
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);

Only the frame the request touches is unpacked, so the call suits a viewer. A range past the end is not a refusal: success with nothing read.

Extraction to disk

/* The whole container, then one node or a list */
danube_ro_extract(session, "./out", NULL, 0);
uint64_t ids[2] = {3, 7};
danube_ro_extract(session, "./out", ids, 2);

A vault container refuses extraction (DANUBE_RO_VAULT): its data is read into memory only. Progress is attached with danube_ro_on_progress.

04 Reference

Seventeen surface calls

CallWhat it does
danube_ro_openopen a container; a session is created on any outcome but an empty path
danube_ro_closeclose the session; the pointer is invalid afterwards
danube_ro_messageexplanation of the last refusal
danube_ro_infodetails: flags, nodes, bytes, parts, dates, author
danube_ro_versionversion of the built module
danube_ro_countnumber of children of a folder
danube_ro_childrenlist children page by page
danube_ro_nodedetails of a node by id or by name inside a folder
danube_ro_pathfull path of a node inside the container
danube_ro_searchsearch by name, exact or partial
danube_ro_readread data into memory with seeking
danube_ro_extractextract the whole container, one node or a list
danube_ro_checkintegrity check, verified data in percent
danube_ro_keyslist the keys of the store
danube_ro_keys_exportwrite the keys as files into a folder
danube_ro_showshow key values in later calls of the session
danube_ro_on_progressattach or detach the progress handler
05 Result codes

What a refusal means

CodeMeaning
DANUBE_RO_OK (0)success
DANUBE_RO_ERROR (1)refusal, details in danube_ro_message
DANUBE_RO_NO_FILE (2)no container at the address
DANUBE_RO_BAD_PASS (3)wrong password
DANUBE_RO_FORMAT (4)the format cannot be parsed; this edition needs 4.0.0
DANUBE_RO_VAULT (5)vault: extraction to disk is refused
DANUBE_RO_DENIED (6)the action is not allowed
DANUBE_RO_NOT_FOUND (7)there is no such node or keys store
DANUBE_RO_IO (8)filesystem error
DANUBE_RO_SMALL (9)buffer too small, the value is clipped and zero terminated
DANUBE_RO_STOP (10)stopped by the caller

Fixed size fields of the structures are clipped silently — DANUBE_RO_SMALL never appears for them. A session is not thread safe: one thread, one session.

06 Parts and format

Container 4.0.0 and its parts

4.0.0 containers are read; archives of previous releases are refused with DANUBE_RO_FORMAT. A split container is the main .adn file plus .pdn parts; a part is identified by its header (archive identifier and part number), so it may be renamed, while a part of another archive in the same folder is neither used nor damaged. The number of parts comes from danube_ro_info, the number of pieces inside a node from danube_ro_node.

Inside the container: lib/ — the module, include/danube_read.h — the surface, LICENSE — version 1.1 with section 3.4, THIRD-PARTY-LICENSES.md, README-SDK.txt — a note about the build leg, SDK.html and SDK.en.html — this guide.

Why a container and not an archive: dan is already installed at this point — otherwise there would be no reason to download the SDK. It also demonstrates the format itself: the delivery can be opened with INFO, checked with DIAGNOSTIC and unpacked with the stock extraction.

Distribution terms: the edition is free for any use, commercial included; embedding, linking of any kind, redistribution of unmodified copies and building the danube_ro target from source are allowed. The writing part of the library is licensed commercially (section 3.1).

07 Download

SDK builds

Seventeen containers for Windows, macOS, Linux, BSD, Solaris and illumos, x86_64 and ARM64.

dan -method EXTRACT -danube danube-ro-3.3.0_Linux_glibc_amd64.adn -dest .
SystemBuildArchitectureFiles
Windowsyour systemMinGW-w64 (GCC)x86_64adn
MinGW-w64 (clang)ARM64adn
MSVCx86_64adn
ARM64adn
macOSyour systemApple Siliconadn
Linuxyour systemglibcAMD64adn
ARM64adn
muslAMD64adn
FreeBSDyour systemAMD64adn
ARM64adn
NetBSDyour systemAMD64adn
ARM64adn
OpenBSDyour systemAMD64adn
ARM64adn
DragonFly BSDyour systemAMD64adn
Solarisyour systemSolaris 11.4AMD64adn
OpenIndiana (illumos)AMD64adn