1BSON_VISITOR_T(3)                   libbson                  BSON_VISITOR_T(3)
2
3
4

NAME

6       bson_visitor_t - bson_visitor_t
7

SYNOPSIS

9          #include <bson/bson.h>
10
11          typedef struct {
12             /* run before / after descending into a document */
13             bool (*visit_before) (const bson_iter_t *iter, const char *key, void *data);
14             bool (*visit_after) (const bson_iter_t *iter, const char *key, void *data);
15             /* corrupt BSON, or unsupported type and visit_unsupported_type not set */
16             void (*visit_corrupt) (const bson_iter_t *iter, void *data);
17             /* normal bson field callbacks */
18             bool (*visit_double) (const bson_iter_t *iter,
19                                   const char *key,
20                                   double v_double,
21                                   void *data);
22             bool (*visit_utf8) (const bson_iter_t *iter,
23                                 const char *key,
24                                 size_t v_utf8_len,
25                                 const char *v_utf8,
26                                 void *data);
27             bool (*visit_document) (const bson_iter_t *iter,
28                                     const char *key,
29                                     const bson_t *v_document,
30                                     void *data);
31             bool (*visit_array) (const bson_iter_t *iter,
32                                  const char *key,
33                                  const bson_t *v_array,
34                                  void *data);
35             bool (*visit_binary) (const bson_iter_t *iter,
36                                   const char *key,
37                                   bson_subtype_t v_subtype,
38                                   size_t v_binary_len,
39                                   const uint8_t *v_binary,
40                                   void *data);
41             /* normal field with deprecated "Undefined" BSON type */
42             bool (*visit_undefined) (const bson_iter_t *iter,
43                                      const char *key,
44                                      void *data);
45             bool (*visit_oid) (const bson_iter_t *iter,
46                                const char *key,
47                                const bson_oid_t *v_oid,
48                                void *data);
49             bool (*visit_bool) (const bson_iter_t *iter,
50                                 const char *key,
51                                 bool v_bool,
52                                 void *data);
53             bool (*visit_date_time) (const bson_iter_t *iter,
54                                      const char *key,
55                                      int64_t msec_since_epoch,
56                                      void *data);
57             bool (*visit_null) (const bson_iter_t *iter, const char *key, void *data);
58             bool (*visit_regex) (const bson_iter_t *iter,
59                                  const char *key,
60                                  const char *v_regex,
61                                  const char *v_options,
62                                  void *data);
63             bool (*visit_dbpointer) (const bson_iter_t *iter,
64                                      const char *key,
65                                      size_t v_collection_len,
66                                      const char *v_collection,
67                                      const bson_oid_t *v_oid,
68                                      void *data);
69             bool (*visit_code) (const bson_iter_t *iter,
70                                 const char *key,
71                                 size_t v_code_len,
72                                 const char *v_code,
73                                 void *data);
74             bool (*visit_symbol) (const bson_iter_t *iter,
75                                   const char *key,
76                                   size_t v_symbol_len,
77                                   const char *v_symbol,
78                                   void *data);
79             bool (*visit_codewscope) (const bson_iter_t *iter,
80                                       const char *key,
81                                       size_t v_code_len,
82                                       const char *v_code,
83                                       const bson_t *v_scope,
84                                       void *data);
85             bool (*visit_int32) (const bson_iter_t *iter,
86                                  const char *key,
87                                  int32_t v_int32,
88                                  void *data);
89             bool (*visit_timestamp) (const bson_iter_t *iter,
90                                      const char *key,
91                                      uint32_t v_timestamp,
92                                      uint32_t v_increment,
93                                      void *data);
94             bool (*visit_int64) (const bson_iter_t *iter,
95                                  const char *key,
96                                  int64_t v_int64,
97                                  void *data);
98             bool (*visit_maxkey) (const bson_iter_t *iter, const char *key, void *data);
99             bool (*visit_minkey) (const bson_iter_t *iter, const char *key, void *data);
100             /* if set, called instead of visit_corrupt when an apparently valid BSON
101              * includes an unrecognized field type (reading future version of BSON) */
102             void (*visit_unsupported_type) (const bson_iter_t *iter,
103                                             const char *key,
104                                             uint32_t type_code,
105                                             void *data);
106             bool (*visit_decimal128) (const bson_iter_t *iter,
107                                       const char *key,
108                                       const bson_decimal128_t *v_decimal128,
109                                       void *data);
110
111             void *padding[7];
112          } bson_visitor_t bson_visitor_t;
113

DESCRIPTION

115       The bson_visitor_t structure provides a series of callbacks that can be
116       called while iterating a BSON document. This may simplify  the  converā€
117       sion of a bson_t to a higher level language structure.
118
119       If  the  optional  callback visit_unsupported_type is set, it is called
120       instead of visit_corrupt in the specific case of an unrecognized  field
121       type.  (Parsing is aborted in either case.) Use this callback to report
122       an error like "unrecognized type" instead  of  simply  "corrupt  BSON".
123       This  future-proofs  code  that  may use an older version of libbson to
124       parse future BSON formats.
125

BASIC EXAMPLE

127          #include <bson/bson.h>
128          #include <stdio.h>
129
130          static bool
131          my_visit_before (const bson_iter_t *iter, const char *key, void *data)
132          {
133             int *count = (int *) data;
134
135             (*count)++;
136
137             /* returning true stops further iteration of the document */
138
139             return false;
140          }
141
142          static void
143          count_fields (bson_t *doc)
144          {
145             bson_visitor_t visitor = {0};
146             bson_iter_t iter;
147             int count = 0;
148
149             visitor.visit_before = my_visit_before;
150
151             if (bson_iter_init (&iter, doc)) {
152                bson_iter_visit_all (&iter, &visitor, &count);
153             }
154
155             printf ("Found %d fields.\n", count);
156          }
157
158       The example below demonstrates how to set your own callbacks to provide
159       information  about the location of corrupt or unsupported BSON document
160       entries.
161

EXAMPLE CORRUPTION CHECK

163          #include <bson/bson.h>
164          #include <stdio.h>
165
166          typedef struct {
167             ssize_t *err_offset;
168          } my_state_t;
169
170          static void
171          my_visit_corrupt (const bson_iter_t *iter, void *data)
172          {
173             *(((my_state_t *) data)->err_offset) = iter->off;
174          }
175
176          static void
177          my_visit_unsupported_type (const bson_iter_t *iter,
178                                     const char *key,
179                                     uint32_t type_code,
180                                     void *data)
181          {
182             *(((my_state_t *) data)->err_offset) = iter->off;
183          }
184
185          static void
186          find_error_location (bson_t *doc)
187          {
188             bson_visitor_t visitors = {0};
189             bson_iter_t iter;
190             my_state_t state;
191             ssize_t err_offset = -1;
192
193             visitors.visit_corrupt = my_visit_corrupt;
194             visitors.visit_unsupported_type = my_visit_unsupported_type;
195             /* provide additional visitors as needed based on your requirements */
196             state.err_offset = &err_offset;
197
198             if (!bson_iter_init (&iter, doc)) {
199                printf ("Could not initialize iterator!");
200                exit (1);
201             }
202
203             if (bson_iter_visit_all (&iter, &visitors, &state) ||
204                 err_offset != -1) {
205                printf ("Found error at offset %d.\n", err_offset);
206             } else {
207                printf ("BSON document had no errors.\n");
208             }
209          }
210
211       The example below demonstrates how to use a visitor to validate a  BSON
212       document's maximum depth.
213

EXAMPLE CUSTOM VALIDATION

215       bson-check-depth.c
216
217          /* Reports the maximum nested depth of a BSON document. */
218          #include <bson/bson.h>
219
220          #include <assert.h>
221          #include <stdio.h>
222          #include <stdlib.h>
223
224          typedef struct {
225             uint32_t depth;
226             int max_depth;
227             bool valid;
228          } check_depth_t;
229
230          bool
231          _check_depth_document (const bson_iter_t *iter,
232                                 const char *key,
233                                 const bson_t *v_document,
234                                 void *data);
235
236          static const bson_visitor_t check_depth_funcs = {
237             NULL,
238             NULL,
239             NULL,
240             NULL,
241             NULL,
242             _check_depth_document,
243             _check_depth_document,
244             NULL,
245          };
246
247          bool
248          _check_depth_document (const bson_iter_t *iter,
249                                 const char *key,
250                                 const bson_t *v_document,
251                                 void *data)
252          {
253             check_depth_t *state = (check_depth_t *) data;
254             bson_iter_t child;
255
256             BSON_UNUSED (iter);
257             BSON_UNUSED (key);
258
259             if (!bson_iter_init (&child, v_document)) {
260                fprintf (stderr, "corrupt\n");
261                return true; /* cancel */
262             }
263
264             state->depth++;
265             if (state->depth > state->max_depth) {
266                state->valid = false;
267                return true; /* cancel */
268             }
269
270             bson_iter_visit_all (&child, &check_depth_funcs, state);
271             state->depth--;
272             return false; /* continue */
273          }
274
275          void
276          check_depth (const bson_t *bson, int max_depth)
277          {
278             bson_iter_t iter;
279             check_depth_t state = {0};
280
281             if (!bson_iter_init (&iter, bson)) {
282                fprintf (stderr, "corrupt\n");
283             }
284
285             state.valid = true;
286             state.max_depth = max_depth;
287             _check_depth_document (&iter, NULL, bson, &state);
288             if (!state.valid) {
289                printf ("document exceeds maximum depth of %d\n", state.max_depth);
290             } else {
291                char *as_json = bson_as_canonical_extended_json (bson, NULL);
292                printf ("document %s ", as_json);
293                printf ("is valid\n");
294                bson_free (as_json);
295             }
296          }
297
298          int
299          main (int argc, char **argv)
300          {
301             bson_reader_t *bson_reader;
302             const bson_t *bson;
303             bool reached_eof;
304             char *filename;
305             bson_error_t error;
306             int max_depth;
307
308             if (argc != 3) {
309                fprintf (stderr, "usage: %s FILE MAX_DEPTH\n", argv[0]);
310                fprintf (stderr, "Checks that the depth of the BSON contained in FILE\n");
311                fprintf (stderr, "does not exceed MAX_DEPTH\n");
312             }
313
314             filename = argv[1];
315             max_depth = atoi (argv[2]);
316             bson_reader = bson_reader_new_from_file (filename, &error);
317             if (!bson_reader) {
318                printf ("could not read %s: %s\n", filename, error.message);
319                return 1;
320             }
321
322             while ((bson = bson_reader_read (bson_reader, &reached_eof))) {
323                check_depth (bson, max_depth);
324             }
325
326             if (!reached_eof) {
327                printf ("error reading BSON\n");
328             }
329
330             bson_reader_destroy (bson_reader);
331             return 0;
332          }
333
334

AUTHOR

336       MongoDB, Inc
337
339       2017-present, MongoDB, Inc
340
341
342
343
3441.23.1                           Oct 20, 2022                BSON_VISITOR_T(3)
Impressum