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

LIBBSON

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

AUTHOR

2326       MongoDB, Inc
2327
2329       2017-present, MongoDB, Inc
2330
2331
2332
2333
23341.25.1                           Nov 08, 2023                BSON_REFERENCE(3)
Impressum