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