1 /*
2 * Copyright 2013 MongoDB, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #ifndef BSON_ITER_H
19 #define BSON_ITER_H
20
21
22 #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION)
23 # error "Only <bson.h> can be included directly."
24 #endif
25
26
27 #include "bson.h"
28 #include "bson-endian.h"
29 #include "bson-macros.h"
30 #include "bson-types.h"
31
32
33 BSON_BEGIN_DECLS
34
35
36 #define BSON_ITER_HOLDS_DOUBLE(iter) \
37 (bson_iter_type ((iter)) == BSON_TYPE_DOUBLE)
38
39 #define BSON_ITER_HOLDS_UTF8(iter) \
40 (bson_iter_type ((iter)) == BSON_TYPE_UTF8)
41
42 #define BSON_ITER_HOLDS_DOCUMENT(iter) \
43 (bson_iter_type ((iter)) == BSON_TYPE_DOCUMENT)
44
45 #define BSON_ITER_HOLDS_ARRAY(iter) \
46 (bson_iter_type ((iter)) == BSON_TYPE_ARRAY)
47
48 #define BSON_ITER_HOLDS_BINARY(iter) \
49 (bson_iter_type ((iter)) == BSON_TYPE_BINARY)
50
51 #define BSON_ITER_HOLDS_UNDEFINED(iter) \
52 (bson_iter_type ((iter)) == BSON_TYPE_UNDEFINED)
53
54 #define BSON_ITER_HOLDS_OID(iter) \
55 (bson_iter_type ((iter)) == BSON_TYPE_OID)
56
57 #define BSON_ITER_HOLDS_BOOL(iter) \
58 (bson_iter_type ((iter)) == BSON_TYPE_BOOL)
59
60 #define BSON_ITER_HOLDS_DATE_TIME(iter) \
61 (bson_iter_type ((iter)) == BSON_TYPE_DATE_TIME)
62
63 #define BSON_ITER_HOLDS_NULL(iter) \
64 (bson_iter_type ((iter)) == BSON_TYPE_NULL)
65
66 #define BSON_ITER_HOLDS_REGEX(iter) \
67 (bson_iter_type ((iter)) == BSON_TYPE_REGEX)
68
69 #define BSON_ITER_HOLDS_DBPOINTER(iter) \
70 (bson_iter_type ((iter)) == BSON_TYPE_DBPOINTER)
71
72 #define BSON_ITER_HOLDS_CODE(iter) \
73 (bson_iter_type ((iter)) == BSON_TYPE_CODE)
74
75 #define BSON_ITER_HOLDS_SYMBOL(iter) \
76 (bson_iter_type ((iter)) == BSON_TYPE_SYMBOL)
77
78 #define BSON_ITER_HOLDS_CODEWSCOPE(iter) \
79 (bson_iter_type ((iter)) == BSON_TYPE_CODEWSCOPE)
80
81 #define BSON_ITER_HOLDS_INT32(iter) \
82 (bson_iter_type ((iter)) == BSON_TYPE_INT32)
83
84 #define BSON_ITER_HOLDS_TIMESTAMP(iter) \
85 (bson_iter_type ((iter)) == BSON_TYPE_TIMESTAMP)
86
87 #define BSON_ITER_HOLDS_INT64(iter) \
88 (bson_iter_type ((iter)) == BSON_TYPE_INT64)
89
90 #define BSON_ITER_HOLDS_DECIMAL128(iter) \
91 (bson_iter_type (iter)) == BSON_TYPE_DECIMAL128
92
93 #define BSON_ITER_HOLDS_MAXKEY(iter) \
94 (bson_iter_type ((iter)) == BSON_TYPE_MAXKEY)
95
96 #define BSON_ITER_HOLDS_MINKEY(iter) \
97 (bson_iter_type ((iter)) == BSON_TYPE_MINKEY)
98
99 #define BSON_ITER_IS_KEY(iter, key) \
100 (0 == strcmp ((key), bson_iter_key ((iter))))
101
102
103 const bson_value_t *
104 bson_iter_value (bson_iter_t *iter);
105
106
107 /**
108 * bson_iter_utf8_len_unsafe:
109 * @iter: a bson_iter_t.
110 *
111 * Returns the length of a string currently pointed to by @iter. This performs
112 * no validation so the is responsible for knowing the BSON is valid. Calling
113 * bson_validate() is one way to do this ahead of time.
114 */
115 static BSON_INLINE uint32_t
bson_iter_utf8_len_unsafe(const bson_iter_t * iter)116 bson_iter_utf8_len_unsafe (const bson_iter_t *iter)
117 {
118 int32_t val;
119
120 memcpy (&val, iter->raw + iter->d1, sizeof (val));
121 val = BSON_UINT32_FROM_LE (val);
122 return BSON_MAX (0, val - 1);
123 }
124
125
126 void
127 bson_iter_array (const bson_iter_t *iter,
128 uint32_t *array_len,
129 const uint8_t **array);
130
131
132 void
133 bson_iter_binary (const bson_iter_t *iter,
134 bson_subtype_t *subtype,
135 uint32_t *binary_len,
136 const uint8_t **binary);
137
138
139 const char *
140 bson_iter_code (const bson_iter_t *iter,
141 uint32_t *length);
142
143
144 /**
145 * bson_iter_code_unsafe:
146 * @iter: A bson_iter_t.
147 * @length: A location for the length of the resulting string.
148 *
149 * Like bson_iter_code() but performs no integrity checks.
150 *
151 * Returns: A string that should not be modified or freed.
152 */
153 static BSON_INLINE const char *
bson_iter_code_unsafe(const bson_iter_t * iter,uint32_t * length)154 bson_iter_code_unsafe (const bson_iter_t *iter,
155 uint32_t *length)
156 {
157 *length = bson_iter_utf8_len_unsafe (iter);
158 return (const char *)(iter->raw + iter->d2);
159 }
160
161
162 const char *
163 bson_iter_codewscope (const bson_iter_t *iter,
164 uint32_t *length,
165 uint32_t *scope_len,
166 const uint8_t **scope);
167
168
169 void
170 bson_iter_dbpointer (const bson_iter_t *iter,
171 uint32_t *collection_len,
172 const char **collection,
173 const bson_oid_t **oid);
174
175
176 void
177 bson_iter_document (const bson_iter_t *iter,
178 uint32_t *document_len,
179 const uint8_t **document);
180
181
182 double
183 bson_iter_double (const bson_iter_t *iter);
184
185
186 /**
187 * bson_iter_double_unsafe:
188 * @iter: A bson_iter_t.
189 *
190 * Similar to bson_iter_double() but does not perform an integrity checking.
191 *
192 * Returns: A double.
193 */
194 static BSON_INLINE double
bson_iter_double_unsafe(const bson_iter_t * iter)195 bson_iter_double_unsafe (const bson_iter_t *iter)
196 {
197 double val;
198
199 memcpy (&val, iter->raw + iter->d1, sizeof (val));
200 return BSON_DOUBLE_FROM_LE (val);
201 }
202
203
204 bool
205 bson_iter_init (bson_iter_t *iter,
206 const bson_t *bson);
207
208
209 bool
210 bson_iter_init_find (bson_iter_t *iter,
211 const bson_t *bson,
212 const char *key);
213
214
215 bool
216 bson_iter_init_find_case (bson_iter_t *iter,
217 const bson_t *bson,
218 const char *key);
219
220
221 int32_t
222 bson_iter_int32 (const bson_iter_t *iter);
223
224
225 /**
226 * bson_iter_int32_unsafe:
227 * @iter: A bson_iter_t.
228 *
229 * Similar to bson_iter_int32() but with no integrity checking.
230 *
231 * Returns: A 32-bit signed integer.
232 */
233 static BSON_INLINE int32_t
bson_iter_int32_unsafe(const bson_iter_t * iter)234 bson_iter_int32_unsafe (const bson_iter_t *iter)
235 {
236 int32_t val;
237
238 memcpy (&val, iter->raw + iter->d1, sizeof (val));
239 return BSON_UINT32_FROM_LE (val);
240 }
241
242
243 int64_t
244 bson_iter_int64 (const bson_iter_t *iter);
245
246
247 int64_t
248 bson_iter_as_int64 (const bson_iter_t *iter);
249
250
251 /**
252 * bson_iter_int64_unsafe:
253 * @iter: a bson_iter_t.
254 *
255 * Similar to bson_iter_int64() but without integrity checking.
256 *
257 * Returns: A 64-bit signed integer.
258 */
259 static BSON_INLINE int64_t
bson_iter_int64_unsafe(const bson_iter_t * iter)260 bson_iter_int64_unsafe (const bson_iter_t *iter)
261 {
262 int64_t val;
263
264 memcpy (&val, iter->raw + iter->d1, sizeof (val));
265 return BSON_UINT64_FROM_LE (val);
266 }
267
268
269 bool
270 bson_iter_find (bson_iter_t *iter,
271 const char *key);
272
273
274 bool
275 bson_iter_find_case (bson_iter_t *iter,
276 const char *key);
277
278
279 bool
280 bson_iter_find_descendant (bson_iter_t *iter,
281 const char *dotkey,
282 bson_iter_t *descendant);
283
284
285 bool
286 bson_iter_next (bson_iter_t *iter);
287
288
289 const bson_oid_t *
290 bson_iter_oid (const bson_iter_t *iter);
291
292
293 /**
294 * bson_iter_oid_unsafe:
295 * @iter: A #bson_iter_t.
296 *
297 * Similar to bson_iter_oid() but performs no integrity checks.
298 *
299 * Returns: A #bson_oid_t that should not be modified or freed.
300 */
301 static BSON_INLINE const bson_oid_t *
bson_iter_oid_unsafe(const bson_iter_t * iter)302 bson_iter_oid_unsafe (const bson_iter_t *iter)
303 {
304 return (const bson_oid_t *)(iter->raw + iter->d1);
305 }
306
307
308 bool
309 bson_iter_decimal128 (const bson_iter_t *iter,
310 bson_decimal128_t *dec);
311
312
313 /**
314 * bson_iter_decimal128_unsafe:
315 * @iter: A #bson_iter_t.
316 *
317 * Similar to bson_iter_decimal128() but performs no integrity checks.
318 *
319 * Returns: A #bson_decimal128_t.
320 */
321 static BSON_INLINE void
bson_iter_decimal128_unsafe(const bson_iter_t * iter,bson_decimal128_t * dec)322 bson_iter_decimal128_unsafe (const bson_iter_t *iter,
323 bson_decimal128_t *dec)
324 {
325 uint64_t low_le;
326 uint64_t high_le;
327
328 memcpy (&low_le, iter->raw + iter->d1, sizeof (low_le));
329 memcpy (&high_le, iter->raw + iter->d1 + 8, sizeof (high_le));
330
331 dec->low = BSON_UINT64_FROM_LE (low_le);
332 dec->high = BSON_UINT64_FROM_LE (high_le);
333 }
334
335
336 const char *
337 bson_iter_key (const bson_iter_t *iter);
338
339
340 /**
341 * bson_iter_key_unsafe:
342 * @iter: A bson_iter_t.
343 *
344 * Similar to bson_iter_key() but performs no integrity checking.
345 *
346 * Returns: A string that should not be modified or freed.
347 */
348 static BSON_INLINE const char *
bson_iter_key_unsafe(const bson_iter_t * iter)349 bson_iter_key_unsafe (const bson_iter_t *iter)
350 {
351 return (const char *)(iter->raw + iter->key);
352 }
353
354
355 const char *
356 bson_iter_utf8 (const bson_iter_t *iter,
357 uint32_t *length);
358
359
360 /**
361 * bson_iter_utf8_unsafe:
362 *
363 * Similar to bson_iter_utf8() but performs no integrity checking.
364 *
365 * Returns: A string that should not be modified or freed.
366 */
367 static BSON_INLINE const char *
bson_iter_utf8_unsafe(const bson_iter_t * iter,size_t * length)368 bson_iter_utf8_unsafe (const bson_iter_t *iter,
369 size_t *length)
370 {
371 *length = bson_iter_utf8_len_unsafe (iter);
372 return (const char *)(iter->raw + iter->d2);
373 }
374
375
376 char *
377 bson_iter_dup_utf8 (const bson_iter_t *iter,
378 uint32_t *length);
379
380
381 int64_t
382 bson_iter_date_time (const bson_iter_t *iter);
383
384
385 time_t
386 bson_iter_time_t (const bson_iter_t *iter);
387
388
389 /**
390 * bson_iter_time_t_unsafe:
391 * @iter: A bson_iter_t.
392 *
393 * Similar to bson_iter_time_t() but performs no integrity checking.
394 *
395 * Returns: A time_t containing the number of seconds since UNIX epoch
396 * in UTC.
397 */
398 static BSON_INLINE time_t
bson_iter_time_t_unsafe(const bson_iter_t * iter)399 bson_iter_time_t_unsafe (const bson_iter_t *iter)
400 {
401 return (time_t)(bson_iter_int64_unsafe (iter) / 1000UL);
402 }
403
404
405 void
406 bson_iter_timeval (const bson_iter_t *iter,
407 struct timeval *tv);
408
409
410 /**
411 * bson_iter_timeval_unsafe:
412 * @iter: A bson_iter_t.
413 * @tv: A struct timeval.
414 *
415 * Similar to bson_iter_timeval() but performs no integrity checking.
416 */
417 static BSON_INLINE void
bson_iter_timeval_unsafe(const bson_iter_t * iter,struct timeval * tv)418 bson_iter_timeval_unsafe (const bson_iter_t *iter,
419 struct timeval *tv)
420 {
421 int64_t value = bson_iter_int64_unsafe (iter);
422 #ifdef BSON_OS_WIN32
423 tv->tv_sec = (long) (value / 1000);
424 #else
425 tv->tv_sec = (suseconds_t) (value / 1000);
426 #endif
427 tv->tv_usec = (value % 1000) * 1000;
428 }
429
430
431 void
432 bson_iter_timestamp (const bson_iter_t *iter,
433 uint32_t *timestamp,
434 uint32_t *increment);
435
436
437 bool
438 bson_iter_bool (const bson_iter_t *iter);
439
440
441 /**
442 * bson_iter_bool_unsafe:
443 * @iter: A bson_iter_t.
444 *
445 * Similar to bson_iter_bool() but performs no integrity checking.
446 *
447 * Returns: true or false.
448 */
449 static BSON_INLINE bool
bson_iter_bool_unsafe(const bson_iter_t * iter)450 bson_iter_bool_unsafe (const bson_iter_t *iter)
451 {
452 char val;
453
454 memcpy (&val, iter->raw + iter->d1, 1);
455 return !!val;
456 }
457
458
459 bool
460 bson_iter_as_bool (const bson_iter_t *iter);
461
462
463 const char *
464 bson_iter_regex (const bson_iter_t *iter,
465 const char **options);
466
467
468 const char *
469 bson_iter_symbol (const bson_iter_t *iter,
470 uint32_t *length);
471
472
473 bson_type_t
474 bson_iter_type (const bson_iter_t *iter);
475
476
477 /**
478 * bson_iter_type_unsafe:
479 * @iter: A bson_iter_t.
480 *
481 * Similar to bson_iter_type() but performs no integrity checking.
482 *
483 * Returns: A bson_type_t.
484 */
485 static BSON_INLINE bson_type_t
bson_iter_type_unsafe(const bson_iter_t * iter)486 bson_iter_type_unsafe (const bson_iter_t *iter)
487 {
488 return (bson_type_t) (iter->raw + iter->type) [0];
489 }
490
491
492 bool
493 bson_iter_recurse (const bson_iter_t *iter,
494 bson_iter_t *child);
495
496
497 void
498 bson_iter_overwrite_int32 (bson_iter_t *iter,
499 int32_t value);
500
501
502 void
503 bson_iter_overwrite_int64 (bson_iter_t *iter,
504 int64_t value);
505
506
507 void
508 bson_iter_overwrite_double (bson_iter_t *iter,
509 double value);
510
511
512 void
513 bson_iter_overwrite_decimal128 (bson_iter_t *iter,
514 bson_decimal128_t *value);
515
516
517 void
518 bson_iter_overwrite_bool (bson_iter_t *iter,
519 bool value);
520
521
522 bool
523 bson_iter_visit_all (bson_iter_t *iter,
524 const bson_visitor_t *visitor,
525 void *data);
526
527
528 BSON_END_DECLS
529
530
531 #endif /* BSON_ITER_H */
532