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.

LibraryLocationRuntimeTests
C++ (reference)cpp/C++17, no depscmake -B build cpp && ctest --test-dir build
Pythonpython/Python ≥ 3.7, stdlib onlypython -m unittest discover -s tests
TypeScript / JSjs/Node ≥ 18 (ESM), no depsnpm test
Rustrust/Rust ≥ 1.70, no depscargo test
Gogo/Go ≥ 1.21, stdlib onlygo 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 build

Python

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 tests

TypeScript / 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 test

Rust

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 test

Go

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-failure

Test targets

CTest targetLanguageTestsDescription
msgpack_unitC29Core SQLite extension unit tests
msgpack_sqlSQLSQL integration tests via CLI
msgpack_spec_p1p10C10 suitesPer-section msgpack spec compliance
msgpack_blob_unitC++632Standalone C++ API (no SQLite dependency)
msgpack_interopC++197C++ ↔ SQLite interoperability
fuzz_corpusC100+Fuzz corpus against SQL extension
fuzz_blob_corpusC++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