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.INDENT 0.0
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             if (!bson_iter_init (&child, v_document)) {
257                fprintf (stderr, "corrupt\n");
258                return true; /* cancel */
259             }
260
261             state->depth++;
262             if (state->depth > state->max_depth) {
263                state->valid = false;
264                return true; /* cancel */
265             }
266
267             bson_iter_visit_all (&child, &check_depth_funcs, state);
268             state->depth--;
269             return false; /* continue */
270          }
271
272          void
273          check_depth (const bson_t *bson, int max_depth)
274          {
275             bson_iter_t iter;
276             check_depth_t state = {0};
277
278             if (!bson_iter_init (&iter, bson)) {
279                fprintf (stderr, "corrupt\n");
280             }
281
282             state.valid = true;
283             state.max_depth = max_depth;
284             _check_depth_document (&iter, NULL, bson, &state);
285             if (!state.valid) {
286                printf ("document exceeds maximum depth of %d\n", state.max_depth);
287             } else {
288                char *as_json = bson_as_canonical_extended_json (bson, NULL);
289                printf ("document %s ", as_json);
290                printf ("is valid\n");
291                bson_free (as_json);
292             }
293          }
294
295          int
296          main (int argc, char **argv)
297          {
298             bson_reader_t *bson_reader;
299             const bson_t *bson;
300             bool reached_eof;
301             char *filename;
302             bson_error_t error;
303             int max_depth;
304
305             if (argc != 3) {
306                fprintf (stderr, "usage: %s FILE MAX_DEPTH\n", argv[0]);
307                fprintf (stderr, "Checks that the depth of the BSON contained in FILE\n");
308                fprintf (stderr, "does not exceed MAX_DEPTH\n");
309             }
310
311             filename = argv[1];
312             max_depth = atoi (argv[2]);
313             bson_reader = bson_reader_new_from_file (filename, &error);
314             if (!bson_reader) {
315                printf ("could not read %s: %s\n", filename, error.message);
316                return 1;
317             }
318
319             while ((bson = bson_reader_read (bson_reader, &reached_eof))) {
320                check_depth (bson, max_depth);
321             }
322
323             if (!reached_eof) {
324                printf ("error reading BSON\n");
325             }
326
327             bson_reader_destroy (bson_reader);
328             return 0;
329          }
330

AUTHOR

332       MongoDB, Inc
333
335       2017-present, MongoDB, Inc
336
337
338
339
3401.16.2                           Feb 25, 2020                BSON_VISITOR_T(3)
Impressum