bson
The bson library provides predicates for parsing and generating the
BSON 1.1 binary interchange format:
The library requires a backend Prolog compiler with unbounded integer arithmetic support.
API documentation
Open the ../../apis/library_index.html#bson link in a web browser.
Loading
To load all entities in this library, load the loader.lgt file:
| ?- logtalk_load(bson(loader)).
Testing
To test this library predicates, load the tester.lgt file:
| ?- logtalk_load(bson(tester)).
The test set uses the official MongoDB BSON corpus files in the
test_files directory. Canonical BSON vectors are parsed successfully
and used for semantic generator round-trip tests, and BSON decode-error
vectors are checked for rejection. See test_files/NOTES.md for
provenance.
Representation
Documents are represented by ordered curly-bracketed terms,
{Pairs}, where each pair is represented byKey-Value. The empty document is{}. Pair order and duplicate keys are preserved.Arrays are represented by lists. BSON array keys are generated and validated as the canonical sequence
"0","1", and so on.Strings and document keys can be represented by atoms,
chars(List), orcodes(List). Use thebson/1parameterized object with the parameter bound toatom,chars, orcodesto select the decoded representation. BSON strings and keys are validated using strict UTF-8 conversion.The BSON Boolean, null, undefined, minimum-key, and maximum-key values are represented by
@false,@true,@null,@undefined,@min_key, and@max_key, respectively.BSON 32-bit and 64-bit integers are represented by
int32(Integer)andint64(Integer). Decoding preserves the encoded width. Generation also accepts plain integers, usingint32when possible andint64otherwise.BSON doubles are represented by floats. IEEE 754 infinities and NaNs use
@infinity,@negative_infinity,@not_a_number, andnot_a_number(Bytes), following theieee_754library conventions. Standard Prolog does not provide a portable distinct representation for IEEE 754 negative zero. Depending on the backend, parsing negative zero may produce0.0, in which case generation cannot recover the original sign bit.Binary values use
binary(Subtype, bytes(Bytes)). Subtypes 0 through 9 and user-defined subtypes 128 through 255 are supported. The deprecated subtype 2 inner length is parsed and generated transparently. Payloads for encrypted, compressed-column, sensitive, and vector subtypes are kept opaque.Object identifiers use
object_id(bytes(Bytes)), whereBytescontains exactly 12 bytes.UTC datetimes use
date_time(Milliseconds), whereMillisecondsis the signed 64-bit count since the Unix epoch.Regular expressions use
regular_expression(Pattern, Options). Options must be unique, alphabetically sorted, and selected fromi,m,s,u, andx.DBPointer, JavaScript, symbol, and JavaScript-with-scope values use
db_pointer(Namespace, ObjectId),javascript(Code),symbol(Symbol), andjavascript(Code, Scope), respectively. These deprecated BSON values remain fully readable and writable.Timestamps use
timestamp(Increment, Seconds), with both fields represented as unsigned 32-bit integers.Decimal128 values use the lossless wire representation
decimal128(bytes(Bytes)), whereBytescontains exactly 16 bytes. Decimal arithmetic and conversion are outside this library’s scope.
Encoding and decoding
The public API consists of generate/2 and parse/2 predicates
operating on complete BSON documents represented as byte lists:
| ?- bson::generate({name-alice, active - @true}, Bytes).
Bytes = [30,0,0,0,2,110,97,109,101,0,6,0,0,0,97,108,105,99,101,0,8,97,99,116,105,118,101,0,1,0]
yes
| ?- bson::parse([12,0,0,0,16,110,0,42,0,0,0,0], Document).
Document = {n-int32(42)}
yes
Parsing rejects malformed lengths, terminators, UTF-8, array keys, Boolean bytes, type codes, subtypes, regular-expression options, fixed-width payloads, and JavaScript-with-scope lengths. The MongoDB 16 MiB server document limit is not a BSON format limit and is therefore not imposed by this library.
For untrusted input, prefer bson(codes) or bson(chars) to avoid
interning arbitrary decoded strings as atoms.