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

NAME

6       bson_reference - Index
7

LIBBSON

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

AUTHOR

2115       MongoDB, Inc
2116
2118       2017-present, MongoDB, Inc
2119
2120
2121
2122
21231.17.6                           Jun 03, 2021                BSON_REFERENCE(3)
Impressum