1BSON_REFERENCE(3) libbson BSON_REFERENCE(3)
2
3
4
6 bson_reference - Index
7
9 A Cross Platform BSON Library for C
10
11 Introduction
12 libbson builds, parses, and iterates BSON documents, the native data
13 format of MongoDB. It also converts BSON to and from JSON, and provides
14 a platform compatibility layer for the MongoDB C Driver.
15
16 Tutorial
17 Using libbson In Your C Program
18 Include bson.h
19 All libbson's functions and types are available in one header file.
20 Simply include bson.h:
21
22 hello_bson.c
23
24 #include <stdio.h>
25 #include <bson/bson.h>
26
27 int
28 main (int argc, const char **argv)
29 {
30 bson_t *b;
31 char *j;
32
33 b = BCON_NEW ("hello", BCON_UTF8 ("bson!"));
34 j = bson_as_canonical_extended_json (b, NULL);
35 printf ("%s\n", j);
36
37 bson_free (j);
38 bson_destroy (b);
39
40 return 0;
41 }
42
43
44 CMake
45 The libbson installation includes a CMake config-file package, so you
46 can use CMake's find_package command to import libbson's CMake target
47 and link to libbson (as a shared library):
48
49 CMakeLists.txt
50
51 # Specify the minimum version you require.
52 find_package (bson-1.0 1.7 REQUIRED)
53
54 # The "hello_bson.c" sample program is shared among four tests.
55 add_executable (hello_bson ../../hello_bson.c)
56 target_link_libraries (hello_bson PRIVATE mongo::bson_shared)
57
58
59 You can also use libbson as a static library instead: Use the
60 mongo::bson_static CMake target:
61
62 # Specify the minimum version you require.
63 find_package (bson-1.0 1.7 REQUIRED)
64
65 # The "hello_bson.c" sample program is shared among four tests.
66 add_executable (hello_bson ../../hello_bson.c)
67 target_link_libraries (hello_bson PRIVATE mongo::bson_static)
68
69
70 pkg-config
71 If you're not using CMake, use pkg-config on the command line to set
72 header and library paths:
73
74 gcc -o hello_bson hello_bson.c $(pkg-config --libs --cflags libbson-1.0)
75
76
77 Or to statically link to libbson:
78
79 gcc -o hello_bson hello_bson.c $(pkg-config --libs --cflags libbson-static-1.0)
80
81
82 Creating a BSON Document
83 The bson_t structure
84 BSON documents are created using the bson_t structure. This structure
85 encapsulates the necessary logic for encoding using the BSON Specifica‐
86 tion. At the core, bson_t is a buffer manager and set of encoding rou‐
87 tines.
88
89 TIP:
90 BSON documents can live on the stack or the heap based on the per‐
91 formance needs or preference of the consumer.
92
93 Let's start by creating a new BSON document on the stack. Whenever us‐
94 ing libbson, make sure you #include <bson/bson.h>.
95
96 bson_t b;
97
98 bson_init (&b);
99
100 This creates an empty document. In JSON, this would be the same as {}.
101
102 We can now proceed to adding items to the BSON document. A variety of
103 functions prefixed with bson_append_ can be used based on the type of
104 field you want to append. Let's append a UTF-8 encoded string.
105
106 bson_append_utf8 (&b, "key", -1, "value", -1);
107
108 Notice the two -1 parameters. The first indicates that the length of
109 key in bytes should be determined with strlen(). Alternatively, we
110 could have passed the number 3. The same goes for the second -1, but
111 for value.
112
113 Libbson provides macros to make this less tedious when using string
114 literals. The following two appends are identical.
115
116 bson_append_utf8 (&b, "key", -1, "value", -1);
117 BSON_APPEND_UTF8 (&b, "key", "value");
118
119 Now let's take a look at an example that adds a few different field
120 types to a BSON document.
121
122 bson_t b = BSON_INITIALIZER;
123
124 BSON_APPEND_INT32 (&b, "a", 1);
125 BSON_APPEND_UTF8 (&b, "hello", "world");
126 BSON_APPEND_BOOL (&b, "bool", true);
127
128 Notice that we omitted the call to bson_init(). By specifying BSON_INI‐
129 TIALIZER we can remove the need to initialize the structure to a base
130 state.
131
132 Sub-Documents and Sub-Arrays
133 To simplify the creation of sub-documents and arrays, bson_append_docu‐
134 ment_begin() and bson_append_array_begin() exist. These can be used to
135 build a sub-document using the parent documents memory region as the
136 destination buffer.
137
138 bson_t parent;
139 bson_t child;
140 char *str;
141
142 bson_init (&parent);
143 bson_append_document_begin (&parent, "foo", 3, &child);
144 bson_append_int32 (&child, "baz", 3, 1);
145 bson_append_document_end (&parent, &child);
146
147 str = bson_as_canonical_extended_json (&parent, NULL);
148 printf ("%s\n", str);
149 bson_free (str);
150
151 bson_destroy (&parent);
152
153 { "foo" : { "baz" : 1 } }
154
155 Simplified BSON C Object Notation
156 Creating BSON documents by hand can be tedious and time consuming.
157 BCON, or BSON C Object Notation, was added to allow for the creation of
158 BSON documents in a format that looks closer to the destination format.
159
160 The following example shows the use of BCON. Notice that values for
161 fields are wrapped in the BCON_* macros. These are required for the
162 variadic processor to determine the parameter type.
163
164 bson_t *doc;
165
166 doc = BCON_NEW ("foo",
167 "{",
168 "int",
169 BCON_INT32 (1),
170 "array",
171 "[",
172 BCON_INT32 (100),
173 "{",
174 "sub",
175 BCON_UTF8 ("value"),
176 "}",
177 "]",
178 "}");
179
180 Creates the following document
181
182 { "foo" : { "int" : 1, "array" : [ 100, { "sub" : "value" } ] } }
183
184 Handling Errors
185 Description
186 Many libbson functions report errors by returning NULL or -1 and fill‐
187 ing out a bson_error_t structure with an error domain, error code, and
188 message.
189
190 • error.domain names the subsystem that generated the error.
191
192 • error.code is a domain-specific error type.
193
194 • error.message describes the error.
195
196 Some error codes overlap with others; always check both the domain and
197 code to determine the type of error.
198
199
200
201
202
203 ┌──────────────────┬─────────────────────┬────────────────────────────────┐
204 │BSON_ERROR_JSON │ BSON_JSON_ER‐ │ bson_json_reader_t │
205 │ │ ROR_READ_CORRUPT_JS │ tried to parse in‐ │
206 │ │ BSON_JSON_ER‐ │ valid MongoDB Ex‐ │
207 │ │ ROR_READ_IN‐ │ tended JSON. Tried │
208 │ │ VALID_PARAM │ to parse a valid │
209 │ │ BSON_JSON_ER‐ │ JSON document that │
210 │ │ ROR_READ_CB_FAILURE │ is invalid as Mon‐ │
211 │ │ │ goDBExtended JSON. │
212 │ │ │ An internal call‐ │
213 │ │ │ back failure during │
214 │ │ │ JSON parsing. │
215 ├──────────────────┼─────────────────────┼────────────────────────────────┤
216 │BSON_ERROR_READER │ BSON_ER‐ │ bson_json_reader_new_from_file │
217 │ │ ROR_READER_BADFD │ could not open the │
218 │ │ │ file. │
219 └──────────────────┴─────────────────────┴────────────────────────────────┘
220
221 ObjectIDs
222 Libbson provides a simple way to generate ObjectIDs. It can be used in
223 a single-threaded or multi-threaded manner depending on your require‐
224 ments.
225
226 The bson_oid_t structure represents an ObjectID in MongoDB. It is a
227 96-bit identifier.
228
229 Composition
230 • 4 bytes : The UNIX timestamp in big-endian format.
231
232 • 5 bytes : A random number.
233
234 • 3 bytes : A 24-bit monotonic counter incrementing from rand() in
235 big-endian.
236
237 Sorting ObjectIDs
238 The typical way to sort in C is using qsort(). Therefore, Libbson pro‐
239 vides a qsort() compatible callback function named bson_oid_compare().
240 It returns less than 1, greater than 1, or 0 depending on the equality
241 of two bson_oid_t structures.
242
243 Comparing Object IDs
244 If you simply want to compare two bson_oid_t structures for equality,
245 use bson_oid_equal().
246
247 Generating
248 To generate a bson_oid_t, you may use the following.
249
250 bson_oid_t oid;
251
252 bson_oid_init (&oid, NULL);
253
254 Parsing ObjectID Strings
255 You can also parse a string containing a bson_oid_t. The input string
256 MUST be 24 characters or more in length.
257
258 bson_oid_t oid;
259
260 bson_oid_init_from_string (&oid, "123456789012345678901234");
261
262 bson_oid_t oid;
263
264 bson_oid_init_from_string_unsafe (&oid, "123456789012345678901234");
265
266 Hashing ObjectIDs
267 If you need to store items in a hashtable, you may want to use the
268 bson_oid_t as the key. Libbson provides a hash function for just this
269 purpose. It is based on DJB hash.
270
271 unsigned hash;
272
273 hash = bson_oid_hash (oid);
274
275 Fetching ObjectID Creation Time
276 You can easily fetch the time that a bson_oid_t was generated using
277 bson_oid_get_time_t().
278
279 time_t t;
280
281 t = bson_oid_get_time_t (oid);
282 printf ("The OID was generated at %u\n", (unsigned) t);
283
284 Parsing and Iterating BSON Documents
285 Parsing
286 BSON documents are lazily parsed as necessary. To begin parsing a BSON
287 document, use one of the provided Libbson functions to create a new
288 bson_t from existing data such as bson_new_from_data(). This will make
289 a copy of the data so that additional mutations may occur to the BSON
290 document.
291
292 TIP:
293 If you only want to parse a BSON document and have no need to mutate
294 it, you may use bson_init_static() to avoid making a copy of the
295 data.
296
297 bson_t *b;
298
299 b = bson_new_from_data (my_data, my_data_len);
300 if (!b) {
301 fprintf (stderr, "The specified length embedded in <my_data> did not match "
302 "<my_data_len>\n");
303 return;
304 }
305
306 bson_destroy (b);
307
308 Only two checks are performed when creating a new bson_t from an exist‐
309 ing buffer. First, the document must begin with the buffer length,
310 matching what was expected by the caller. Second, the document must end
311 with the expected trailing \0 byte.
312
313 To parse the document further we use a bson_iter_t to iterate the ele‐
314 ments within the document. Let's print all of the field names in the
315 document.
316
317 bson_t *b;
318 bson_iter_t iter;
319
320 if ((b = bson_new_from_data (my_data, my_data_len))) {
321 if (bson_iter_init (&iter, b)) {
322 while (bson_iter_next (&iter)) {
323 printf ("Found element key: \"%s\"\n", bson_iter_key (&iter));
324 }
325 }
326 bson_destroy (b);
327 }
328
329 Converting a document to JSON uses a bson_iter_t and bson_visitor_t to
330 iterate all fields of a BSON document recursively and generate a UTF-8
331 encoded JSON string.
332
333 bson_t *b;
334 char *json;
335
336 if ((b = bson_new_from_data (my_data, my_data_len))) {
337 if ((json = bson_as_canonical_extended_json (b, NULL))) {
338 printf ("%s\n", json);
339 bson_free (json);
340 }
341 bson_destroy (b);
342 }
343
344 Recursing into Sub-Documents
345 Libbson provides convenient sub-iterators to dive down into a sub-docu‐
346 ment or sub-array. Below is an example that will dive into a sub-docu‐
347 ment named "foo" and print it's field names.
348
349 bson_iter_t iter;
350 bson_iter_t child;
351 char *json;
352
353 if (bson_iter_init_find (&iter, doc, "foo") &&
354 BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) {
355 while (bson_iter_next (&child)) {
356 printf ("Found sub-key of \"foo\" named \"%s\"\n",
357 bson_iter_key (&child));
358 }
359 }
360
361 Finding Fields using Dot Notation
362 Using the bson_iter_recurse() function exemplified above,
363 bson_iter_find_descendant() can find a field for you using the MongoDB
364 style path notation such as "foo.bar.0.baz".
365
366 Let's create a document like {"foo": {"bar": [{"baz: 1}]}} and locate
367 the "baz" field.
368
369 bson_t *b;
370 bson_iter_t iter;
371 bson_iter_t baz;
372
373 b =
374 BCON_NEW ("foo", "{", "bar", "[", "{", "baz", BCON_INT32 (1), "}", "]", "}");
375
376 if (bson_iter_init (&iter, b) &&
377 bson_iter_find_descendant (&iter, "foo.bar.0.baz", &baz) &&
378 BSON_ITER_HOLDS_INT32 (&baz)) {
379 printf ("baz = %d\n", bson_iter_int32 (&baz));
380 }
381
382 bson_destroy (b);
383
384 Validating a BSON Document
385 If all you want to do is validate that a BSON document is valid, you
386 can use bson_validate().
387
388 size_t err_offset;
389
390 if (!bson_validate (doc, BSON_VALIDATE_NONE, &err_offset)) {
391 fprintf (stderr,
392 "The document failed to validate at offset: %u\n",
393 (unsigned) err_offset);
394 }
395
396 See the bson_validate() documentation for more information and exam‐
397 ples.
398
399 UTF-8
400 Encoding
401 Libbson expects that you are always working with UTF-8 encoded text.
402 Anything else is invalid API use.
403
404 If you should need to walk through UTF-8 sequences, you can use the
405 various UTF-8 helper functions distributed with Libbson.
406
407 Validating a UTF-8 Sequence
408 To validate the string contained in my_string, use the following. You
409 may pass -1 for the string length if you know the string is NULL-termi‐
410 nated.
411
412 if (!bson_utf8_validate (my_string, -1, false)) {
413 printf ("Validation failed.\n");
414 }
415
416 If my_string has NULL bytes within the string, you must provide the
417 string length. Use the following format. Notice the true at the end in‐
418 dicating \0 is allowed.
419
420 if (!bson_utf8_validate (my_string, my_string_len, true)) {
421 printf ("Validation failed.\n");
422 }
423
424 For more information see the API reference for bson_utf8_validate().
425
426 Guides
427 Streaming BSON
428 bson_reader_t provides a streaming reader which can be initialized with
429 a filedescriptor or memory region. bson_writer_t provides a streaming
430 writer which can be initialized with a memory region. (Streaming BSON
431 to a file descriptor is not yet supported.)
432
433 Reading from a BSON Stream
434 bson_reader_t provides a convenient API to read sequential BSON docu‐
435 ments from a file-descriptor or memory buffer. The bson_reader_read()
436 function will read forward in the underlying stream and return a bson_t
437 that can be inspected and iterated upon.
438
439 #include <stdio.h>
440 #include <bson/bson.h>
441
442 int
443 main (int argc, char *argv[])
444 {
445 bson_reader_t *reader;
446 const bson_t *doc;
447 bson_error_t error;
448 bool eof;
449
450 reader = bson_reader_new_from_file ("mycollection.bson", &error);
451
452 if (!reader) {
453 fprintf (stderr, "Failed to open file.\n");
454 return 1;
455 }
456
457 while ((doc = bson_reader_read (reader, &eof))) {
458 char *str = bson_as_canonical_extended_json (doc, NULL);
459 printf ("%s\n", str);
460 bson_free (str);
461 }
462
463 if (!eof) {
464 fprintf (stderr,
465 "corrupted bson document found at %u\n",
466 (unsigned) bson_reader_tell (reader));
467 }
468
469 bson_reader_destroy (reader);
470
471 return 0;
472 }
473
474 See bson_reader_new_from_fd(), bson_reader_new_from_file(), and
475 bson_reader_new_from_data() for more information.
476
477 Writing a sequence of BSON Documents
478 bson_writer_t provides a convenient API to write a sequence of BSON
479 documents to a memory buffer that can grow with realloc(). The
480 bson_writer_begin() and bson_writer_end() functions will manage the un‐
481 derlying buffer while building the sequence of documents.
482
483 This could also be useful if you want to write to a network packet
484 while serializing the documents from a higher level language, (but do
485 so just after the packets header).
486
487 #include <stdio.h>
488 #include <bson/bson.h>
489 #include <assert.h>
490
491 int
492 main (int argc, char *argv[])
493 {
494 bson_writer_t *writer;
495 bson_t *doc;
496 uint8_t *buf = NULL;
497 size_t buflen = 0;
498 bool r;
499 int i;
500
501 writer = bson_writer_new (&buf, &buflen, 0, bson_realloc_ctx, NULL);
502
503 for (i = 0; i < 10000; i++) {
504 r = bson_writer_begin (writer, &doc);
505 assert (r);
506
507 r = BSON_APPEND_INT32 (doc, "i", i);
508 assert (r);
509
510 bson_writer_end (writer);
511 }
512
513 bson_free (buf);
514
515 return 0;
516 }
517
518 See bson_writer_new() for more information.
519
520 JSON
521 Libbson provides routines for converting to and from the JSON format.
522 In particular, it supports the MongoDB extended JSON format.
523
524 Converting BSON to JSON
525 There are often times where you might want to convert a BSON document
526 to JSON. It is convenient for debugging as well as an interchange for‐
527 mat. To help with this, Libbson contains the functions bson_as_canoni‐
528 cal_extended_json() and bson_as_relaxed_extended_json(). The canonical
529 format preserves BSON type information for values that may have ambigu‐
530 ous representations in JSON (e.g. numeric types).
531
532 bson_t *b;
533 size_t len;
534 char *str;
535
536 b = BCON_NEW ("a", BCON_INT32 (1));
537
538 str = bson_as_canonical_extended_json (b, &len);
539 printf ("%s\n", str);
540 bson_free (str);
541
542 bson_destroy (b);
543
544 { "a" : { "$numberInt": "1" } }
545
546 The relaxed format prefers JSON primitives for numeric values and may
547 be used if type fidelity is not required.
548
549 bson_t *b;
550 size_t len;
551 char *str;
552
553 b = BCON_NEW ("a", BCON_INT32 (1));
554
555 str = bson_as_relaxed_extended_json (b, &len);
556 printf ("%s\n", str);
557 bson_free (str);
558
559 bson_destroy (b);
560
561 { "a" : 1 }
562
563 Converting JSON to BSON
564 Converting back from JSON is also useful and common enough that we
565 added bson_init_from_json() and bson_new_from_json().
566
567 The following example creates a new bson_t from the JSON string
568 {"a":1}.
569
570 bson_t *b;
571 bson_error_t error;
572
573 b = bson_new_from_json ("{\"a\":1}", -1, &error);
574
575 if (!b) {
576 printf ("Error: %s\n", error.message);
577 } else {
578 bson_destroy (b);
579 }
580
581 Streaming JSON Parsing
582 Libbson provides bson_json_reader_t to allow for parsing a sequence of
583 JSON documents into BSON. The interface is similar to bson_reader_t but
584 expects the input to be in the MongoDB extended JSON format.
585
586 /*
587 * Copyright 2013 MongoDB, Inc.
588 *
589 * Licensed under the Apache License, Version 2.0 (the "License");
590 * you may not use this file except in compliance with the License.
591 * You may obtain a copy of the License at
592 *
593 * http://www.apache.org/licenses/LICENSE-2.0
594 *
595 * Unless required by applicable law or agreed to in writing, software
596 * distributed under the License is distributed on an "AS IS" BASIS,
597 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
598 * See the License for the specific language governing permissions and
599 * limitations under the License.
600 */
601
602
603 /*
604 * This program will print each JSON document contained in the provided files
605 * as a BSON string to STDOUT.
606 */
607
608
609 #include <bson/bson.h>
610 #include <stdlib.h>
611 #include <stdio.h>
612
613
614 int
615 main (int argc, char *argv[])
616 {
617 bson_json_reader_t *reader;
618 bson_error_t error;
619 const char *filename;
620 bson_t doc = BSON_INITIALIZER;
621 int i;
622 int b;
623
624 /*
625 * Print program usage if no arguments are provided.
626 */
627 if (argc == 1) {
628 fprintf (stderr, "usage: %s FILE...\n", argv[0]);
629 return 1;
630 }
631
632 /*
633 * Process command line arguments expecting each to be a filename.
634 */
635 for (i = 1; i < argc; i++) {
636 filename = argv[i];
637
638 /*
639 * Open the filename provided in command line arguments.
640 */
641 if (0 == strcmp (filename, "-")) {
642 reader = bson_json_reader_new_from_fd (STDIN_FILENO, false);
643 } else {
644 if (!(reader = bson_json_reader_new_from_file (filename, &error))) {
645 fprintf (
646 stderr, "Failed to open \"%s\": %s\n", filename, error.message);
647 continue;
648 }
649 }
650
651 /*
652 * Convert each incoming document to BSON and print to stdout.
653 */
654 while ((b = bson_json_reader_read (reader, &doc, &error))) {
655 if (b < 0) {
656 fprintf (stderr, "Error in json parsing:\n%s\n", error.message);
657 abort ();
658 }
659
660 if (fwrite (bson_get_data (&doc), 1, doc.len, stdout) != doc.len) {
661 fprintf (stderr, "Failed to write to stdout, exiting.\n");
662 exit (1);
663 }
664 bson_reinit (&doc);
665 }
666
667 bson_json_reader_destroy (reader);
668 bson_destroy (&doc);
669 }
670
671 return 0;
672 }
673
674 Examples
675 The following example reads BSON documents from stdin and prints them
676 to stdout as JSON.
677
678 /*
679 * Copyright 2013 MongoDB, Inc.
680 *
681 * Licensed under the Apache License, Version 2.0 (the "License");
682 * you may not use this file except in compliance with the License.
683 * You may obtain a copy of the License at
684 *
685 * http://www.apache.org/licenses/LICENSE-2.0
686 *
687 * Unless required by applicable law or agreed to in writing, software
688 * distributed under the License is distributed on an "AS IS" BASIS,
689 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
690 * See the License for the specific language governing permissions and
691 * limitations under the License.
692 */
693
694
695 /*
696 * This program will print each BSON document contained in the provided files
697 * as a JSON string to STDOUT.
698 */
699
700
701 #include <bson/bson.h>
702 #include <stdio.h>
703
704
705 int
706 main (int argc, char *argv[])
707 {
708 bson_reader_t *reader;
709 const bson_t *b;
710 bson_error_t error;
711 const char *filename;
712 char *str;
713 int i;
714
715 /*
716 * Print program usage if no arguments are provided.
717 */
718 if (argc == 1) {
719 fprintf (stderr, "usage: %s [FILE | -]...\nUse - for STDIN.\n", argv[0]);
720 return 1;
721 }
722
723 /*
724 * Process command line arguments expecting each to be a filename.
725 */
726 for (i = 1; i < argc; i++) {
727 filename = argv[i];
728
729 if (strcmp (filename, "-") == 0) {
730 reader = bson_reader_new_from_fd (STDIN_FILENO, false);
731 } else {
732 if (!(reader = bson_reader_new_from_file (filename, &error))) {
733 fprintf (
734 stderr, "Failed to open \"%s\": %s\n", filename, error.message);
735 continue;
736 }
737 }
738
739 /*
740 * Convert each incoming document to JSON and print to stdout.
741 */
742 while ((b = bson_reader_read (reader, NULL))) {
743 str = bson_as_canonical_extended_json (b, NULL);
744 fprintf (stdout, "%s\n", str);
745 bson_free (str);
746 }
747
748 /*
749 * Cleanup after our reader, which closes the file descriptor.
750 */
751 bson_reader_destroy (reader);
752 }
753
754 return 0;
755 }
756
757 Use Valgrind to Check For BSON Data Leaks
758 A stack-allocated bson_t contains a small internal buffer; it only
759 heap-allocates additional storage if necessary, depending on its data
760 size. Therefore if you forget to call bson_destroy on a stack-allocated
761 bson_t, it might or might not cause a leak that can be detected by val‐
762 grind during testing.
763
764 To catch all potential BSON data leaks in your code, configure the
765 BSON_MEMCHECK flag:
766
767 cmake -DCMAKE_C_FLAGS="-DBSON_MEMCHECK -g" .
768
769 With this flag set, every bson_t mallocs at least one byte. Run your
770 program's unittests with valgrind to verify all bson_t structs are de‐
771 stroyed.
772
773 Set the environment variable MONGOC_TEST_VALGRIND to on to skip tim‐
774 ing-dependent tests known to fail with valgrind.
775
776 Cross Platform Notes
777 Endianness
778 The BSON specification dictates that the encoding format is in lit‐
779 tle-endian. Many implementations simply ignore endianness altogether
780 and expect that they are to be run on little-endian. Libbson supports
781 both Big and Little Endian systems. This means we use memcpy() when ap‐
782 propriate instead of dereferencing and properly convert to and from the
783 host endian format. We expect the compiler intrinsics to optimize it to
784 a dereference when possible.
785
786 Threading
787 Libbson's data structures are NOT thread-safe. You are responsible for
788 accessing and mutating these structures from one thread at a time.
789
790 Libbson requires POSIX threads (pthreads) on all UNIX-like platforms.
791 On Windows, the native threading interface is used. Libbson uses your
792 system's threading library to safely generate unique ObjectIds, and to
793 provide a fallback implementation for atomic operations on platforms
794 without built-in atomics.
795
796 API Reference
797 bson_t
798 BSON Document Abstraction
799
800 Synopsis
801 #include <bson/bson.h>
802
803 /**
804 * bson_empty:
805 * @b: a bson_t.
806 *
807 * Checks to see if @b is an empty BSON document. An empty BSON document is
808 * a 5 byte document which contains the length (4 bytes) and a single NUL
809 * byte indicating end of fields.
810 */
811 #define bson_empty(b) /* ... */
812
813 /**
814 * bson_empty0:
815 *
816 * Like bson_empty() but treats NULL the same as an empty bson_t document.
817 */
818 #define bson_empty0(b) /* ... */
819
820 /**
821 * bson_clear:
822 *
823 * Easily free a bson document and set it to NULL. Use like:
824 *
825 * bson_t *doc = bson_new();
826 * bson_clear (&doc);
827 * BSON_ASSERT (doc == NULL);
828 */
829 #define bson_clear(bptr) /* ... */
830
831 /**
832 * BSON_MAX_SIZE:
833 *
834 * The maximum size in bytes of a BSON document.
835 */
836 #define BSON_MAX_SIZE /* ... */
837
838 #define BSON_APPEND_ARRAY(b, key, val) \
839 bson_append_array (b, key, (int) strlen (key), val)
840
841 #define BSON_APPEND_ARRAY_BEGIN(b, key, child) \
842 bson_append_array_begin (b, key, (int) strlen (key), child)
843
844 #define BSON_APPEND_BINARY(b, key, subtype, val, len) \
845 bson_append_binary (b, key, (int) strlen (key), subtype, val, len)
846
847 #define BSON_APPEND_BOOL(b, key, val) \
848 bson_append_bool (b, key, (int) strlen (key), val)
849
850 #define BSON_APPEND_CODE(b, key, val) \
851 bson_append_code (b, key, (int) strlen (key), val)
852
853 #define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \
854 bson_append_code_with_scope (b, key, (int) strlen (key), val, scope)
855
856 #define BSON_APPEND_DBPOINTER(b, key, coll, oid) \
857 bson_append_dbpointer (b, key, (int) strlen (key), coll, oid)
858
859 #define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \
860 bson_append_document_begin (b, key, (int) strlen (key), child)
861
862 #define BSON_APPEND_DOUBLE(b, key, val) \
863 bson_append_double (b, key, (int) strlen (key), val)
864
865 #define BSON_APPEND_DOCUMENT(b, key, val) \
866 bson_append_document (b, key, (int) strlen (key), val)
867
868 #define BSON_APPEND_INT32(b, key, val) \
869 bson_append_int32 (b, key, (int) strlen (key), val)
870
871 #define BSON_APPEND_INT64(b, key, val) \
872 bson_append_int64 (b, key, (int) strlen (key), val)
873
874 #define BSON_APPEND_MINKEY(b, key) \
875 bson_append_minkey (b, key, (int) strlen (key))
876
877 #define BSON_APPEND_DECIMAL128(b, key, val) \
878 bson_append_decimal128 (b, key, (int) strlen (key), val)
879
880 #define BSON_APPEND_MAXKEY(b, key) \
881 bson_append_maxkey (b, key, (int) strlen (key))
882
883 #define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key))
884
885 #define BSON_APPEND_OID(b, key, val) \
886 bson_append_oid (b, key, (int) strlen (key), val)
887
888 #define BSON_APPEND_REGEX(b, key, val, opt) \
889 bson_append_regex (b, key, (int) strlen (key), val, opt)
890
891 #define BSON_APPEND_UTF8(b, key, val) \
892 bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val))
893
894 #define BSON_APPEND_SYMBOL(b, key, val) \
895 bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val))
896
897 #define BSON_APPEND_TIME_T(b, key, val) \
898 bson_append_time_t (b, key, (int) strlen (key), val)
899
900 #define BSON_APPEND_TIMEVAL(b, key, val) \
901 bson_append_timeval (b, key, (int) strlen (key), val)
902
903 #define BSON_APPEND_DATE_TIME(b, key, val) \
904 bson_append_date_time (b, key, (int) strlen (key), val)
905
906 #define BSON_APPEND_TIMESTAMP(b, key, val, inc) \
907 bson_append_timestamp (b, key, (int) strlen (key), val, inc)
908
909 #define BSON_APPEND_UNDEFINED(b, key) \
910 bson_append_undefined (b, key, (int) strlen (key))
911
912 #define BSON_APPEND_VALUE(b, key, val) \
913 bson_append_value (b, key, (int) strlen (key), (val))
914
915 BSON_ALIGNED_BEGIN (128)
916 typedef struct {
917 uint32_t flags; /* Internal flags for the bson_t. */
918 uint32_t len; /* Length of BSON data. */
919 uint8_t padding[120]; /* Padding for stack allocation. */
920 } bson_t BSON_ALIGNED_END (128);
921
922 Description
923 The bson_t structure represents a BSON document. This structure manages
924 the underlying BSON encoded buffer. For mutable documents, it can ap‐
925 pend new data to the document.
926
927 Performance Notes
928 The bson_t structure attempts to use an inline allocation within the
929 structure to speed up performance of small documents. When this inter‐
930 nal buffer has been exhausted, a heap allocated buffer will be dynami‐
931 cally allocated. Therefore, it is essential to call bson_destroy() on
932 allocated documents.
933
934 Example
935 static void
936 create_on_heap (void)
937 {
938 bson_t *b = bson_new ();
939
940 BSON_APPEND_INT32 (b, "foo", 123);
941 BSON_APPEND_UTF8 (b, "bar", "foo");
942 BSON_APPEND_DOUBLE (b, "baz", 1.23f);
943
944 bson_destroy (b);
945 }
946
947 bson_context_t
948 BSON OID Generation Context
949
950 Synopsis
951 #include <bson/bson.h>
952
953 typedef enum {
954 BSON_CONTEXT_NONE = 0,
955 BSON_CONTEXT_THREAD_SAFE = (1 << 0),
956 BSON_CONTEXT_DISABLE_HOST_CACHE = (1 << 1),
957 BSON_CONTEXT_DISABLE_PID_CACHE = (1 << 2),
958 #ifdef BSON_HAVE_SYSCALL_TID
959 BSON_CONTEXT_USE_TASK_ID = (1 << 3),
960 #endif
961 } bson_context_flags_t;
962
963 typedef struct _bson_context_t bson_context_t;
964
965 bson_context_t *
966 bson_context_get_default (void) BSON_GNUC_CONST;
967 bson_context_t *
968 bson_context_new (bson_context_flags_t flags);
969 void
970 bson_context_destroy (bson_context_t *context);
971
972 Description
973 The bson_context_t structure is context for generation of BSON Object
974 IDs. This context allows overriding behavior of generating ObjectIDs.
975 The flags BSON_CONTEXT_NONE, BSON_CONTEXT_THREAD_SAFE, and BSON_CON‐
976 TEXT_DISABLE_PID_CACHE are the only ones used. The others have no ef‐
977 fect.
978
979 Example
980 #include <bson/bson.h>
981
982 int
983 main (int argc, char *argv[])
984 {
985 bson_context_t *ctx = NULL;
986 bson_oid_t oid;
987
988 /* use default context, via bson_context_get_default() */
989 bson_oid_init (&oid, NULL);
990
991 /* specify a local context for additional control */
992 ctx = bson_context_new (BSON_CONTEXT_THREAD_SAFE);
993 bson_oid_init (&oid, ctx);
994
995 bson_context_destroy (ctx);
996
997 return 0;
998 }
999
1000 bson_decimal128_t
1001 BSON Decimal128 Abstraction
1002
1003 Synopsis
1004 #include <bson/bson.h>
1005
1006 #define BSON_DECIMAL128_STRING 43
1007 #define BSON_DECIMAL128_INF "Infinity"
1008 #define BSON_DECIMAL128_NAN "NaN"
1009
1010 typedef struct {
1011 #if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
1012 uint64_t low;
1013 uint64_t high;
1014 #elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN
1015 uint64_t high;
1016 uint64_t low;
1017 #endif
1018 } bson_decimal128_t;
1019
1020 Description
1021 The bson_decimal128_t structure represents the IEEE-754 Decimal128 data
1022 type.
1023
1024 Example
1025 #include <bson/bson.h>
1026 #include <stdio.h>
1027
1028 int
1029 main (int argc, char *argv[])
1030 {
1031 char string[BSON_DECIMAL128_STRING];
1032 bson_decimal128_t decimal128;
1033
1034 bson_decimal128_from_string ("100.00", &decimal128);
1035 bson_decimal128_to_string (&decimal128, string);
1036 printf ("Decimal128 value: %s\n", string);
1037
1038 return 0;
1039 }
1040
1041 bson_error_t
1042 BSON Error Encapsulation
1043
1044 Synopsis
1045 #include <bson/bson.h>
1046
1047 typedef struct {
1048 uint32_t domain;
1049 uint32_t code;
1050 char message[504];
1051 } bson_error_t;
1052
1053 Description
1054 The bson_error_t structure is used as an out-parameter to pass error
1055 information to the caller. It should be stack-allocated and does not
1056 requiring freeing.
1057
1058 See Handling Errors.
1059
1060 Example
1061 bson_reader_t *reader;
1062 bson_error_t error;
1063
1064 reader = bson_reader_new_from_file ("dump.bson", &error);
1065 if (!reader) {
1066 fprintf (
1067 stderr, "ERROR: %d.%d: %s\n", error.domain, error.code, error.message);
1068 }
1069
1070 bson_iter_t
1071 BSON Document Iterator
1072
1073 Synopsis
1074 #include <bson/bson.h>
1075
1076 #define BSON_ITER_HOLDS_DOUBLE(iter) /* ... */
1077
1078 #define BSON_ITER_HOLDS_UTF8(iter) /* ... */
1079
1080 #define BSON_ITER_HOLDS_DOCUMENT(iter) /* ... */
1081
1082 #define BSON_ITER_HOLDS_ARRAY(iter) /* ... */
1083
1084 #define BSON_ITER_HOLDS_BINARY(iter) /* ... */
1085
1086 #define BSON_ITER_HOLDS_UNDEFINED(iter) /* ... */
1087
1088 #define BSON_ITER_HOLDS_OID(iter) /* ... */
1089
1090 #define BSON_ITER_HOLDS_BOOL(iter) /* ... */
1091
1092 #define BSON_ITER_HOLDS_DATE_TIME(iter) /* ... */
1093
1094 #define BSON_ITER_HOLDS_NULL(iter) /* ... */
1095
1096 #define BSON_ITER_HOLDS_REGEX(iter) /* ... */
1097
1098 #define BSON_ITER_HOLDS_DBPOINTER(iter) /* ... */
1099
1100 #define BSON_ITER_HOLDS_CODE(iter) /* ... */
1101
1102 #define BSON_ITER_HOLDS_SYMBOL(iter) /* ... */
1103
1104 #define BSON_ITER_HOLDS_CODEWSCOPE(iter) /* ... */
1105
1106 #define BSON_ITER_HOLDS_INT32(iter) /* ... */
1107
1108 #define BSON_ITER_HOLDS_TIMESTAMP(iter) /* ... */
1109
1110 #define BSON_ITER_HOLDS_INT64(iter) /* ... */
1111
1112 #define BSON_ITER_HOLDS_DECIMAL128(iter) /* ... */
1113
1114 #define BSON_ITER_HOLDS_MAXKEY(iter) /* ... */
1115
1116 #define BSON_ITER_HOLDS_MINKEY(iter) /* ... */
1117
1118 #define BSON_ITER_HOLDS_INT(iter) \
1119 (BSON_ITER_HOLDS_INT32 (iter) || BSON_ITER_HOLDS_INT64 (iter))
1120
1121 #define BSON_ITER_HOLDS_NUMBER(iter) \
1122 (BSON_ITER_HOLDS_INT (iter) || BSON_ITER_HOLDS_DOUBLE (iter))
1123
1124 #define BSON_ITER_IS_KEY(iter, key) \
1125 (0 == strcmp ((key), bson_iter_key ((iter))))
1126
1127 typedef struct {
1128 /*< private >*/
1129 } bson_iter_t;
1130
1131 Description
1132 bson_iter_t is a structure used to iterate through the elements of a
1133 bson_t. It is meant to be used on the stack and can be discarded at any
1134 time as it contains no external allocation. The contents of the struc‐
1135 ture should be considered private and may change between releases, how‐
1136 ever the structure size will not change.
1137
1138 The bson_t MUST be valid for the lifetime of the iter and it is an er‐
1139 ror to modify the bson_t while using the iter.
1140
1141 Examples
1142 bson_iter_t iter;
1143
1144 if (bson_iter_init (&iter, my_bson_doc)) {
1145 while (bson_iter_next (&iter)) {
1146 printf ("Found a field named: %s\n", bson_iter_key (&iter));
1147 }
1148 }
1149
1150 bson_iter_t iter;
1151
1152 if (bson_iter_init (&iter, my_bson_doc) && bson_iter_find (&iter, "my_field")) {
1153 printf ("Found the field named: %s\n", bson_iter_key (&iter));
1154 }
1155
1156 bson_iter_t iter;
1157 bson_iter_t sub_iter;
1158
1159 if (bson_iter_init_find (&iter, my_bson_doc, "mysubdoc") &&
1160 (BSON_ITER_HOLDS_DOCUMENT (&iter) || BSON_ITER_HOLDS_ARRAY (&iter)) &&
1161 bson_iter_recurse (&iter, &sub_iter)) {
1162 while (bson_iter_next (&sub_iter)) {
1163 printf ("Found key \"%s\" in sub document.\n", bson_iter_key (&sub_iter));
1164 }
1165 }
1166
1167 bson_iter_t iter;
1168
1169 if (bson_iter_init (&iter, my_doc) &&
1170 bson_iter_find_descendant (&iter, "a.b.c.d", &sub_iter)) {
1171 printf ("The type of a.b.c.d is: %d\n", (int) bson_iter_type (&sub_iter));
1172 }
1173
1174 bson_json_reader_t
1175 Bulk JSON to BSON conversion
1176
1177 Synopsis
1178 #include <bson/bson.h>
1179
1180 typedef struct _bson_json_reader_t bson_json_reader_t;
1181
1182 typedef enum {
1183 BSON_JSON_ERROR_READ_CORRUPT_JS = 1,
1184 BSON_JSON_ERROR_READ_INVALID_PARAM,
1185 BSON_JSON_ERROR_READ_CB_FAILURE,
1186 } bson_json_error_code_t;
1187
1188 Description
1189 The bson_json_reader_t structure is used for reading a sequence of JSON
1190 documents and transforming them to bson_t documents.
1191
1192 This can often be useful if you want to perform bulk operations that
1193 are defined in a file containing JSON documents.
1194
1195 TIP:
1196 bson_json_reader_t works upon JSON documents formatted in MongoDB
1197 extended JSON format.
1198
1199 Example
1200 /*
1201 * Copyright 2013 MongoDB, Inc.
1202 *
1203 * Licensed under the Apache License, Version 2.0 (the "License");
1204 * you may not use this file except in compliance with the License.
1205 * You may obtain a copy of the License at
1206 *
1207 * http://www.apache.org/licenses/LICENSE-2.0
1208 *
1209 * Unless required by applicable law or agreed to in writing, software
1210 * distributed under the License is distributed on an "AS IS" BASIS,
1211 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212 * See the License for the specific language governing permissions and
1213 * limitations under the License.
1214 */
1215
1216
1217 /*
1218 * This program will print each JSON document contained in the provided files
1219 * as a BSON string to STDOUT.
1220 */
1221
1222
1223 #include <bson/bson.h>
1224 #include <stdlib.h>
1225 #include <stdio.h>
1226
1227
1228 int
1229 main (int argc, char *argv[])
1230 {
1231 bson_json_reader_t *reader;
1232 bson_error_t error;
1233 const char *filename;
1234 bson_t doc = BSON_INITIALIZER;
1235 int i;
1236 int b;
1237
1238 /*
1239 * Print program usage if no arguments are provided.
1240 */
1241 if (argc == 1) {
1242 fprintf (stderr, "usage: %s FILE...\n", argv[0]);
1243 return 1;
1244 }
1245
1246 /*
1247 * Process command line arguments expecting each to be a filename.
1248 */
1249 for (i = 1; i < argc; i++) {
1250 filename = argv[i];
1251
1252 /*
1253 * Open the filename provided in command line arguments.
1254 */
1255 if (0 == strcmp (filename, "-")) {
1256 reader = bson_json_reader_new_from_fd (STDIN_FILENO, false);
1257 } else {
1258 if (!(reader = bson_json_reader_new_from_file (filename, &error))) {
1259 fprintf (
1260 stderr, "Failed to open \"%s\": %s\n", filename, error.message);
1261 continue;
1262 }
1263 }
1264
1265 /*
1266 * Convert each incoming document to BSON and print to stdout.
1267 */
1268 while ((b = bson_json_reader_read (reader, &doc, &error))) {
1269 if (b < 0) {
1270 fprintf (stderr, "Error in json parsing:\n%s\n", error.message);
1271 abort ();
1272 }
1273
1274 if (fwrite (bson_get_data (&doc), 1, doc.len, stdout) != doc.len) {
1275 fprintf (stderr, "Failed to write to stdout, exiting.\n");
1276 exit (1);
1277 }
1278 bson_reinit (&doc);
1279 }
1280
1281 bson_json_reader_destroy (reader);
1282 bson_destroy (&doc);
1283 }
1284
1285 return 0;
1286 }
1287
1288 bson_md5_t
1289 BSON MD5 Abstraction
1290
1291 Deprecated
1292 All MD5 APIs are deprecated in libbson.
1293
1294 Synopsis
1295 typedef struct {
1296 uint32_t count[2]; /* message length in bits, lsw first */
1297 uint32_t abcd[4]; /* digest buffer */
1298 uint8_t buf[64]; /* accumulate block */
1299 } bson_md5_t;
1300
1301 Description
1302 bson_md5_t encapsulates an implementation of the MD5 algorithm.
1303
1304 bson_oid_t
1305 BSON ObjectID Abstraction
1306
1307 Synopsis
1308 #include <bson/bson.h>
1309
1310 typedef struct {
1311 uint8_t bytes[12];
1312 } bson_oid_t;
1313
1314 Description
1315 The bson_oid_t structure contains the 12-byte ObjectId notation defined
1316 by the BSON ObjectID specification.
1317
1318 ObjectId is a 12-byte BSON type, constructed using:
1319
1320 • a 4-byte value representing the seconds since the Unix epoch (in Big
1321 Endian).
1322
1323 • a 5-byte random value.
1324
1325 • a 3-byte counter (Big Endian), starting with a random value.
1326
1327 String Conversion
1328 You can convert an Object ID to a string using bson_oid_to_string() and
1329 back with bson_oid_init_from_string().
1330
1331 Hashing
1332 A bson_oid_t can be used in hashtables using the function
1333 bson_oid_hash() and bson_oid_equal().
1334
1335 Comparing
1336 A bson_oid_t can be compared to another using bson_oid_compare() for
1337 qsort() style comparing and bson_oid_equal() for direct equality.
1338
1339 Validating
1340 You can validate that a string containing a hex-encoded ObjectID is
1341 valid using the function bson_oid_is_valid().
1342
1343 Example
1344 #include <bson/bson.h>
1345 #include <stdio.h>
1346
1347 int
1348 main (int argc, char *argv[])
1349 {
1350 bson_oid_t oid;
1351 char str[25];
1352
1353 bson_oid_init (&oid, NULL);
1354 bson_oid_to_string (&oid, str);
1355 printf ("%s\n", str);
1356
1357 if (bson_oid_is_valid (str, sizeof str)) {
1358 bson_oid_init_from_string (&oid, str);
1359 }
1360
1361 printf ("The UNIX time was: %u\n", (unsigned) bson_oid_get_time_t (&oid));
1362
1363 return 0;
1364 }
1365
1366 bson_reader_t
1367 Streaming BSON Document Reader
1368
1369 Synopsis
1370 #include <bson/bson.h>
1371
1372 typedef struct _bson_reader_t bson_reader_t;
1373
1374 bson_reader_t *
1375 bson_reader_new_from_handle (void *handle,
1376 bson_reader_read_func_t rf,
1377 bson_reader_destroy_func_t df);
1378 bson_reader_t *
1379 bson_reader_new_from_fd (int fd, bool close_on_destroy);
1380 bson_reader_t *
1381 bson_reader_new_from_file (const char *path, bson_error_t *error);
1382 bson_reader_t *
1383 bson_reader_new_from_data (const uint8_t *data, size_t length);
1384
1385 void
1386 bson_reader_destroy (bson_reader_t *reader);
1387
1388 Description
1389 bson_reader_t is a structure used for reading a sequence of BSON docu‐
1390 ments. The sequence can come from a file-descriptor, memory region, or
1391 custom callbacks.
1392
1393 Example
1394 /*
1395 * Copyright 2013 MongoDB, Inc.
1396 *
1397 * Licensed under the Apache License, Version 2.0 (the "License");
1398 * you may not use this file except in compliance with the License.
1399 * You may obtain a copy of the License at
1400 *
1401 * http://www.apache.org/licenses/LICENSE-2.0
1402 *
1403 * Unless required by applicable law or agreed to in writing, software
1404 * distributed under the License is distributed on an "AS IS" BASIS,
1405 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1406 * See the License for the specific language governing permissions and
1407 * limitations under the License.
1408 */
1409
1410
1411 /*
1412 * This program will print each BSON document contained in the provided files
1413 * as a JSON string to STDOUT.
1414 */
1415
1416
1417 #include <bson/bson.h>
1418 #include <stdio.h>
1419
1420
1421 int
1422 main (int argc, char *argv[])
1423 {
1424 bson_reader_t *reader;
1425 const bson_t *b;
1426 bson_error_t error;
1427 const char *filename;
1428 char *str;
1429 int i;
1430
1431 /*
1432 * Print program usage if no arguments are provided.
1433 */
1434 if (argc == 1) {
1435 fprintf (stderr, "usage: %s [FILE | -]...\nUse - for STDIN.\n", argv[0]);
1436 return 1;
1437 }
1438
1439 /*
1440 * Process command line arguments expecting each to be a filename.
1441 */
1442 for (i = 1; i < argc; i++) {
1443 filename = argv[i];
1444
1445 if (strcmp (filename, "-") == 0) {
1446 reader = bson_reader_new_from_fd (STDIN_FILENO, false);
1447 } else {
1448 if (!(reader = bson_reader_new_from_file (filename, &error))) {
1449 fprintf (
1450 stderr, "Failed to open \"%s\": %s\n", filename, error.message);
1451 continue;
1452 }
1453 }
1454
1455 /*
1456 * Convert each incoming document to JSON and print to stdout.
1457 */
1458 while ((b = bson_reader_read (reader, NULL))) {
1459 str = bson_as_canonical_extended_json (b, NULL);
1460 fprintf (stdout, "%s\n", str);
1461 bson_free (str);
1462 }
1463
1464 /*
1465 * Cleanup after our reader, which closes the file descriptor.
1466 */
1467 bson_reader_destroy (reader);
1468 }
1469
1470 return 0;
1471 }
1472
1473 Character and String Routines
1474 We provide a small number of character and string routines to substi‐
1475 tute for those that are not available on all platforms, and routines to
1476 make UTF-8 character manipulation convenient.
1477
1478 bson_string_t
1479 String Building Abstraction
1480
1481 Synopsis
1482 #include <bson/bson.h>
1483
1484 typedef struct {
1485 char *str;
1486 uint32_t len;
1487 uint32_t alloc;
1488 } bson_string_t;
1489
1490 Description
1491 bson_string_t is an abstraction for building strings. As chunks are
1492 added to the string, allocations are performed in powers of two.
1493
1494 This API is useful if you need to build UTF-8 encoded strings.
1495
1496 Example
1497 bson_string_t *str;
1498
1499 str = bson_string_new (NULL);
1500 bson_string_append_printf (str, "%d %s %f\n", 0, "some string", 0.123);
1501 printf ("%s\n", str->str);
1502
1503 bson_string_free (str, true);
1504
1505 TIP:
1506 You can call bson_string_free() with false if you would like to take
1507 ownership of str->str. Some APIs that do this might call return
1508 bson_string_free (str, false); after building the string.
1509
1510 bson_subtype_t
1511 Binary Field Subtype
1512
1513 Synopsis
1514 #include <bson/bson.h>
1515
1516
1517 typedef enum {
1518 BSON_SUBTYPE_BINARY = 0x00,
1519 BSON_SUBTYPE_FUNCTION = 0x01,
1520 BSON_SUBTYPE_BINARY_DEPRECATED = 0x02,
1521 BSON_SUBTYPE_UUID_DEPRECATED = 0x03,
1522 BSON_SUBTYPE_UUID = 0x04,
1523 BSON_SUBTYPE_MD5 = 0x05,
1524 BSON_SUBTYPE_COLUMN = 0x07,
1525 BSON_SUBTYPE_USER = 0x80,
1526 } bson_subtype_t;
1527
1528 Description
1529 This enumeration contains the various subtypes that may be used in a
1530 binary field. See http://bsonspec.org for more information.
1531
1532 Example
1533 bson_t doc = BSON_INITIALIZER;
1534
1535 BSON_APPEND_BINARY (&doc, "binary", BSON_SUBTYPE_BINARY, data, data_len);
1536
1537 bson_type_t
1538 BSON Type Enumeration
1539
1540 Synopsis
1541 #include <bson/bson.h>
1542
1543 typedef enum {
1544 BSON_TYPE_EOD = 0x00,
1545 BSON_TYPE_DOUBLE = 0x01,
1546 BSON_TYPE_UTF8 = 0x02,
1547 BSON_TYPE_DOCUMENT = 0x03,
1548 BSON_TYPE_ARRAY = 0x04,
1549 BSON_TYPE_BINARY = 0x05,
1550 BSON_TYPE_UNDEFINED = 0x06,
1551 BSON_TYPE_OID = 0x07,
1552 BSON_TYPE_BOOL = 0x08,
1553 BSON_TYPE_DATE_TIME = 0x09,
1554 BSON_TYPE_NULL = 0x0A,
1555 BSON_TYPE_REGEX = 0x0B,
1556 BSON_TYPE_DBPOINTER = 0x0C,
1557 BSON_TYPE_CODE = 0x0D,
1558 BSON_TYPE_SYMBOL = 0x0E,
1559 BSON_TYPE_CODEWSCOPE = 0x0F,
1560 BSON_TYPE_INT32 = 0x10,
1561 BSON_TYPE_TIMESTAMP = 0x11,
1562 BSON_TYPE_INT64 = 0x12,
1563 BSON_TYPE_DECIMAL128 = 0x13,
1564 BSON_TYPE_MAXKEY = 0x7F,
1565 BSON_TYPE_MINKEY = 0xFF,
1566 } bson_type_t;
1567
1568 Description
1569 The bson_type_t enumeration contains all of the types from the BSON
1570 Specification. It can be used to determine the type of a field at run‐
1571 time.
1572
1573 Example
1574 bson_iter_t iter;
1575
1576 if (bson_iter_init_find (&iter, doc, "foo") &&
1577 (BSON_TYPE_INT32 == bson_iter_type (&iter))) {
1578 printf ("'foo' is an int32.\n");
1579 }
1580
1581 bson_unichar_t
1582 Unicode Character Abstraction
1583
1584 Synopsis
1585 typedef uint32_t bson_unichar_t;
1586
1587 Description
1588 bson_unichar_t provides an abstraction on a single unicode character.
1589 It is the 32-bit representation of a character. As UTF-8 can contain
1590 multi-byte characters, this should be used when iterating through UTF-8
1591 text.
1592
1593 Example
1594 static void
1595 print_each_char (const char *str)
1596 {
1597 bson_unichar_t c;
1598
1599 for (; *str; str = bson_utf8_next_char (str)) {
1600 c = bson_utf8_get_char (str);
1601 printf ("The numberic value is %u.\n", (unsigned) c);
1602 }
1603 }
1604
1605 bson_value_t
1606 BSON Boxed Container Type
1607
1608 Synopsis
1609 #include <bson/bson.h>
1610
1611 typedef struct _bson_value_t {
1612 bson_type_t value_type;
1613 union {
1614 bson_oid_t v_oid;
1615 int64_t v_int64;
1616 int32_t v_int32;
1617 int8_t v_int8;
1618 double v_double;
1619 bool v_bool;
1620 int64_t v_datetime;
1621 struct {
1622 uint32_t timestamp;
1623 uint32_t increment;
1624 } v_timestamp;
1625 struct {
1626 uint32_t len;
1627 char *str;
1628 } v_utf8;
1629 struct {
1630 uint32_t data_len;
1631 uint8_t *data;
1632 } v_doc;
1633 struct {
1634 uint32_t data_len;
1635 uint8_t *data;
1636 bson_subtype_t subtype;
1637 } v_binary;
1638 struct {
1639 char *regex;
1640 char *options;
1641 } v_regex;
1642 struct {
1643 char *collection;
1644 uint32_t collection_len;
1645 bson_oid_t oid;
1646 } v_dbpointer;
1647 struct {
1648 uint32_t code_len;
1649 char *code;
1650 } v_code;
1651 struct {
1652 uint32_t code_len;
1653 char *code;
1654 uint32_t scope_len;
1655 uint8_t *scope_data;
1656 } v_codewscope;
1657 struct {
1658 uint32_t len;
1659 char *symbol;
1660 } v_symbol;
1661 } value;
1662 } bson_value_t;
1663
1664 Description
1665 The bson_value_t structure is a boxed type for encapsulating a runtime
1666 determined type.
1667
1668 Example
1669 const bson_value_t *value;
1670
1671 value = bson_iter_value (&iter);
1672
1673 if (value->value_type == BSON_TYPE_INT32) {
1674 printf ("%d\n", value->value.v_int32);
1675 }
1676
1677 bson_visitor_t
1678 Synopsis
1679 #include <bson/bson.h>
1680
1681 typedef struct {
1682 /* run before / after descending into a document */
1683 bool (*visit_before) (const bson_iter_t *iter, const char *key, void *data);
1684 bool (*visit_after) (const bson_iter_t *iter, const char *key, void *data);
1685 /* corrupt BSON, or unsupported type and visit_unsupported_type not set */
1686 void (*visit_corrupt) (const bson_iter_t *iter, void *data);
1687 /* normal bson field callbacks */
1688 bool (*visit_double) (const bson_iter_t *iter,
1689 const char *key,
1690 double v_double,
1691 void *data);
1692 bool (*visit_utf8) (const bson_iter_t *iter,
1693 const char *key,
1694 size_t v_utf8_len,
1695 const char *v_utf8,
1696 void *data);
1697 bool (*visit_document) (const bson_iter_t *iter,
1698 const char *key,
1699 const bson_t *v_document,
1700 void *data);
1701 bool (*visit_array) (const bson_iter_t *iter,
1702 const char *key,
1703 const bson_t *v_array,
1704 void *data);
1705 bool (*visit_binary) (const bson_iter_t *iter,
1706 const char *key,
1707 bson_subtype_t v_subtype,
1708 size_t v_binary_len,
1709 const uint8_t *v_binary,
1710 void *data);
1711 /* normal field with deprecated "Undefined" BSON type */
1712 bool (*visit_undefined) (const bson_iter_t *iter,
1713 const char *key,
1714 void *data);
1715 bool (*visit_oid) (const bson_iter_t *iter,
1716 const char *key,
1717 const bson_oid_t *v_oid,
1718 void *data);
1719 bool (*visit_bool) (const bson_iter_t *iter,
1720 const char *key,
1721 bool v_bool,
1722 void *data);
1723 bool (*visit_date_time) (const bson_iter_t *iter,
1724 const char *key,
1725 int64_t msec_since_epoch,
1726 void *data);
1727 bool (*visit_null) (const bson_iter_t *iter, const char *key, void *data);
1728 bool (*visit_regex) (const bson_iter_t *iter,
1729 const char *key,
1730 const char *v_regex,
1731 const char *v_options,
1732 void *data);
1733 bool (*visit_dbpointer) (const bson_iter_t *iter,
1734 const char *key,
1735 size_t v_collection_len,
1736 const char *v_collection,
1737 const bson_oid_t *v_oid,
1738 void *data);
1739 bool (*visit_code) (const bson_iter_t *iter,
1740 const char *key,
1741 size_t v_code_len,
1742 const char *v_code,
1743 void *data);
1744 bool (*visit_symbol) (const bson_iter_t *iter,
1745 const char *key,
1746 size_t v_symbol_len,
1747 const char *v_symbol,
1748 void *data);
1749 bool (*visit_codewscope) (const bson_iter_t *iter,
1750 const char *key,
1751 size_t v_code_len,
1752 const char *v_code,
1753 const bson_t *v_scope,
1754 void *data);
1755 bool (*visit_int32) (const bson_iter_t *iter,
1756 const char *key,
1757 int32_t v_int32,
1758 void *data);
1759 bool (*visit_timestamp) (const bson_iter_t *iter,
1760 const char *key,
1761 uint32_t v_timestamp,
1762 uint32_t v_increment,
1763 void *data);
1764 bool (*visit_int64) (const bson_iter_t *iter,
1765 const char *key,
1766 int64_t v_int64,
1767 void *data);
1768 bool (*visit_maxkey) (const bson_iter_t *iter, const char *key, void *data);
1769 bool (*visit_minkey) (const bson_iter_t *iter, const char *key, void *data);
1770 /* if set, called instead of visit_corrupt when an apparently valid BSON
1771 * includes an unrecognized field type (reading future version of BSON) */
1772 void (*visit_unsupported_type) (const bson_iter_t *iter,
1773 const char *key,
1774 uint32_t type_code,
1775 void *data);
1776 bool (*visit_decimal128) (const bson_iter_t *iter,
1777 const char *key,
1778 const bson_decimal128_t *v_decimal128,
1779 void *data);
1780
1781 void *padding[7];
1782 } bson_visitor_t bson_visitor_t;
1783
1784 Description
1785 The bson_visitor_t structure provides a series of callbacks that can be
1786 called while iterating a BSON document. This may simplify the conver‐
1787 sion of a bson_t to a higher level language structure.
1788
1789 If the optional callback visit_unsupported_type is set, it is called
1790 instead of visit_corrupt in the specific case of an unrecognized field
1791 type. (Parsing is aborted in either case.) Use this callback to report
1792 an error like "unrecognized type" instead of simply "corrupt BSON".
1793 This future-proofs code that may use an older version of libbson to
1794 parse future BSON formats.
1795
1796 Basic Example
1797 #include <bson/bson.h>
1798 #include <stdio.h>
1799
1800 static bool
1801 my_visit_before (const bson_iter_t *iter, const char *key, void *data)
1802 {
1803 int *count = (int *) data;
1804
1805 (*count)++;
1806
1807 /* returning true stops further iteration of the document */
1808
1809 return false;
1810 }
1811
1812 static void
1813 count_fields (bson_t *doc)
1814 {
1815 bson_visitor_t visitor = {0};
1816 bson_iter_t iter;
1817 int count = 0;
1818
1819 visitor.visit_before = my_visit_before;
1820
1821 if (bson_iter_init (&iter, doc)) {
1822 bson_iter_visit_all (&iter, &visitor, &count);
1823 }
1824
1825 printf ("Found %d fields.\n", count);
1826 }
1827
1828 The example below demonstrates how to set your own callbacks to provide
1829 information about the location of corrupt or unsupported BSON document
1830 entries.
1831
1832 Example Corruption Check
1833 #include <bson/bson.h>
1834 #include <stdio.h>
1835
1836 typedef struct {
1837 ssize_t *err_offset;
1838 } my_state_t;
1839
1840 static void
1841 my_visit_corrupt (const bson_iter_t *iter, void *data)
1842 {
1843 *(((my_state_t *) data)->err_offset) = iter->off;
1844 }
1845
1846 static void
1847 my_visit_unsupported_type (const bson_iter_t *iter,
1848 const char *key,
1849 uint32_t type_code,
1850 void *data)
1851 {
1852 *(((my_state_t *) data)->err_offset) = iter->off;
1853 }
1854
1855 static void
1856 find_error_location (bson_t *doc)
1857 {
1858 bson_visitor_t visitors = {0};
1859 bson_iter_t iter;
1860 my_state_t state;
1861 ssize_t err_offset = -1;
1862
1863 visitors.visit_corrupt = my_visit_corrupt;
1864 visitors.visit_unsupported_type = my_visit_unsupported_type;
1865 /* provide additional visitors as needed based on your requirements */
1866 state.err_offset = &err_offset;
1867
1868 if (!bson_iter_init (&iter, doc)) {
1869 printf ("Could not initialize iterator!");
1870 exit (1);
1871 }
1872
1873 if (bson_iter_visit_all (&iter, &visitors, &state) ||
1874 err_offset != -1) {
1875 printf ("Found error at offset %d.\n", err_offset);
1876 } else {
1877 printf ("BSON document had no errors.\n");
1878 }
1879 }
1880
1881 The example below demonstrates how to use a visitor to validate a BSON
1882 document's maximum depth.
1883
1884 Example Custom Validation
1885 bson-check-depth.c
1886
1887 /* Reports the maximum nested depth of a BSON document. */
1888 #include <bson/bson.h>
1889
1890 #include <assert.h>
1891 #include <stdio.h>
1892 #include <stdlib.h>
1893
1894 typedef struct {
1895 uint32_t depth;
1896 int max_depth;
1897 bool valid;
1898 } check_depth_t;
1899
1900 bool
1901 _check_depth_document (const bson_iter_t *iter,
1902 const char *key,
1903 const bson_t *v_document,
1904 void *data);
1905
1906 static const bson_visitor_t check_depth_funcs = {
1907 NULL,
1908 NULL,
1909 NULL,
1910 NULL,
1911 NULL,
1912 _check_depth_document,
1913 _check_depth_document,
1914 NULL,
1915 };
1916
1917 bool
1918 _check_depth_document (const bson_iter_t *iter,
1919 const char *key,
1920 const bson_t *v_document,
1921 void *data)
1922 {
1923 check_depth_t *state = (check_depth_t *) data;
1924 bson_iter_t child;
1925
1926 if (!bson_iter_init (&child, v_document)) {
1927 fprintf (stderr, "corrupt\n");
1928 return true; /* cancel */
1929 }
1930
1931 state->depth++;
1932 if (state->depth > state->max_depth) {
1933 state->valid = false;
1934 return true; /* cancel */
1935 }
1936
1937 bson_iter_visit_all (&child, &check_depth_funcs, state);
1938 state->depth--;
1939 return false; /* continue */
1940 }
1941
1942 void
1943 check_depth (const bson_t *bson, int max_depth)
1944 {
1945 bson_iter_t iter;
1946 check_depth_t state = {0};
1947
1948 if (!bson_iter_init (&iter, bson)) {
1949 fprintf (stderr, "corrupt\n");
1950 }
1951
1952 state.valid = true;
1953 state.max_depth = max_depth;
1954 _check_depth_document (&iter, NULL, bson, &state);
1955 if (!state.valid) {
1956 printf ("document exceeds maximum depth of %d\n", state.max_depth);
1957 } else {
1958 char *as_json = bson_as_canonical_extended_json (bson, NULL);
1959 printf ("document %s ", as_json);
1960 printf ("is valid\n");
1961 bson_free (as_json);
1962 }
1963 }
1964
1965 int
1966 main (int argc, char **argv)
1967 {
1968 bson_reader_t *bson_reader;
1969 const bson_t *bson;
1970 bool reached_eof;
1971 char *filename;
1972 bson_error_t error;
1973 int max_depth;
1974
1975 if (argc != 3) {
1976 fprintf (stderr, "usage: %s FILE MAX_DEPTH\n", argv[0]);
1977 fprintf (stderr, "Checks that the depth of the BSON contained in FILE\n");
1978 fprintf (stderr, "does not exceed MAX_DEPTH\n");
1979 }
1980
1981 filename = argv[1];
1982 max_depth = atoi (argv[2]);
1983 bson_reader = bson_reader_new_from_file (filename, &error);
1984 if (!bson_reader) {
1985 printf ("could not read %s: %s\n", filename, error.message);
1986 return 1;
1987 }
1988
1989 while ((bson = bson_reader_read (bson_reader, &reached_eof))) {
1990 check_depth (bson, max_depth);
1991 }
1992
1993 if (!reached_eof) {
1994 printf ("error reading BSON\n");
1995 }
1996
1997 bson_reader_destroy (bson_reader);
1998 return 0;
1999 }
2000
2001
2002 bson_writer_t
2003 Bulk BSON serialization Abstraction
2004
2005 Synopsis
2006 #include <bson/bson.h>
2007
2008 typedef struct _bson_writer_t bson_writer_t;
2009
2010 bson_writer_t *
2011 bson_writer_new (uint8_t **buf,
2012 size_t *buflen,
2013 size_t offset,
2014 bson_realloc_func realloc_func,
2015 void *realloc_func_ctx);
2016 void
2017 bson_writer_destroy (bson_writer_t *writer);
2018
2019 Description
2020 The bson_writer_t API provides an abstraction for serializing many BSON
2021 documents to a single memory region. The memory region may be dynami‐
2022 cally allocated and re-allocated as more memory is demanded. This can
2023 be useful when building network packets from a high-level language. For
2024 example, you can serialize a Python Dictionary directly to a single
2025 buffer destined for a TCP packet.
2026
2027 Example
2028 #include <bson/bson.h>
2029
2030 int
2031 main (int argc, char *argv[])
2032 {
2033 bson_writer_t *writer;
2034 uint8_t *buf = NULL;
2035 size_t buflen = 0;
2036 bson_t *doc;
2037
2038 writer = bson_writer_new (&buf, &buflen, 0, bson_realloc_ctx, NULL);
2039
2040 for (i = 0; i < 1000; i++) {
2041 bson_writer_begin (writer, &doc);
2042 BSON_APPEND_INT32 (&doc, "i", i);
2043 bson_writer_end (writer);
2044 }
2045
2046 bson_writer_destroy (writer);
2047
2048 bson_free (buf);
2049
2050 return 0;
2051 }
2052
2053 System Clock
2054 BSON Clock Abstraction
2055
2056 Synopsis
2057 int64_t
2058 bson_get_monotonic_time (void);
2059 int
2060 bson_gettimeofday (struct timeval *tv);
2061
2062 Description
2063 The clock abstraction in Libbson provides a cross-platform way to han‐
2064 dle timeouts within the BSON library. It abstracts the differences in
2065 implementations of gettimeofday() as well as providing a monotonic (in‐
2066 crementing only) clock in microseconds.
2067
2068 Memory Management
2069 BSON Memory Abstraction.
2070
2071 Description
2072 Libbson contains a lightweight memory abstraction to make portability
2073 to new platforms easier. Additionally, it helps us integrate with in‐
2074 teresting higher-level languages. One caveat, however, is that Libbson
2075 is not designed to deal with Out of Memory (OOM) situations. Doing so
2076 requires extreme diligence throughout the application stack that has
2077 rarely been implemented correctly. This may change in the future. As it
2078 stands now, Libbson will abort() under OOM situations.
2079
2080 To aid in language binding integration, Libbson allows for setting a
2081 custom memory allocator via bson_mem_set_vtable(). This allocation may
2082 be reversed via bson_mem_restore_vtable().
2083
2084 Libbson Versioning
2085 Versioning Macros and Functions
2086
2087 Macros
2088 The following preprocessor macros can be used to perform various checks
2089 based on the version of the library you are compiling against. This may
2090 be useful if you only want to enable a feature on a certain version of
2091 the library.
2092
2093 Synopsis
2094 #define BSON_CHECK_VERSION(major, minor, micro)
2095
2096 #define BSON_MAJOR_VERSION (1)
2097 #define BSON_MINOR_VERSION (4)
2098 #define BSON_MICRO_VERSION (1)
2099 #define BSON_VERSION_S "1.4.1"
2100
2101 #define BSON_VERSION_HEX \
2102 (BSON_MAJOR_VERSION << 24 | BSON_MINOR_VERSION << 16 | \
2103 BSON_MICRO_VERSION << 8)
2104
2105 Only compile a block on Libbson 1.1.0 and newer.
2106
2107 #if BSON_CHECK_VERSION(1, 1, 0)
2108 static void
2109 do_something (void)
2110 {
2111 }
2112 #endif
2113
2115 MongoDB, Inc
2116
2118 2017-present, MongoDB, Inc
2119
2120
2121
2122
21231.20.0 Nov 18, 2021 BSON_REFERENCE(3)