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

AUTHOR

339       MongoDB, Inc
340
342       2017-present, MongoDB, Inc
343
344
345
346
3471.24.3                           Aug 17, 2023                BSON_VISITOR_T(3)
Impressum