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: hello_bson.c.INDENT 0.0
21
22          #include <stdio.h>
23          #include <bson/bson.h>
24
25          int
26          main (int argc, const char **argv)
27          {
28             bson_t *b;
29             char *j;
30
31             b = BCON_NEW ("hello", BCON_UTF8 ("bson!"));
32             j = bson_as_canonical_extended_json (b, NULL);
33             printf ("%s\n", j);
34
35             bson_free (j);
36             bson_destroy (b);
37
38             return 0;
39          }
40
41
42   CMake
43       The libbson installation includes a CMake config-file package,  so  you
44       can  use  CMake's find_package command to import libbson's CMake target
45       and link to libbson (as a shared library): CMakeLists.txt.INDENT 0.0
46
47          # Specify the minimum version you require.
48          find_package (bson-1.0 1.7 REQUIRED)
49
50          # The "hello_bson.c" sample program is shared among four tests.
51          add_executable (hello_bson ../../hello_bson.c)
52          target_link_libraries (hello_bson PRIVATE mongo::bson_shared)
53
54
55You  can  also  use  libbson  as   a   static   library   instead:   Use   the

mongo::bson_static CMake target:

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

AUTHOR

2117       MongoDB, Inc
2118
2120       2017-present, MongoDB, Inc
2121
2122
2123
2124
21251.16.2                           Feb 25, 2020                BSON_REFERENCE(3)
Impressum