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