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