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