1BSON_REFERENCE(3)                   libbson                  BSON_REFERENCE(3)
2
3
4

NAME

6       bson_reference - Index
7

LIBBSON

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

AUTHOR

2116       MongoDB, Inc
2117
2119       2017-present, MongoDB, Inc
2120
2121
2122
2123
21241.17.4                           Feb 04, 2021                BSON_REFERENCE(3)
Impressum