Language libraries
The same Blob / Builder / Value / Iterator API in C++, Python, JS/TS, Rust, and Go — with byte-identical output.
Overview
Besides the SQLite extension, the Blob API ships as self-contained packages — the reference C++ library plus native, zero-dependency re-implementations in other languages. Each one exposes the same Blob / Builder / Value / Iterator API and produces byte-identical msgpack output, so blobs round-trip freely between SQL, C++, Python, JavaScript, Rust and Go.
| Library | Location | Runtime | Tests |
|---|---|---|---|
| C++ (reference) | cpp/ | C++17, no deps | cmake -B build cpp && ctest --test-dir build |
| Python | python/ | Python ≥ 3.7, stdlib only | python -m unittest discover -s tests |
| TypeScript / JS | js/ | Node ≥ 18 (ESM), no deps | npm test |
| Rust | rust/ | Rust ≥ 1.70, no deps | cargo test |
| Go | go/ | Go ≥ 1.21, stdlib only | go test ./... |
C++ (reference)
The reference C++17 implementation has no dependencies, lives in cpp/, and is documented in the C++ README.
cmake -B build cpp && ctest --test-dir buildPython
The Python port targets Python ≥ 3.7 and uses the standard library only.
# Python
from msgpack_blob import Blob, Value
blob = Blob.from_json('{"name":"Alice"}')
blob.set("$.age", Value.integer(30)).to_json() # '{"name":"Alice","age":30}'python -m unittest discover -s testsTypeScript / JS
The TypeScript / JavaScript port is ESM, has no dependencies, and runs on Node ≥ 18.
// TypeScript
import { Blob, Value } from "msgpack-blob";
const blob = Blob.fromJson('{"name":"Alice"}');
blob.set("$.age", Value.integer(30)).toJson(); // '{"name":"Alice","age":30}'npm testRust
The Rust crate targets Rust ≥ 1.70 and has no dependencies.
// Rust
use msgpack_blob::{Blob, Value};
let blob = Blob::from_json(r#"{"name":"Alice"}"#);
blob.set("$.age", &Value::integer(30)).to_json(); // {"name":"Alice","age":30}cargo testGo
The Go package targets Go ≥ 1.21 and uses the standard library only.
// Go
import mb "github.com/khanaffan/sqlite-msgpack/go"
blob := mb.FromJSON(`{"name":"Alice"}`)
blob.Set("$.age", mb.Int(30)).ToJSON() // {"name":"Alice","age":30}go test ./...Cross-language vectors
All ports are verified against a shared vector file generated from the C++ reference implementation (cpp/tests/gen_blob_vectors.cpp, CTest target blob_vectors_gen), guaranteeing cross-language byte-identity for encoding, JSON conversion, mutation, extraction and iteration.
Testing
The project includes a comprehensive test suite covering both the SQL extension and the C++ API.
cmake -B build -DMSGPACK_BUILD_TESTS=ON
cmake --build build
cd build && ctest --output-on-failureTest targets
| CTest target | Language | Tests | Description |
|---|---|---|---|
msgpack_unit | C | 29 | Core SQLite extension unit tests |
msgpack_sql | SQL | — | SQL integration tests via CLI |
msgpack_spec_p1–p10 | C | 10 suites | Per-section msgpack spec compliance |
msgpack_blob_unit | C++ | 632 | Standalone C++ API (no SQLite dependency) |
msgpack_interop | C++ | 197 | C++ ↔ SQLite interoperability |
fuzz_corpus | C | 100+ | Fuzz corpus against SQL extension |
fuzz_blob_corpus | C++ | 100+ | Fuzz corpus against C++ API |
Fuzz testing
Both the SQL extension and C++ API have dedicated libFuzzer harnesses (tests/fuzz_msgpack.c and cpp/tests/fuzz_msgpack_blob.cpp). Without libFuzzer, the corpus runners (fuzz_corpus_runner and fuzz_blob_corpus_runner) exercise the same code paths using 100+ seed files (including adversarially deep nesting, truncated length prefixes, and reserved-byte inputs) as part of the normal CTest suite.
# With libFuzzer (Clang required)
cmake -B build-fuzz -DMSGPACK_BUILD_FUZZ=ON \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake --build build-fuzz
./build-fuzz/fuzz_msgpack tests/fuzz_corpus -max_total_time=300
./build-fuzz/cpp/fuzz_msgpack_blob tests/fuzz_corpus -max_total_time=300