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

AUTHOR

2012       MongoDB, Inc
2013
2015       2017-present, MongoDB, Inc
2016
2017
2018
2019
20201.13.1                           Jan 24, 2019                BSON_REFERENCE(3)
Impressum