bson_guides - Guides
Contents
Copyright
2017-present, MongoDB, Inc
1.21.0 Feb 09, 2022 BSON_GUIDES(3)
Json
Libbson provides routines for converting to and from the JSON format. In particular, it supports the
MongoDBextendedJSON format.
ConvertingBSONtoJSON
There are often times where you might want to convert a BSON document to JSON. It is convenient for
debugging as well as an interchange format. To help with this, Libbson contains the functions
bson_as_canonical_extended_json() and bson_as_relaxed_extended_json(). The canonical format preserves
BSON type information for values that may have ambiguous representations in JSON (e.g. numeric types).
bson_t *b;
size_t len;
char *str;
b = BCON_NEW ("a", BCON_INT32 (1));
str = bson_as_canonical_extended_json (b, &len);
printf ("%s\n", str);
bson_free (str);
bson_destroy (b);
{ "a" : { "$numberInt": "1" } }
The relaxed format prefers JSON primitives for numeric values and may be used if type fidelity is not
required.
bson_t *b;
size_t len;
char *str;
b = BCON_NEW ("a", BCON_INT32 (1));
str = bson_as_relaxed_extended_json (b, &len);
printf ("%s\n", str);
bson_free (str);
bson_destroy (b);
{ "a" : 1 }
ConvertingJSONtoBSON
Converting back from JSON is also useful and common enough that we added bson_init_from_json() and
bson_new_from_json().
The following example creates a new bson_t from the JSON string {"a":1}.
bson_t *b;
bson_error_t error;
b = bson_new_from_json ("{\"a\":1}", -1, &error);
if (!b) {
printf ("Error: %s\n", error.message);
} else {
bson_destroy (b);
}
StreamingJSONParsing
Libbson provides bson_json_reader_t to allow for parsing a sequence of JSON documents into BSON. The
interface is similar to bson_reader_t but expects the input to be in the MongoDBextendedJSON format.
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This program will print each JSON document contained in the provided files
* as a BSON string to STDOUT.
*/
#include <bson/bson.h>
#include <stdlib.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
bson_json_reader_t *reader;
bson_error_t error;
const char *filename;
bson_t doc = BSON_INITIALIZER;
int i;
int b;
/*
* Print program usage if no arguments are provided.
*/
if (argc == 1) {
fprintf (stderr, "usage: %s FILE...\n", argv[0]);
return 1;
}
/*
* Process command line arguments expecting each to be a filename.
*/
for (i = 1; i < argc; i++) {
filename = argv[i];
/*
* Open the filename provided in command line arguments.
*/
if (0 == strcmp (filename, "-")) {
reader = bson_json_reader_new_from_fd (STDIN_FILENO, false);
} else {
if (!(reader = bson_json_reader_new_from_file (filename, &error))) {
fprintf (
stderr, "Failed to open \"%s\": %s\n", filename, error.message);
continue;
}
}
/*
* Convert each incoming document to BSON and print to stdout.
*/
while ((b = bson_json_reader_read (reader, &doc, &error))) {
if (b < 0) {
fprintf (stderr, "Error in json parsing:\n%s\n", error.message);
abort ();
}
if (fwrite (bson_get_data (&doc), 1, doc.len, stdout) != doc.len) {
fprintf (stderr, "Failed to write to stdout, exiting.\n");
exit (1);
}
bson_reinit (&doc);
}
bson_json_reader_destroy (reader);
bson_destroy (&doc);
}
return 0;
}
Examples
The following example reads BSON documents from stdin and prints them to stdout as JSON.
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This program will print each BSON document contained in the provided files
* as a JSON string to STDOUT.
*/
#include <bson/bson.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
bson_reader_t *reader;
const bson_t *b;
bson_error_t error;
const char *filename;
char *str;
int i;
/*
* Print program usage if no arguments are provided.
*/
if (argc == 1) {
fprintf (stderr, "usage: %s [FILE | -]...\nUse - for STDIN.\n", argv[0]);
return 1;
}
/*
* Process command line arguments expecting each to be a filename.
*/
for (i = 1; i < argc; i++) {
filename = argv[i];
if (strcmp (filename, "-") == 0) {
reader = bson_reader_new_from_fd (STDIN_FILENO, false);
} else {
if (!(reader = bson_reader_new_from_file (filename, &error))) {
fprintf (
stderr, "Failed to open \"%s\": %s\n", filename, error.message);
continue;
}
}
/*
* Convert each incoming document to JSON and print to stdout.
*/
while ((b = bson_reader_read (reader, NULL))) {
str = bson_as_canonical_extended_json (b, NULL);
fprintf (stdout, "%s\n", str);
bson_free (str);
}
/*
* Cleanup after our reader, which closes the file descriptor.
*/
bson_reader_destroy (reader);
}
return 0;
}
Name
bson_guides - Guides
Streaming Bson
bson_reader_t provides a streaming reader which can be initialized with a filedescriptor or memory
region. bson_writer_t provides a streaming writer which can be initialized with a memory region.
(Streaming BSON to a file descriptor is not yet supported.)
ReadingfromaBSONStreambson_reader_t provides a convenient API to read sequential BSON documents from a file-descriptor or
memory buffer. The bson_reader_read() function will read forward in the underlying stream and return a
bson_t that can be inspected and iterated upon.
#include <stdio.h>
#include <bson/bson.h>
int
main (int argc, char *argv[])
{
bson_reader_t *reader;
const bson_t *doc;
bson_error_t error;
bool eof;
reader = bson_reader_new_from_file ("mycollection.bson", &error);
if (!reader) {
fprintf (stderr, "Failed to open file.\n");
return 1;
}
while ((doc = bson_reader_read (reader, &eof))) {
char *str = bson_as_canonical_extended_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
if (!eof) {
fprintf (stderr,
"corrupted bson document found at %u\n",
(unsigned) bson_reader_tell (reader));
}
bson_reader_destroy (reader);
return 0;
}
See bson_reader_new_from_fd(), bson_reader_new_from_file(), and bson_reader_new_from_data() for more
information.
WritingasequenceofBSONDocumentsbson_writer_t provides a convenient API to write a sequence of BSON documents to a memory buffer that can
grow with realloc(). The bson_writer_begin() and bson_writer_end() functions will manage the underlying
buffer while building the sequence of documents.
This could also be useful if you want to write to a network packet while serializing the documents from a
higher level language, (but do so just after the packets header).
#include <stdio.h>
#include <bson/bson.h>
#include <assert.h>
int
main (int argc, char *argv[])
{
bson_writer_t *writer;
bson_t *doc;
uint8_t *buf = NULL;
size_t buflen = 0;
bool r;
int i;
writer = bson_writer_new (&buf, &buflen, 0, bson_realloc_ctx, NULL);
for (i = 0; i < 10000; i++) {
r = bson_writer_begin (writer, &doc);
assert (r);
r = BSON_APPEND_INT32 (doc, "i", i);
assert (r);
bson_writer_end (writer);
}
bson_free (buf);
return 0;
}
See bson_writer_new() for more information.
Use Valgrind To Check For Bson Data Leaks
A stack-allocated bson_t contains a small internal buffer; it only heap-allocates additional storage if
necessary, depending on its data size. Therefore if you forget to call bson_destroy on a stack-allocated
bson_t, it might or might not cause a leak that can be detected by valgrind during testing.
To catch all potential BSON data leaks in your code, configure the BSON_MEMCHECK flag:
cmake -DCMAKE_C_FLAGS="-DBSON_MEMCHECK -g" .
With this flag set, every bson_t mallocs at least one byte. Run your program's unittests with valgrind to
verify all bson_t structs are destroyed.
Set the environment variable MONGOC_TEST_VALGRIND to on to skip timing-dependent tests known to fail with
valgrind.
