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

AUTHOR

2120       MongoDB, Inc
2121
2123       2017-present, MongoDB, Inc
2124
2125
2126
2127
21281.15.2                           Nov 06, 2019                BSON_REFERENCE(3)
Impressum