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