File Coverage

bson/bson-iter.c
Criterion Covered Total %
statement 416 657 63.3
branch 175 444 39.4
condition n/a
subroutine n/a
pod n/a
total 591 1101 53.6


line stmt bran cond sub pod time code
1             /*
2             * Copyright 2013-2014 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             #include "bson-iter.h"
19             #include "bson-config.h"
20             #include "bson-decimal128.h"
21              
22              
23             #define ITER_TYPE(i) ((bson_type_t) *((i)->raw + (i)->type))
24              
25              
26             /*
27             *--------------------------------------------------------------------------
28             *
29             * bson_iter_init --
30             *
31             * Initializes @iter to be used to iterate @bson.
32             *
33             * Returns:
34             * true if bson_iter_t was initialized. otherwise false.
35             *
36             * Side effects:
37             * @iter is initialized.
38             *
39             *--------------------------------------------------------------------------
40             */
41              
42             bool
43 5067           bson_iter_init (bson_iter_t *iter, /* OUT */
44             const bson_t *bson) /* IN */
45             {
46 5067 50         BSON_ASSERT (iter);
47 5067 50         BSON_ASSERT (bson);
48              
49 5067 50         if (BSON_UNLIKELY (bson->len < 5)) {
50 0           memset (iter, 0, sizeof *iter);
51 0           return false;
52             }
53              
54 5067           iter->raw = bson_get_data (bson);
55 5067           iter->len = bson->len;
56 5067           iter->off = 0;
57 5067           iter->type = 0;
58 5067           iter->key = 0;
59 5067           iter->d1 = 0;
60 5067           iter->d2 = 0;
61 5067           iter->d3 = 0;
62 5067           iter->d4 = 0;
63 5067           iter->next_off = 4;
64 5067           iter->err_off = 0;
65              
66 5067           return true;
67             }
68              
69              
70             /*
71             *--------------------------------------------------------------------------
72             *
73             * bson_iter_recurse --
74             *
75             * Creates a new sub-iter looking at the document or array that @iter
76             * is currently pointing at.
77             *
78             * Returns:
79             * true if successful and @child was initialized.
80             *
81             * Side effects:
82             * @child is initialized.
83             *
84             *--------------------------------------------------------------------------
85             */
86              
87             bool
88 261           bson_iter_recurse (const bson_iter_t *iter, /* IN */
89             bson_iter_t *child) /* OUT */
90             {
91 261           const uint8_t *data = NULL;
92 261           uint32_t len = 0;
93              
94 261 50         BSON_ASSERT (iter);
95 261 50         BSON_ASSERT (child);
96              
97 261 100         if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
98 247           bson_iter_document (iter, &len, &data);
99 14 50         } else if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
100 14           bson_iter_array (iter, &len, &data);
101             } else {
102 0           return false;
103             }
104              
105 261           child->raw = data;
106 261           child->len = len;
107 261           child->off = 0;
108 261           child->type = 0;
109 261           child->key = 0;
110 261           child->d1 = 0;
111 261           child->d2 = 0;
112 261           child->d3 = 0;
113 261           child->d4 = 0;
114 261           child->next_off = 4;
115 261           child->err_off = 0;
116              
117 261           return true;
118             }
119              
120              
121             /*
122             *--------------------------------------------------------------------------
123             *
124             * bson_iter_init_find --
125             *
126             * Initializes a #bson_iter_t and moves the iter to the first field
127             * matching @key.
128             *
129             * Returns:
130             * true if the field named @key was found; otherwise false.
131             *
132             * Side effects:
133             * None.
134             *
135             *--------------------------------------------------------------------------
136             */
137              
138             bool
139 0           bson_iter_init_find (bson_iter_t *iter, /* INOUT */
140             const bson_t *bson, /* IN */
141             const char *key) /* IN */
142             {
143 0 0         BSON_ASSERT (iter);
144 0 0         BSON_ASSERT (bson);
145 0 0         BSON_ASSERT (key);
146              
147 0 0         return bson_iter_init (iter, bson) && bson_iter_find (iter, key);
    0          
148             }
149              
150              
151             /*
152             *--------------------------------------------------------------------------
153             *
154             * bson_iter_init_find_case --
155             *
156             * A case-insensitive version of bson_iter_init_find().
157             *
158             * Returns:
159             * true if the field was found and @iter is observing that field.
160             *
161             * Side effects:
162             * None.
163             *
164             *--------------------------------------------------------------------------
165             */
166              
167             bool
168 0           bson_iter_init_find_case (bson_iter_t *iter, /* INOUT */
169             const bson_t *bson, /* IN */
170             const char *key) /* IN */
171             {
172 0 0         BSON_ASSERT (iter);
173 0 0         BSON_ASSERT (bson);
174 0 0         BSON_ASSERT (key);
175              
176 0 0         return bson_iter_init (iter, bson) && bson_iter_find_case (iter, key);
    0          
177             }
178              
179              
180             /*
181             *--------------------------------------------------------------------------
182             *
183             * _bson_iter_find_with_len --
184             *
185             * Internal helper for finding an exact key.
186             *
187             * Returns:
188             * true if the field @key was found.
189             *
190             * Side effects:
191             * None.
192             *
193             *--------------------------------------------------------------------------
194             */
195              
196             static bool
197 0           _bson_iter_find_with_len (bson_iter_t *iter, /* INOUT */
198             const char *key, /* IN */
199             int keylen) /* IN */
200             {
201             const char *ikey;
202              
203 0 0         if (keylen == 0) {
204 0           return false;
205             }
206              
207 0 0         if (keylen < 0) {
208 0           keylen = (int)strlen (key);
209             }
210              
211 0 0         while (bson_iter_next (iter)) {
212 0           ikey = bson_iter_key (iter);
213              
214 0 0         if ((0 == strncmp (key, ikey, keylen)) && (ikey [keylen] == '\0')) {
    0          
215 0           return true;
216             }
217             }
218              
219 0           return false;
220             }
221              
222              
223             /*
224             *--------------------------------------------------------------------------
225             *
226             * bson_iter_find --
227             *
228             * Searches through @iter starting from the current position for a key
229             * matching @key. This is a case-sensitive search meaning "KEY" and
230             * "key" would NOT match.
231             *
232             * Returns:
233             * true if @key is found.
234             *
235             * Side effects:
236             * None.
237             *
238             *--------------------------------------------------------------------------
239             */
240              
241             bool
242 0           bson_iter_find (bson_iter_t *iter, /* INOUT */
243             const char *key) /* IN */
244             {
245 0 0         BSON_ASSERT (iter);
246 0 0         BSON_ASSERT (key);
247              
248 0           return _bson_iter_find_with_len (iter, key, -1);
249             }
250              
251              
252             /*
253             *--------------------------------------------------------------------------
254             *
255             * bson_iter_find_case --
256             *
257             * Searches through @iter starting from the current position for a key
258             * matching @key. This is a case-insensitive search meaning "KEY" and
259             * "key" would match.
260             *
261             * Returns:
262             * true if @key is found.
263             *
264             * Side effects:
265             * None.
266             *
267             *--------------------------------------------------------------------------
268             */
269              
270             bool
271 0           bson_iter_find_case (bson_iter_t *iter, /* INOUT */
272             const char *key) /* IN */
273             {
274 0 0         BSON_ASSERT (iter);
275 0 0         BSON_ASSERT (key);
276              
277 0 0         while (bson_iter_next (iter)) {
278             #ifdef BSON_OS_WIN32
279             if (!_stricmp(key, bson_iter_key (iter))) {
280             #else
281 0 0         if (!strcasecmp (key, bson_iter_key (iter))) {
282             #endif
283 0           return true;
284             }
285             }
286              
287 0           return false;
288             }
289              
290              
291             /*
292             *--------------------------------------------------------------------------
293             *
294             * bson_iter_find_descendant --
295             *
296             * Locates a descendant using the "parent.child.key" notation. This
297             * operates similar to bson_iter_find() except that it can recurse
298             * into children documents using the dot notation.
299             *
300             * Returns:
301             * true if the descendant was found and @descendant was initialized.
302             *
303             * Side effects:
304             * @descendant may be initialized.
305             *
306             *--------------------------------------------------------------------------
307             */
308              
309             bool
310 0           bson_iter_find_descendant (bson_iter_t *iter, /* INOUT */
311             const char *dotkey, /* IN */
312             bson_iter_t *descendant) /* OUT */
313             {
314             bson_iter_t tmp;
315             const char *dot;
316             size_t sublen;
317              
318 0 0         BSON_ASSERT (iter);
319 0 0         BSON_ASSERT (dotkey);
320 0 0         BSON_ASSERT (descendant);
321              
322 0 0         if ((dot = strchr (dotkey, '.'))) {
323 0           sublen = dot - dotkey;
324             } else {
325 0           sublen = strlen (dotkey);
326             }
327              
328 0 0         if (_bson_iter_find_with_len (iter, dotkey, (int)sublen)) {
329 0 0         if (!dot) {
330 0           *descendant = *iter;
331 0           return true;
332             }
333              
334 0 0         if (BSON_ITER_HOLDS_DOCUMENT (iter) || BSON_ITER_HOLDS_ARRAY (iter)) {
    0          
335 0 0         if (bson_iter_recurse (iter, &tmp)) {
336 0           return bson_iter_find_descendant (&tmp, dot + 1, descendant);
337             }
338             }
339             }
340              
341 0           return false;
342             }
343              
344              
345             /*
346             *--------------------------------------------------------------------------
347             *
348             * bson_iter_key --
349             *
350             * Retrieves the key of the current field. The resulting key is valid
351             * while @iter is valid.
352             *
353             * Returns:
354             * A string that should not be modified or freed.
355             *
356             * Side effects:
357             * None.
358             *
359             *--------------------------------------------------------------------------
360             */
361              
362             const char *
363 1905           bson_iter_key (const bson_iter_t *iter) /* IN */
364             {
365 1905 50         BSON_ASSERT (iter);
366              
367 1905           return bson_iter_key_unsafe (iter);
368             }
369              
370              
371             /*
372             *--------------------------------------------------------------------------
373             *
374             * bson_iter_type --
375             *
376             * Retrieves the type of the current field. It may be useful to check
377             * the type using the BSON_ITER_HOLDS_*() macros.
378             *
379             * Returns:
380             * A bson_type_t.
381             *
382             * Side effects:
383             * None.
384             *
385             *--------------------------------------------------------------------------
386             */
387              
388             bson_type_t
389 2020           bson_iter_type (const bson_iter_t *iter) /* IN */
390             {
391 2020 50         BSON_ASSERT (iter);
392 2020 50         BSON_ASSERT (iter->raw);
393 2020 50         BSON_ASSERT (iter->len);
394              
395 2020           return bson_iter_type_unsafe (iter);
396             }
397              
398              
399             /*
400             *--------------------------------------------------------------------------
401             *
402             * _bson_iter_next_internal --
403             *
404             * Internal function to advance @iter to the next field and retrieve
405             * the key and BSON type before error-checking.
406             *
407             * Return:
408             * true if an element was decoded, else false.
409             *
410             * Side effects:
411             * @key and @bson_type are set.
412             *
413             * If the return value is false:
414             * - @iter is invalidated: @iter->raw is NULLed
415             * - @unsupported is set to true if the bson type is unsupported
416             * - otherwise if the BSON is corrupt, @iter->err_off is nonzero
417             * - otherwise @bson_type is set to BSON_TYPE_EOD
418             *
419             *--------------------------------------------------------------------------
420             */
421              
422             static bool
423 7360           _bson_iter_next_internal (bson_iter_t *iter, /* INOUT */
424             const char **key, /* OUT */
425             uint32_t *bson_type, /* OUT */
426             bool *unsupported) /* OUT */
427             {
428             const uint8_t *data;
429             uint32_t o;
430             unsigned int len;
431              
432 7360 50         BSON_ASSERT (iter);
433              
434 7360           *unsupported = false;
435              
436 7360 50         if (!iter->raw) {
437 0           *key = NULL;
438 0           *bson_type = BSON_TYPE_EOD;
439 0           return false;
440             }
441              
442 7360           data = iter->raw;
443 7360           len = iter->len;
444              
445 7360           iter->off = iter->next_off;
446 7360           iter->type = iter->off;
447 7360           iter->key = iter->off + 1;
448 7360           iter->d1 = 0;
449 7360           iter->d2 = 0;
450 7360           iter->d3 = 0;
451 7360           iter->d4 = 0;
452              
453 12557 100         for (o = iter->off + 1; o < len; o++) {
454 9029 100         if (!data [o]) {
455 3832           iter->d1 = ++o;
456 3832           goto fill_data_fields;
457             }
458             }
459              
460 3528           goto mark_invalid;
461              
462             fill_data_fields:
463              
464 3832           *key = bson_iter_key_unsafe (iter);
465 3832           *bson_type = ITER_TYPE (iter);
466              
467 3832           switch (*bson_type) {
468             case BSON_TYPE_DATE_TIME:
469             case BSON_TYPE_DOUBLE:
470             case BSON_TYPE_INT64:
471             case BSON_TYPE_TIMESTAMP:
472 223           iter->next_off = o + 8;
473 223           break;
474             case BSON_TYPE_CODE:
475             case BSON_TYPE_SYMBOL:
476             case BSON_TYPE_UTF8:
477             {
478             uint32_t l;
479              
480 263 50         if ((o + 4) >= len) {
481 0           iter->err_off = o;
482 18           goto mark_invalid;
483             }
484              
485 263           iter->d2 = o + 4;
486 263           memcpy (&l, iter->raw + iter->d1, sizeof (l));
487 263           l = BSON_UINT32_FROM_LE (l);
488              
489 263 100         if (l > (len - (o + 4))) {
490 6           iter->err_off = o;
491 6           goto mark_invalid;
492             }
493              
494 257           iter->next_off = o + 4 + l;
495              
496             /*
497             * Make sure the string length includes the NUL byte.
498             */
499 257 100         if (BSON_UNLIKELY ((l == 0) || (iter->next_off >= len))) {
    100          
500 9           iter->err_off = o;
501 9           goto mark_invalid;
502             }
503              
504             /*
505             * Make sure the last byte is a NUL byte.
506             */
507 248 100         if (BSON_UNLIKELY ((iter->raw + iter->d2)[l - 1] != '\0')) {
508 3           iter->err_off = o + 4 + l - 1;
509 3           goto mark_invalid;
510             }
511             }
512 245           break;
513             case BSON_TYPE_BINARY:
514             {
515             bson_subtype_t subtype;
516             uint32_t l;
517              
518 58 50         if (o >= (len - 4)) {
519 0           iter->err_off = o;
520 2           goto mark_invalid;
521             }
522              
523 58           iter->d2 = o + 4;
524 58           iter->d3 = o + 5;
525              
526 58           memcpy (&l, iter->raw + iter->d1, sizeof (l));
527 58           l = BSON_UINT32_FROM_LE (l);
528              
529 58 100         if (l >= (len - o)) {
530 2           iter->err_off = o;
531 2           goto mark_invalid;
532             }
533              
534 56           subtype = *(iter->raw + iter->d2);
535              
536 56 100         if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
537 10 50         if (l < 4) {
538 0           iter->err_off = o;
539 0           goto mark_invalid;
540             }
541             }
542              
543 56           iter->next_off = o + 5 + l;
544             }
545 56           break;
546             case BSON_TYPE_ARRAY:
547             case BSON_TYPE_DOCUMENT:
548             {
549             uint32_t l;
550              
551 522 50         if (o >= (len - 4)) {
552 0           iter->err_off = o;
553 0           goto mark_invalid;
554             }
555              
556 522           memcpy (&l, iter->raw + iter->d1, sizeof (l));
557 522           l = BSON_UINT32_FROM_LE (l);
558              
559 522 50         if ((l > len) || (l > (len - o))) {
    50          
560 0           iter->err_off = o;
561 0           goto mark_invalid;
562             }
563              
564 522           iter->next_off = o + l;
565             }
566 522           break;
567             case BSON_TYPE_OID:
568 38           iter->next_off = o + 12;
569 38           break;
570             case BSON_TYPE_BOOL:
571             {
572             char val;
573 34           memcpy (&val, iter->raw + iter->d1, 1);
574 34 100         if ( val != 0x00 && val != 0x01 ) {
    100          
575 2           iter->err_off = o;
576 2           goto mark_invalid;
577             }
578              
579 32           iter->next_off = o + 1;
580             }
581 32           break;
582             case BSON_TYPE_REGEX:
583             {
584 46           bool eor = false;
585 46           bool eoo = false;
586              
587 238 50         for (; o < len; o++) {
588 238 100         if (!data [o]) {
589 46           iter->d2 = ++o;
590 46           eor = true;
591 46           break;
592             }
593             }
594              
595 46 50         if (!eor) {
596 0           iter->err_off = iter->next_off;
597 0           goto mark_invalid;
598             }
599              
600 110 50         for (; o < len; o++) {
601 110 100         if (!data [o]) {
602 46           eoo = true;
603 46           break;
604             }
605             }
606              
607 46 50         if (!eoo) {
608 0           iter->err_off = iter->next_off;
609 0           goto mark_invalid;
610             }
611              
612 46           iter->next_off = o + 1;
613             }
614 46           break;
615             case BSON_TYPE_DBPOINTER:
616             {
617             uint32_t l;
618              
619 19 50         if (o >= (len - 4)) {
620 0           iter->err_off = o;
621 2           goto mark_invalid;
622             }
623              
624 19           iter->d2 = o + 4;
625 19           memcpy (&l, iter->raw + iter->d1, sizeof (l));
626 19           l = BSON_UINT32_FROM_LE (l);
627              
628 19 100         if ((l > len) || (l > (len - o))) {
    50          
629 1           iter->err_off = o;
630 1           goto mark_invalid;
631             }
632              
633 18 100         if ( *(iter->raw + o + l + 3) ) {
634             /* not null terminated */
635 1           iter->err_off = o + l + 3;
636 1           goto mark_invalid;
637             }
638              
639 17           iter->d3 = o + 4 + l;
640 17           iter->next_off = o + 4 + l + 12;
641             }
642 17           break;
643             case BSON_TYPE_CODEWSCOPE:
644             {
645             uint32_t l;
646             uint32_t doclen;
647              
648 37 50         if ((len < 19) || (o >= (len - 14))) {
    50          
649 0           iter->err_off = o;
650 10           goto mark_invalid;
651             }
652              
653 37           iter->d2 = o + 4;
654 37           iter->d3 = o + 8;
655              
656 37           memcpy (&l, iter->raw + iter->d1, sizeof (l));
657 37           l = BSON_UINT32_FROM_LE (l);
658              
659 37 100         if ((l < 14) || (l >= (len - o))) {
    100          
660 5           iter->err_off = o;
661 5           goto mark_invalid;
662             }
663              
664 32           iter->next_off = o + l;
665              
666 32 50         if (iter->next_off >= len) {
667 0           iter->err_off = o;
668 0           goto mark_invalid;
669             }
670              
671 32           memcpy (&l, iter->raw + iter->d2, sizeof (l));
672 32           l = BSON_UINT32_FROM_LE (l);
673              
674 32 100         if (l >= (len - o - 4 - 4)) {
675 2           iter->err_off = o;
676 2           goto mark_invalid;
677             }
678              
679 30 50         if ((o + 4 + 4 + l + 4) >= iter->next_off) {
680 0           iter->err_off = o + 4;
681 0           goto mark_invalid;
682             }
683              
684 30           iter->d4 = o + 4 + 4 + l;
685 30           memcpy (&doclen, iter->raw + iter->d4, sizeof (doclen));
686 30           doclen = BSON_UINT32_FROM_LE (doclen);
687              
688 30 100         if ((o + 4 + 4 + l + doclen) != iter->next_off) {
689 3           iter->err_off = o + 4 + 4 + l;
690 3           goto mark_invalid;
691             }
692             }
693 27           break;
694             case BSON_TYPE_INT32:
695 130           iter->next_off = o + 4;
696 130           break;
697             case BSON_TYPE_DECIMAL128:
698 2412           iter->next_off = o + 16;
699 2412           break;
700             case BSON_TYPE_MAXKEY:
701             case BSON_TYPE_MINKEY:
702             case BSON_TYPE_NULL:
703             case BSON_TYPE_UNDEFINED:
704 39           iter->d1 = -1;
705 39           iter->next_off = o;
706 39           break;
707             default:
708 5           *unsupported = true;
709             /* FALL THROUGH */
710             case BSON_TYPE_EOD:
711 11           iter->err_off = o;
712 11           goto mark_invalid;
713             }
714              
715             /*
716             * Check to see if any of the field locations would overflow the
717             * current BSON buffer. If so, set the error location to the offset
718             * of where the field starts.
719             */
720 3787 100         if (iter->next_off >= len) {
721 9           iter->err_off = o;
722 9           goto mark_invalid;
723             }
724              
725 3778           iter->err_off = 0;
726              
727 3778           return true;
728              
729             mark_invalid:
730 3582           iter->raw = NULL;
731 3582           iter->len = 0;
732 3582           iter->next_off = 0;
733              
734 3582           return false;
735             }
736              
737              
738             /*
739             *--------------------------------------------------------------------------
740             *
741             * bson_iter_next --
742             *
743             * Advances @iter to the next field of the underlying BSON document.
744             * If all fields have been exhausted, then %false is returned.
745             *
746             * It is a programming error to use @iter after this function has
747             * returned false.
748             *
749             * Returns:
750             * true if the iter was advanced to the next record.
751             * otherwise false and @iter should be considered invalid.
752             *
753             * Side effects:
754             * @iter may be invalidated.
755             *
756             *--------------------------------------------------------------------------
757             */
758              
759             bool
760 3624           bson_iter_next (bson_iter_t *iter) /* INOUT */
761             {
762             uint32_t bson_type;
763             const char *key;
764             bool unsupported;
765              
766 3624           return _bson_iter_next_internal (iter, &key, &bson_type, &unsupported);
767             }
768              
769              
770             /*
771             *--------------------------------------------------------------------------
772             *
773             * bson_iter_binary --
774             *
775             * Retrieves the BSON_TYPE_BINARY field. The subtype is stored in
776             * @subtype. The length of @binary in bytes is stored in @binary_len.
777             *
778             * @binary should not be modified or freed and is only valid while
779             * @iter's bson_t is valid and unmodified.
780             *
781             * Parameters:
782             * @iter: A bson_iter_t
783             * @subtype: A location for the binary subtype.
784             * @binary_len: A location for the length of @binary.
785             * @binary: A location for a pointer to the binary data.
786             *
787             * Returns:
788             * None.
789             *
790             * Side effects:
791             * None.
792             *
793             *--------------------------------------------------------------------------
794             */
795              
796             void
797 56           bson_iter_binary (const bson_iter_t *iter, /* IN */
798             bson_subtype_t *subtype, /* OUT */
799             uint32_t *binary_len, /* OUT */
800             const uint8_t **binary) /* OUT */
801             {
802             bson_subtype_t backup;
803              
804 56 50         BSON_ASSERT (iter);
805 56 50         BSON_ASSERT (!binary || binary_len);
    50          
806              
807 56 50         if (ITER_TYPE (iter) == BSON_TYPE_BINARY) {
808 56 50         if (!subtype) {
809 0           subtype = &backup;
810             }
811              
812 56           *subtype = (bson_subtype_t) *(iter->raw + iter->d2);
813              
814 56 50         if (binary) {
815 56           memcpy (binary_len, (iter->raw + iter->d1), sizeof (*binary_len));
816 56           *binary_len = BSON_UINT32_FROM_LE (*binary_len);
817 56           *binary = iter->raw + iter->d3;
818              
819 56 100         if (*subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
820 10           *binary_len -= sizeof (int32_t);
821 10           *binary += sizeof (int32_t);
822             }
823             }
824              
825 56           return;
826             }
827              
828 0 0         if (binary) {
829 0           *binary = NULL;
830             }
831              
832 0 0         if (binary_len) {
833 0           *binary_len = 0;
834             }
835              
836 0 0         if (subtype) {
837 0           *subtype = BSON_SUBTYPE_BINARY;
838             }
839             }
840              
841              
842             /*
843             *--------------------------------------------------------------------------
844             *
845             * bson_iter_bool --
846             *
847             * Retrieves the current field of type BSON_TYPE_BOOL.
848             *
849             * Returns:
850             * true or false, dependent on bson document.
851             *
852             * Side effects:
853             * None.
854             *
855             *--------------------------------------------------------------------------
856             */
857              
858             bool
859 18           bson_iter_bool (const bson_iter_t *iter) /* IN */
860             {
861 18 50         BSON_ASSERT (iter);
862              
863 18 50         if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
864 18           return bson_iter_bool_unsafe (iter);
865             }
866              
867 0           return false;
868             }
869              
870              
871             /*
872             *--------------------------------------------------------------------------
873             *
874             * bson_iter_as_bool --
875             *
876             * If @iter is on a boolean field, returns the boolean. If it is on a
877             * non-boolean field such as int32, int64, or double, it will convert
878             * the value to a boolean.
879             *
880             * Zero is false, and non-zero is true.
881             *
882             * Returns:
883             * true or false, dependent on field type.
884             *
885             * Side effects:
886             * None.
887             *
888             *--------------------------------------------------------------------------
889             */
890              
891             bool
892 0           bson_iter_as_bool (const bson_iter_t *iter) /* IN */
893             {
894 0 0         BSON_ASSERT (iter);
895              
896 0           switch ((int)ITER_TYPE (iter)) {
897             case BSON_TYPE_BOOL:
898 0           return bson_iter_bool (iter);
899             case BSON_TYPE_DOUBLE:
900 0           return !(bson_iter_double (iter) == 0.0);
901             case BSON_TYPE_INT64:
902 0           return !(bson_iter_int64 (iter) == 0);
903             case BSON_TYPE_INT32:
904 0           return !(bson_iter_int32 (iter) == 0);
905             case BSON_TYPE_UTF8:
906 0           return true;
907             case BSON_TYPE_NULL:
908             case BSON_TYPE_UNDEFINED:
909 0           return false;
910             default:
911 0           return true;
912             }
913             }
914              
915              
916             /*
917             *--------------------------------------------------------------------------
918             *
919             * bson_iter_double --
920             *
921             * Retrieves the current field of type BSON_TYPE_DOUBLE.
922             *
923             * Returns:
924             * A double.
925             *
926             * Side effects:
927             * None.
928             *
929             *--------------------------------------------------------------------------
930             */
931              
932             double
933 59           bson_iter_double (const bson_iter_t *iter) /* IN */
934             {
935 59 50         BSON_ASSERT (iter);
936              
937 59 50         if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
938 59           return bson_iter_double_unsafe (iter);
939             }
940              
941 0           return 0;
942             }
943              
944              
945             /*
946             *--------------------------------------------------------------------------
947             *
948             * bson_iter_int32 --
949             *
950             * Retrieves the value of the field of type BSON_TYPE_INT32.
951             *
952             * Returns:
953             * A 32-bit signed integer.
954             *
955             * Side effects:
956             * None.
957             *
958             *--------------------------------------------------------------------------
959             */
960              
961             int32_t
962 69           bson_iter_int32 (const bson_iter_t *iter) /* IN */
963             {
964 69 50         BSON_ASSERT (iter);
965              
966 69 50         if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
967 69           return bson_iter_int32_unsafe (iter);
968             }
969              
970 0           return 0;
971             }
972              
973              
974             /*
975             *--------------------------------------------------------------------------
976             *
977             * bson_iter_int64 --
978             *
979             * Retrieves a 64-bit signed integer for the current BSON_TYPE_INT64
980             * field.
981             *
982             * Returns:
983             * A 64-bit signed integer.
984             *
985             * Side effects:
986             * None.
987             *
988             *--------------------------------------------------------------------------
989             */
990              
991             int64_t
992 25           bson_iter_int64 (const bson_iter_t *iter) /* IN */
993             {
994 25 50         BSON_ASSERT (iter);
995              
996 25 50         if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
997 25           return bson_iter_int64_unsafe (iter);
998             }
999              
1000 0           return 0;
1001             }
1002              
1003              
1004             /*
1005             *--------------------------------------------------------------------------
1006             *
1007             * bson_iter_as_int64 --
1008             *
1009             * If @iter is not an int64 field, it will try to convert the value to
1010             * an int64. Such field types include:
1011             *
1012             * - bool
1013             * - double
1014             * - int32
1015             *
1016             * Returns:
1017             * An int64_t.
1018             *
1019             * Side effects:
1020             * None.
1021             *
1022             *--------------------------------------------------------------------------
1023             */
1024              
1025             int64_t
1026 0           bson_iter_as_int64 (const bson_iter_t *iter) /* IN */
1027             {
1028 0 0         BSON_ASSERT (iter);
1029              
1030 0           switch ((int)ITER_TYPE (iter)) {
1031             case BSON_TYPE_BOOL:
1032 0           return (int64_t)bson_iter_bool (iter);
1033             case BSON_TYPE_DOUBLE:
1034 0           return (int64_t)bson_iter_double (iter);
1035             case BSON_TYPE_INT64:
1036 0           return bson_iter_int64 (iter);
1037             case BSON_TYPE_INT32:
1038 0           return (int64_t)bson_iter_int32 (iter);
1039             default:
1040 0           return 0;
1041             }
1042             }
1043              
1044              
1045             /*
1046             *--------------------------------------------------------------------------
1047             *
1048             * bson_iter_decimal128 --
1049             *
1050             * This function retrieves the current field of type %BSON_TYPE_DECIMAL128.
1051             * The result is valid while @iter is valid, and is stored in @dec.
1052             *
1053             * Returns:
1054             *
1055             * True on success, false on failure.
1056             *
1057             * Side Effects:
1058             * None.
1059             *
1060             *--------------------------------------------------------------------------
1061             */
1062             bool
1063 2412           bson_iter_decimal128 (const bson_iter_t *iter, /* IN */
1064             bson_decimal128_t *dec) /* OUT */
1065             {
1066 2412 50         BSON_ASSERT (iter);
1067              
1068 2412 50         if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
1069 2412           bson_iter_decimal128_unsafe (iter, dec);
1070 2412           return true;
1071             }
1072              
1073 0           return false;
1074             }
1075              
1076              
1077             /*
1078             *--------------------------------------------------------------------------
1079             *
1080             * bson_iter_oid --
1081             *
1082             * Retrieves the current field of type %BSON_TYPE_OID. The result is
1083             * valid while @iter is valid.
1084             *
1085             * Returns:
1086             * A bson_oid_t that should not be modified or freed.
1087             *
1088             * Side effects:
1089             * None.
1090             *
1091             *--------------------------------------------------------------------------
1092             */
1093              
1094             const bson_oid_t *
1095 20           bson_iter_oid (const bson_iter_t *iter) /* IN */
1096             {
1097 20 50         BSON_ASSERT (iter);
1098              
1099 20 50         if (ITER_TYPE (iter) == BSON_TYPE_OID) {
1100 20           return bson_iter_oid_unsafe (iter);
1101             }
1102              
1103 0           return NULL;
1104             }
1105              
1106              
1107             /*
1108             *--------------------------------------------------------------------------
1109             *
1110             * bson_iter_regex --
1111             *
1112             * Fetches the current field from the iter which should be of type
1113             * BSON_TYPE_REGEX.
1114             *
1115             * Returns:
1116             * Regex from @iter. This should not be modified or freed.
1117             *
1118             * Side effects:
1119             * None.
1120             *
1121             *--------------------------------------------------------------------------
1122             */
1123              
1124             const char *
1125 46           bson_iter_regex (const bson_iter_t *iter, /* IN */
1126             const char **options) /* IN */
1127             {
1128 46           const char *ret = NULL;
1129 46           const char *ret_options = NULL;
1130              
1131 46 50         BSON_ASSERT (iter);
1132              
1133 46 50         if (ITER_TYPE (iter) == BSON_TYPE_REGEX) {
1134 46           ret = (const char *)(iter->raw + iter->d1);
1135 46           ret_options = (const char *)(iter->raw + iter->d2);
1136             }
1137              
1138 46 50         if (options) {
1139 46           *options = ret_options;
1140             }
1141              
1142 46           return ret;
1143             }
1144              
1145              
1146             /*
1147             *--------------------------------------------------------------------------
1148             *
1149             * bson_iter_utf8 --
1150             *
1151             * Retrieves the current field of type %BSON_TYPE_UTF8 as a UTF-8
1152             * encoded string.
1153             *
1154             * Parameters:
1155             * @iter: A bson_iter_t.
1156             * @length: A location for the length of the string.
1157             *
1158             * Returns:
1159             * A string that should not be modified or freed.
1160             *
1161             * Side effects:
1162             * @length will be set to the result strings length if non-NULL.
1163             *
1164             *--------------------------------------------------------------------------
1165             */
1166              
1167             const char *
1168 203           bson_iter_utf8 (const bson_iter_t *iter, /* IN */
1169             uint32_t *length) /* OUT */
1170             {
1171 203 50         BSON_ASSERT (iter);
1172              
1173 203 50         if (ITER_TYPE (iter) == BSON_TYPE_UTF8) {
1174 203 50         if (length) {
1175 203           *length = bson_iter_utf8_len_unsafe (iter);
1176             }
1177              
1178 203           return (const char *)(iter->raw + iter->d2);
1179             }
1180              
1181 0 0         if (length) {
1182 0           *length = 0;
1183             }
1184              
1185 0           return NULL;
1186             }
1187              
1188              
1189             /*
1190             *--------------------------------------------------------------------------
1191             *
1192             * bson_iter_dup_utf8 --
1193             *
1194             * Copies the current UTF-8 element into a newly allocated string. The
1195             * string should be freed using bson_free() when the caller is
1196             * finished with it.
1197             *
1198             * Returns:
1199             * A newly allocated char* that should be freed with bson_free().
1200             *
1201             * Side effects:
1202             * @length will be set to the result strings length if non-NULL.
1203             *
1204             *--------------------------------------------------------------------------
1205             */
1206              
1207             char *
1208 0           bson_iter_dup_utf8 (const bson_iter_t *iter, /* IN */
1209             uint32_t *length) /* OUT */
1210             {
1211 0           uint32_t local_length = 0;
1212             const char *str;
1213 0           char *ret = NULL;
1214              
1215 0 0         BSON_ASSERT (iter);
1216              
1217 0 0         if ((str = bson_iter_utf8 (iter, &local_length))) {
1218 0           ret = bson_malloc0 (local_length + 1);
1219 0           memcpy (ret, str, local_length);
1220 0           ret[local_length] = '\0';
1221             }
1222              
1223 0 0         if (length) {
1224 0           *length = local_length;
1225             }
1226              
1227 0           return ret;
1228             }
1229              
1230              
1231             /*
1232             *--------------------------------------------------------------------------
1233             *
1234             * bson_iter_code --
1235             *
1236             * Retrieves the current field of type %BSON_TYPE_CODE. The length of
1237             * the resulting string is stored in @length.
1238             *
1239             * Parameters:
1240             * @iter: A bson_iter_t.
1241             * @length: A location for the code length.
1242             *
1243             * Returns:
1244             * A NUL-terminated string containing the code which should not be
1245             * modified or freed.
1246             *
1247             * Side effects:
1248             * None.
1249             *
1250             *--------------------------------------------------------------------------
1251             */
1252              
1253             const char *
1254 18           bson_iter_code (const bson_iter_t *iter, /* IN */
1255             uint32_t *length) /* OUT */
1256             {
1257 18 50         BSON_ASSERT (iter);
1258              
1259 18 50         if (ITER_TYPE (iter) == BSON_TYPE_CODE) {
1260 18 50         if (length) {
1261 18           *length = bson_iter_utf8_len_unsafe (iter);
1262             }
1263              
1264 18           return (const char *)(iter->raw + iter->d2);
1265             }
1266              
1267 0 0         if (length) {
1268 0           *length = 0;
1269             }
1270              
1271 0           return NULL;
1272             }
1273              
1274              
1275             /*
1276             *--------------------------------------------------------------------------
1277             *
1278             * bson_iter_codewscope --
1279             *
1280             * Similar to bson_iter_code() but with a scope associated encoded as
1281             * a BSON document. @scope should not be modified or freed. It is
1282             * valid while @iter is valid.
1283             *
1284             * Parameters:
1285             * @iter: A #bson_iter_t.
1286             * @length: A location for the length of resulting string.
1287             * @scope_len: A location for the length of @scope.
1288             * @scope: A location for the scope encoded as BSON.
1289             *
1290             * Returns:
1291             * A NUL-terminated string that should not be modified or freed.
1292             *
1293             * Side effects:
1294             * @length is set to the resulting string length in bytes.
1295             * @scope_len is set to the length of @scope in bytes.
1296             * @scope is set to the scope documents buffer which can be
1297             * turned into a bson document with bson_init_static().
1298             *
1299             *--------------------------------------------------------------------------
1300             */
1301              
1302             const char *
1303 27           bson_iter_codewscope (const bson_iter_t *iter, /* IN */
1304             uint32_t *length, /* OUT */
1305             uint32_t *scope_len, /* OUT */
1306             const uint8_t **scope) /* OUT */
1307             {
1308             uint32_t len;
1309              
1310 27 50         BSON_ASSERT (iter);
1311              
1312 27 50         if (ITER_TYPE (iter) == BSON_TYPE_CODEWSCOPE) {
1313 27 50         if (length) {
1314 27           memcpy (&len, iter->raw + iter->d2, sizeof (len));
1315 27           *length = BSON_UINT32_FROM_LE (len) - 1;
1316             }
1317              
1318 27           memcpy (&len, iter->raw + iter->d4, sizeof (len));
1319 27           *scope_len = BSON_UINT32_FROM_LE (len);
1320 27           *scope = iter->raw + iter->d4;
1321 27           return (const char *)(iter->raw + iter->d3);
1322             }
1323              
1324 0 0         if (length) {
1325 0           *length = 0;
1326             }
1327              
1328 0 0         if (scope_len) {
1329 0           *scope_len = 0;
1330             }
1331              
1332 0 0         if (scope) {
1333 0           *scope = NULL;
1334             }
1335              
1336 27           return NULL;
1337             }
1338              
1339              
1340             /*
1341             *--------------------------------------------------------------------------
1342             *
1343             * bson_iter_dbpointer --
1344             *
1345             * Retrieves a BSON_TYPE_DBPOINTER field. @collection_len will be set
1346             * to the length of the collection name. The collection name will be
1347             * placed into @collection. The oid will be placed into @oid.
1348             *
1349             * @collection and @oid should not be modified.
1350             *
1351             * Parameters:
1352             * @iter: A #bson_iter_t.
1353             * @collection_len: A location for the length of @collection.
1354             * @collection: A location for the collection name.
1355             * @oid: A location for the oid.
1356             *
1357             * Returns:
1358             * None.
1359             *
1360             * Side effects:
1361             * @collection_len is set to the length of @collection in bytes
1362             * excluding the null byte.
1363             * @collection is set to the collection name, including a terminating
1364             * null byte.
1365             * @oid is initialized with the oid.
1366             *
1367             *--------------------------------------------------------------------------
1368             */
1369              
1370             void
1371 15           bson_iter_dbpointer (const bson_iter_t *iter, /* IN */
1372             uint32_t *collection_len, /* OUT */
1373             const char **collection, /* OUT */
1374             const bson_oid_t **oid) /* OUT */
1375             {
1376 15 50         BSON_ASSERT (iter);
1377              
1378 15 50         if (collection) {
1379 15           *collection = NULL;
1380             }
1381              
1382 15 50         if (oid) {
1383 15           *oid = NULL;
1384             }
1385              
1386 15 50         if (ITER_TYPE (iter) == BSON_TYPE_DBPOINTER) {
1387 15 50         if (collection_len) {
1388 15           memcpy (collection_len, (iter->raw + iter->d1), sizeof (*collection_len));
1389 15           *collection_len = BSON_UINT32_FROM_LE (*collection_len);
1390              
1391 15 100         if ((*collection_len) > 0) {
1392 14           (*collection_len)--;
1393             }
1394             }
1395              
1396 15 50         if (collection) {
1397 15           *collection = (const char *)(iter->raw + iter->d2);
1398             }
1399              
1400 15 50         if (oid) {
1401 15           *oid = (const bson_oid_t *)(iter->raw + iter->d3);
1402             }
1403             }
1404 15           }
1405              
1406              
1407             /*
1408             *--------------------------------------------------------------------------
1409             *
1410             * bson_iter_symbol --
1411             *
1412             * Retrieves the symbol of the current field of type BSON_TYPE_SYMBOL.
1413             *
1414             * Parameters:
1415             * @iter: A bson_iter_t.
1416             * @length: A location for the length of the symbol.
1417             *
1418             * Returns:
1419             * A string containing the symbol as UTF-8. The value should not be
1420             * modified or freed.
1421             *
1422             * Side effects:
1423             * @length is set to the resulting strings length in bytes,
1424             * excluding the null byte.
1425             *
1426             *--------------------------------------------------------------------------
1427             */
1428              
1429             const char *
1430 24           bson_iter_symbol (const bson_iter_t *iter, /* IN */
1431             uint32_t *length) /* OUT */
1432             {
1433 24           const char *ret = NULL;
1434 24           uint32_t ret_length = 0;
1435              
1436 24 50         BSON_ASSERT (iter);
1437              
1438 24 50         if (ITER_TYPE (iter) == BSON_TYPE_SYMBOL) {
1439 24           ret = (const char *)(iter->raw + iter->d2);
1440 24           ret_length = bson_iter_utf8_len_unsafe (iter);
1441             }
1442              
1443 24 50         if (length) {
1444 24           *length = ret_length;
1445             }
1446              
1447 24           return ret;
1448             }
1449              
1450              
1451             /*
1452             *--------------------------------------------------------------------------
1453             *
1454             * bson_iter_date_time --
1455             *
1456             * Fetches the number of milliseconds elapsed since the UNIX epoch.
1457             * This value can be negative as times before 1970 are valid.
1458             *
1459             * Returns:
1460             * A signed 64-bit integer containing the number of milliseconds.
1461             *
1462             * Side effects:
1463             * None.
1464             *
1465             *--------------------------------------------------------------------------
1466             */
1467              
1468             int64_t
1469 21           bson_iter_date_time (const bson_iter_t *iter) /* IN */
1470             {
1471 21 50         BSON_ASSERT (iter);
1472              
1473 21 50         if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
1474 21           return bson_iter_int64_unsafe (iter);
1475             }
1476              
1477 0           return 0;
1478             }
1479              
1480              
1481             /*
1482             *--------------------------------------------------------------------------
1483             *
1484             * bson_iter_time_t --
1485             *
1486             * Retrieves the current field of type BSON_TYPE_DATE_TIME as a
1487             * time_t.
1488             *
1489             * Returns:
1490             * A #time_t of the number of seconds since UNIX epoch in UTC.
1491             *
1492             * Side effects:
1493             * None.
1494             *
1495             *--------------------------------------------------------------------------
1496             */
1497              
1498             time_t
1499 0           bson_iter_time_t (const bson_iter_t *iter) /* IN */
1500             {
1501 0 0         BSON_ASSERT (iter);
1502              
1503 0 0         if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
1504 0           return bson_iter_time_t_unsafe (iter);
1505             }
1506              
1507 0           return 0;
1508             }
1509              
1510              
1511             /*
1512             *--------------------------------------------------------------------------
1513             *
1514             * bson_iter_timestamp --
1515             *
1516             * Fetches the current field if it is a BSON_TYPE_TIMESTAMP.
1517             *
1518             * Parameters:
1519             * @iter: A #bson_iter_t.
1520             * @timestamp: a location for the timestamp.
1521             * @increment: A location for the increment.
1522             *
1523             * Returns:
1524             * None.
1525             *
1526             * Side effects:
1527             * @timestamp is initialized.
1528             * @increment is initialized.
1529             *
1530             *--------------------------------------------------------------------------
1531             */
1532              
1533             void
1534 16           bson_iter_timestamp (const bson_iter_t *iter, /* IN */
1535             uint32_t *timestamp, /* OUT */
1536             uint32_t *increment) /* OUT */
1537             {
1538             uint64_t encoded;
1539 16           uint32_t ret_timestamp = 0;
1540 16           uint32_t ret_increment = 0;
1541              
1542 16 50         BSON_ASSERT (iter);
1543              
1544 16 50         if (ITER_TYPE (iter) == BSON_TYPE_TIMESTAMP) {
1545 16           memcpy (&encoded, iter->raw + iter->d1, sizeof (encoded));
1546 16           encoded = BSON_UINT64_FROM_LE (encoded);
1547 16           ret_timestamp = (encoded >> 32) & 0xFFFFFFFF;
1548 16           ret_increment = encoded & 0xFFFFFFFF;
1549             }
1550              
1551 16 50         if (timestamp) {
1552 16           *timestamp = ret_timestamp;
1553             }
1554              
1555 16 50         if (increment) {
1556 16           *increment = ret_increment;
1557             }
1558 16           }
1559              
1560              
1561             /*
1562             *--------------------------------------------------------------------------
1563             *
1564             * bson_iter_timeval --
1565             *
1566             * Retrieves the current field of type BSON_TYPE_DATE_TIME and stores
1567             * it into the struct timeval provided. tv->tv_sec is set to the
1568             * number of seconds since the UNIX epoch in UTC.
1569             *
1570             * Since BSON_TYPE_DATE_TIME does not support fractions of a second,
1571             * tv->tv_usec will always be set to zero.
1572             *
1573             * Returns:
1574             * None.
1575             *
1576             * Side effects:
1577             * @tv is initialized.
1578             *
1579             *--------------------------------------------------------------------------
1580             */
1581              
1582             void
1583 0           bson_iter_timeval (const bson_iter_t *iter, /* IN */
1584             struct timeval *tv) /* OUT */
1585             {
1586 0 0         BSON_ASSERT (iter);
1587              
1588 0 0         if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
1589 0           bson_iter_timeval_unsafe (iter, tv);
1590 0           return;
1591             }
1592              
1593 0           memset (tv, 0, sizeof *tv);
1594             }
1595              
1596              
1597             /**
1598             * bson_iter_document:
1599             * @iter: a bson_iter_t.
1600             * @document_len: A location for the document length.
1601             * @document: A location for a pointer to the document buffer.
1602             *
1603             */
1604             /*
1605             *--------------------------------------------------------------------------
1606             *
1607             * bson_iter_document --
1608             *
1609             * Retrieves the data to the document BSON structure and stores the
1610             * length of the document buffer in @document_len and the document
1611             * buffer in @document.
1612             *
1613             * If you would like to iterate over the child contents, you might
1614             * consider creating a bson_t on the stack such as the following. It
1615             * allows you to call functions taking a const bson_t* only.
1616             *
1617             * bson_t b;
1618             * uint32_t len;
1619             * const uint8_t *data;
1620             *
1621             * bson_iter_document(iter, &len, &data);
1622             *
1623             * if (bson_init_static (&b, data, len)) {
1624             * ...
1625             * }
1626             *
1627             * There is no need to cleanup the bson_t structure as no data can be
1628             * modified in the process of its use (as it is static/const).
1629             *
1630             * Returns:
1631             * None.
1632             *
1633             * Side effects:
1634             * @document_len is initialized.
1635             * @document is initialized.
1636             *
1637             *--------------------------------------------------------------------------
1638             */
1639              
1640             void
1641 492           bson_iter_document (const bson_iter_t *iter, /* IN */
1642             uint32_t *document_len, /* OUT */
1643             const uint8_t **document) /* OUT */
1644             {
1645 492 50         BSON_ASSERT (iter);
1646 492 50         BSON_ASSERT (document_len);
1647 492 50         BSON_ASSERT (document);
1648              
1649 492           *document = NULL;
1650 492           *document_len = 0;
1651              
1652 492 50         if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
1653 492           memcpy (document_len, (iter->raw + iter->d1), sizeof (*document_len));
1654 492           *document_len = BSON_UINT32_FROM_LE (*document_len);
1655 492           *document = (iter->raw + iter->d1);
1656             }
1657 492           }
1658              
1659              
1660             /**
1661             * bson_iter_array:
1662             * @iter: a #bson_iter_t.
1663             * @array_len: A location for the array length.
1664             * @array: A location for a pointer to the array buffer.
1665             */
1666             /*
1667             *--------------------------------------------------------------------------
1668             *
1669             * bson_iter_array --
1670             *
1671             * Retrieves the data to the array BSON structure and stores the
1672             * length of the array buffer in @array_len and the array buffer in
1673             * @array.
1674             *
1675             * If you would like to iterate over the child contents, you might
1676             * consider creating a bson_t on the stack such as the following. It
1677             * allows you to call functions taking a const bson_t* only.
1678             *
1679             * bson_t b;
1680             * uint32_t len;
1681             * const uint8_t *data;
1682             *
1683             * bson_iter_array (iter, &len, &data);
1684             *
1685             * if (bson_init_static (&b, data, len)) {
1686             * ...
1687             * }
1688             *
1689             * There is no need to cleanup the #bson_t structure as no data can be
1690             * modified in the process of its use.
1691             *
1692             * Returns:
1693             * None.
1694             *
1695             * Side effects:
1696             * @array_len is initialized.
1697             * @array is initialized.
1698             *
1699             *--------------------------------------------------------------------------
1700             */
1701              
1702             void
1703 28           bson_iter_array (const bson_iter_t *iter, /* IN */
1704             uint32_t *array_len, /* OUT */
1705             const uint8_t **array) /* OUT */
1706             {
1707 28 50         BSON_ASSERT (iter);
1708 28 50         BSON_ASSERT (array_len);
1709 28 50         BSON_ASSERT (array);
1710              
1711 28           *array = NULL;
1712 28           *array_len = 0;
1713              
1714 28 50         if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
1715 28           memcpy (array_len, (iter->raw + iter->d1), sizeof (*array_len));
1716 28           *array_len = BSON_UINT32_FROM_LE (*array_len);
1717 28           *array = (iter->raw + iter->d1);
1718             }
1719 28           }
1720              
1721              
1722             #define VISIT_FIELD(name) visitor->visit_##name && visitor->visit_##name
1723             #define VISIT_AFTER VISIT_FIELD (after)
1724             #define VISIT_BEFORE VISIT_FIELD (before)
1725             #define VISIT_CORRUPT if (visitor->visit_corrupt) visitor->visit_corrupt
1726             #define VISIT_DOUBLE VISIT_FIELD (double)
1727             #define VISIT_UTF8 VISIT_FIELD (utf8)
1728             #define VISIT_DOCUMENT VISIT_FIELD (document)
1729             #define VISIT_ARRAY VISIT_FIELD (array)
1730             #define VISIT_BINARY VISIT_FIELD (binary)
1731             #define VISIT_UNDEFINED VISIT_FIELD (undefined)
1732             #define VISIT_OID VISIT_FIELD (oid)
1733             #define VISIT_BOOL VISIT_FIELD (bool)
1734             #define VISIT_DATE_TIME VISIT_FIELD (date_time)
1735             #define VISIT_NULL VISIT_FIELD (null)
1736             #define VISIT_REGEX VISIT_FIELD (regex)
1737             #define VISIT_DBPOINTER VISIT_FIELD (dbpointer)
1738             #define VISIT_CODE VISIT_FIELD (code)
1739             #define VISIT_SYMBOL VISIT_FIELD (symbol)
1740             #define VISIT_CODEWSCOPE VISIT_FIELD (codewscope)
1741             #define VISIT_INT32 VISIT_FIELD (int32)
1742             #define VISIT_TIMESTAMP VISIT_FIELD (timestamp)
1743             #define VISIT_INT64 VISIT_FIELD (int64)
1744             #define VISIT_DECIMAL128 VISIT_FIELD (decimal128)
1745             #define VISIT_MAXKEY VISIT_FIELD (maxkey)
1746             #define VISIT_MINKEY VISIT_FIELD (minkey)
1747              
1748              
1749             /**
1750             * bson_iter_visit_all:
1751             * @iter: A #bson_iter_t.
1752             * @visitor: A #bson_visitor_t containing the visitors.
1753             * @data: User data for @visitor data parameters.
1754             *
1755             *
1756             * Returns: true if the visitor was pre-maturely ended; otherwise false.
1757             */
1758             /*
1759             *--------------------------------------------------------------------------
1760             *
1761             * bson_iter_visit_all --
1762             *
1763             * Visits all fields forward from the current position of @iter. For
1764             * each field found a function in @visitor will be called. Typically
1765             * you will use this immediately after initializing a bson_iter_t.
1766             *
1767             * bson_iter_init (&iter, b);
1768             * bson_iter_visit_all (&iter, my_visitor, NULL);
1769             *
1770             * @iter will no longer be valid after this function has executed and
1771             * will need to be reinitialized if intending to reuse.
1772             *
1773             * Returns:
1774             * true if successfully visited all fields or callback requested
1775             * early termination, otherwise false.
1776             *
1777             * Side effects:
1778             * None.
1779             *
1780             *--------------------------------------------------------------------------
1781             */
1782              
1783             bool
1784 1879           bson_iter_visit_all (bson_iter_t *iter, /* INOUT */
1785             const bson_visitor_t *visitor, /* IN */
1786             void *data) /* IN */
1787             {
1788             uint32_t bson_type;
1789             const char *key;
1790             bool unsupported;
1791              
1792 1879 50         BSON_ASSERT (iter);
1793 1879 50         BSON_ASSERT (visitor);
1794              
1795 3736 100         while (_bson_iter_next_internal (iter, &key, &bson_type, &unsupported)) {
1796 1873 100         if (*key && !bson_utf8_validate (key, strlen (key), false)) {
    50          
1797 0           iter->err_off = iter->off;
1798 0           break;
1799             }
1800              
1801 1873 50         if (VISIT_BEFORE (iter, key, data)) {
    50          
1802 0           return true;
1803             }
1804              
1805 1873           switch (bson_type) {
1806             case BSON_TYPE_DOUBLE:
1807              
1808 59 50         if (VISIT_DOUBLE (iter, key, bson_iter_double (iter), data)) {
    0          
1809 0           return true;
1810             }
1811              
1812 59           break;
1813             case BSON_TYPE_UTF8:
1814             {
1815             uint32_t utf8_len;
1816             const char *utf8;
1817              
1818 100           utf8 = bson_iter_utf8 (iter, &utf8_len);
1819              
1820 100 100         if (!bson_utf8_validate (utf8, utf8_len, true)) {
1821 3           iter->err_off = iter->off;
1822 3           return true;
1823             }
1824              
1825 97 50         if (VISIT_UTF8 (iter, key, utf8_len, utf8, data)) {
    50          
1826 0           return true;
1827             }
1828             }
1829 97           break;
1830             case BSON_TYPE_DOCUMENT:
1831             {
1832 245           const uint8_t *docbuf = NULL;
1833 245           uint32_t doclen = 0;
1834             bson_t b;
1835              
1836 245           bson_iter_document (iter, &doclen, &docbuf);
1837              
1838 245 100         if (bson_init_static (&b, docbuf, doclen) &&
    50          
1839 244 50         VISIT_DOCUMENT (iter, key, &b, data)) {
1840 0           return true;
1841             }
1842             }
1843 245           break;
1844             case BSON_TYPE_ARRAY:
1845             {
1846 14           const uint8_t *docbuf = NULL;
1847 14           uint32_t doclen = 0;
1848             bson_t b;
1849              
1850 14           bson_iter_array (iter, &doclen, &docbuf);
1851              
1852 14 50         if (bson_init_static (&b, docbuf, doclen)
1853 14 50         && VISIT_ARRAY (iter, key, &b, data)) {
    50          
1854 0           return true;
1855             }
1856             }
1857 14           break;
1858             case BSON_TYPE_BINARY:
1859             {
1860 28           const uint8_t *binary = NULL;
1861 28           bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
1862 28           uint32_t binary_len = 0;
1863              
1864 28           bson_iter_binary (iter, &subtype, &binary_len, &binary);
1865              
1866 28 50         if (VISIT_BINARY (iter, key, subtype, binary_len, binary, data)) {
    0          
1867 0           return true;
1868             }
1869             }
1870 28           break;
1871             case BSON_TYPE_UNDEFINED:
1872              
1873 2 50         if (VISIT_UNDEFINED (iter, key, data)) {
    0          
1874 0           return true;
1875             }
1876              
1877 2           break;
1878             case BSON_TYPE_OID:
1879              
1880 18 50         if (VISIT_OID (iter, key, bson_iter_oid (iter), data)) {
    0          
1881 0           return true;
1882             }
1883              
1884 18           break;
1885             case BSON_TYPE_BOOL:
1886              
1887 14 50         if (VISIT_BOOL (iter, key, bson_iter_bool (iter), data)) {
    0          
1888 0           return true;
1889             }
1890              
1891 14           break;
1892             case BSON_TYPE_DATE_TIME:
1893              
1894 15 50         if (VISIT_DATE_TIME (iter, key, bson_iter_date_time (iter), data)) {
    0          
1895 0           return true;
1896             }
1897              
1898 15           break;
1899             case BSON_TYPE_NULL:
1900              
1901 7 50         if (VISIT_NULL (iter, key, data)) {
    0          
1902 0           return true;
1903             }
1904              
1905 7           break;
1906             case BSON_TYPE_REGEX:
1907             {
1908 23           const char *regex = NULL;
1909 23           const char *options = NULL;
1910 23           regex = bson_iter_regex (iter, &options);
1911              
1912 23 50         if (VISIT_REGEX (iter, key, regex, options, data)) {
    0          
1913 0           return true;
1914             }
1915             }
1916 23           break;
1917             case BSON_TYPE_DBPOINTER:
1918             {
1919 8           uint32_t collection_len = 0;
1920 8           const char *collection = NULL;
1921 8           const bson_oid_t *oid = NULL;
1922              
1923 8           bson_iter_dbpointer (iter, &collection_len, &collection, &oid);
1924              
1925 8 50         if (VISIT_DBPOINTER (iter, key, collection_len, collection, oid,
    0          
1926             data)) {
1927 0           return true;
1928             }
1929             }
1930 8           break;
1931             case BSON_TYPE_CODE:
1932             {
1933             uint32_t code_len;
1934             const char *code;
1935              
1936 9           code = bson_iter_code (iter, &code_len);
1937              
1938 9 50         if (VISIT_CODE (iter, key, code_len, code, data)) {
    0          
1939 0           return true;
1940             }
1941             }
1942 9           break;
1943             case BSON_TYPE_SYMBOL:
1944             {
1945             uint32_t symbol_len;
1946             const char *symbol;
1947              
1948 12           symbol = bson_iter_symbol (iter, &symbol_len);
1949              
1950 12 50         if (VISIT_SYMBOL (iter, key, symbol_len, symbol, data)) {
    0          
1951 0           return true;
1952             }
1953             }
1954 12           break;
1955             case BSON_TYPE_CODEWSCOPE:
1956             {
1957 14           uint32_t length = 0;
1958             const char *code;
1959 14           const uint8_t *docbuf = NULL;
1960 14           uint32_t doclen = 0;
1961             bson_t b;
1962              
1963 14           code = bson_iter_codewscope (iter, &length, &doclen, &docbuf);
1964              
1965 14 50         if (bson_init_static (&b, docbuf, doclen) &&
    50          
1966 14 100         VISIT_CODEWSCOPE (iter, key, length, code, &b, data)) {
1967 13           return true;
1968             }
1969             }
1970 1           break;
1971             case BSON_TYPE_INT32:
1972              
1973 59 50         if (VISIT_INT32 (iter, key, bson_iter_int32 (iter), data)) {
    0          
1974 0           return true;
1975             }
1976              
1977 59           break;
1978             case BSON_TYPE_TIMESTAMP:
1979             {
1980             uint32_t timestamp;
1981             uint32_t increment;
1982 7           bson_iter_timestamp (iter, ×tamp, &increment);
1983              
1984 7 50         if (VISIT_TIMESTAMP (iter, key, timestamp, increment, data)) {
    0          
1985 0           return true;
1986             }
1987             }
1988 7           break;
1989             case BSON_TYPE_INT64:
1990              
1991 25 50         if (VISIT_INT64 (iter, key, bson_iter_int64 (iter), data)) {
    0          
1992 0           return true;
1993             }
1994              
1995 25           break;
1996             case BSON_TYPE_DECIMAL128:
1997             {
1998             bson_decimal128_t dec;
1999 1206           bson_iter_decimal128 (iter, &dec);
2000              
2001 1206 50         if (VISIT_DECIMAL128 (iter, key, &dec, data)) {
    0          
2002 0           return true;
2003             }
2004             }
2005 1206           break;
2006             case BSON_TYPE_MAXKEY:
2007              
2008 4 50         if (VISIT_MAXKEY (iter, bson_iter_key_unsafe (iter), data)) {
    0          
2009 0           return true;
2010             }
2011              
2012 4           break;
2013             case BSON_TYPE_MINKEY:
2014              
2015 4 50         if (VISIT_MINKEY (iter, bson_iter_key_unsafe (iter), data)) {
    0          
2016 0           return true;
2017             }
2018              
2019 4           break;
2020             case BSON_TYPE_EOD:
2021             default:
2022 0           break;
2023             }
2024              
2025 1857 50         if (VISIT_AFTER (iter, bson_iter_key_unsafe (iter), data)) {
    0          
2026 0           return true;
2027             }
2028             }
2029              
2030 1863 100         if (iter->err_off) {
2031 54 100         if (unsupported &&
    50          
2032 5 50         visitor->visit_unsupported_type &&
2033 5           bson_utf8_validate (key, strlen (key), false)) {
2034 5           visitor->visit_unsupported_type (iter, key, bson_type, data);
2035 5           return false;
2036             }
2037              
2038 49 50         VISIT_CORRUPT (iter, data);
2039             }
2040              
2041             #undef VISIT_FIELD
2042              
2043 1879           return false;
2044             }
2045              
2046              
2047             /*
2048             *--------------------------------------------------------------------------
2049             *
2050             * bson_iter_overwrite_bool --
2051             *
2052             * Overwrites the current BSON_TYPE_BOOLEAN field with a new value.
2053             * This is performed in-place and therefore no keys are moved.
2054             *
2055             * Returns:
2056             * None.
2057             *
2058             * Side effects:
2059             * None.
2060             *
2061             *--------------------------------------------------------------------------
2062             */
2063              
2064             void
2065 0           bson_iter_overwrite_bool (bson_iter_t *iter, /* IN */
2066             bool value) /* IN */
2067             {
2068 0 0         BSON_ASSERT (iter);
2069 0           value = !!value;
2070              
2071 0 0         if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
2072 0           memcpy ((void *)(iter->raw + iter->d1), &value, 1);
2073             }
2074 0           }
2075              
2076              
2077             /*
2078             *--------------------------------------------------------------------------
2079             *
2080             * bson_iter_overwrite_int32 --
2081             *
2082             * Overwrites the current BSON_TYPE_INT32 field with a new value.
2083             * This is performed in-place and therefore no keys are moved.
2084             *
2085             * Returns:
2086             * None.
2087             *
2088             * Side effects:
2089             * None.
2090             *
2091             *--------------------------------------------------------------------------
2092             */
2093              
2094             void
2095 0           bson_iter_overwrite_int32 (bson_iter_t *iter, /* IN */
2096             int32_t value) /* IN */
2097             {
2098 0 0         BSON_ASSERT (iter);
2099              
2100 0 0         if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
2101             #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
2102             value = BSON_UINT32_TO_LE (value);
2103             #endif
2104 0           memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value));
2105             }
2106 0           }
2107              
2108              
2109             /*
2110             *--------------------------------------------------------------------------
2111             *
2112             * bson_iter_overwrite_int64 --
2113             *
2114             * Overwrites the current BSON_TYPE_INT64 field with a new value.
2115             * This is performed in-place and therefore no keys are moved.
2116             *
2117             * Returns:
2118             * None.
2119             *
2120             * Side effects:
2121             * None.
2122             *
2123             *--------------------------------------------------------------------------
2124             */
2125              
2126             void
2127 0           bson_iter_overwrite_int64 (bson_iter_t *iter, /* IN */
2128             int64_t value) /* IN */
2129             {
2130 0 0         BSON_ASSERT (iter);
2131              
2132 0 0         if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
2133             #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
2134             value = BSON_UINT64_TO_LE (value);
2135             #endif
2136 0           memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value));
2137             }
2138 0           }
2139              
2140              
2141             /*
2142             *--------------------------------------------------------------------------
2143             *
2144             * bson_iter_overwrite_double --
2145             *
2146             * Overwrites the current BSON_TYPE_DOUBLE field with a new value.
2147             * This is performed in-place and therefore no keys are moved.
2148             *
2149             * Returns:
2150             * None.
2151             *
2152             * Side effects:
2153             * None.
2154             *
2155             *--------------------------------------------------------------------------
2156             */
2157              
2158             void
2159 0           bson_iter_overwrite_double (bson_iter_t *iter, /* IN */
2160             double value) /* IN */
2161             {
2162 0 0         BSON_ASSERT (iter);
2163              
2164 0 0         if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
2165 0           value = BSON_DOUBLE_TO_LE (value);
2166 0           memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value));
2167             }
2168 0           }
2169              
2170              
2171             /*
2172             *--------------------------------------------------------------------------
2173             *
2174             * bson_iter_overwrite_decimal128 --
2175             *
2176             * Overwrites the current BSON_TYPE_DECIMAL128 field with a new value.
2177             * This is performed in-place and therefore no keys are moved.
2178             *
2179             * Returns:
2180             * None.
2181             *
2182             * Side effects:
2183             * None.
2184             *
2185             *--------------------------------------------------------------------------
2186             */
2187             void
2188 0           bson_iter_overwrite_decimal128 (bson_iter_t *iter, /* IN */
2189             bson_decimal128_t *value) /* IN */
2190             {
2191 0 0         BSON_ASSERT (iter);
2192              
2193 0 0         if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
2194             #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
2195             uint64_t data[2];
2196             data[0] = BSON_UINT64_TO_LE (value->low);
2197             data[1] = BSON_UINT64_TO_LE (value->high);
2198             memcpy ((void *)(iter->raw + iter->d1), data, sizeof (data));
2199             #else
2200 0           memcpy ((void *)(iter->raw + iter->d1), value, sizeof (*value));
2201             #endif
2202             }
2203 0           }
2204              
2205              
2206             /*
2207             *--------------------------------------------------------------------------
2208             *
2209             * bson_iter_value --
2210             *
2211             * Retrieves a bson_value_t containing the boxed value of the current
2212             * element. The result of this function valid until the state of
2213             * iter has been changed (through the use of bson_iter_next()).
2214             *
2215             * Returns:
2216             * A bson_value_t that should not be modified or freed. If you need
2217             * to hold on to the value, use bson_value_copy().
2218             *
2219             * Side effects:
2220             * None.
2221             *
2222             *--------------------------------------------------------------------------
2223             */
2224              
2225             const bson_value_t *
2226 0           bson_iter_value (bson_iter_t *iter) /* IN */
2227             {
2228             bson_value_t *value;
2229              
2230 0 0         BSON_ASSERT (iter);
2231              
2232 0           value = &iter->value;
2233 0           value->value_type = ITER_TYPE (iter);
2234              
2235 0           switch (value->value_type) {
2236             case BSON_TYPE_DOUBLE:
2237 0           value->value.v_double = bson_iter_double (iter);
2238 0           break;
2239             case BSON_TYPE_UTF8:
2240 0           value->value.v_utf8.str =
2241 0           (char *)bson_iter_utf8 (iter, &value->value.v_utf8.len);
2242 0           break;
2243             case BSON_TYPE_DOCUMENT:
2244 0           bson_iter_document (iter,
2245             &value->value.v_doc.data_len,
2246 0           (const uint8_t **)&value->value.v_doc.data);
2247 0           break;
2248             case BSON_TYPE_ARRAY:
2249 0           bson_iter_array (iter,
2250             &value->value.v_doc.data_len,
2251 0           (const uint8_t **)&value->value.v_doc.data);
2252 0           break;
2253             case BSON_TYPE_BINARY:
2254 0           bson_iter_binary (iter,
2255             &value->value.v_binary.subtype,
2256             &value->value.v_binary.data_len,
2257 0           (const uint8_t **)&value->value.v_binary.data);
2258 0           break;
2259             case BSON_TYPE_OID:
2260 0           bson_oid_copy (bson_iter_oid (iter), &value->value.v_oid);
2261 0           break;
2262             case BSON_TYPE_BOOL:
2263 0           value->value.v_bool = bson_iter_bool (iter);
2264 0           break;
2265             case BSON_TYPE_DATE_TIME:
2266 0           value->value.v_datetime = bson_iter_date_time (iter);
2267 0           break;
2268             case BSON_TYPE_REGEX:
2269 0           value->value.v_regex.regex = (char *)bson_iter_regex (
2270             iter,
2271 0           (const char **)&value->value.v_regex.options);
2272 0           break;
2273             case BSON_TYPE_DBPOINTER: {
2274             const bson_oid_t *oid;
2275              
2276 0           bson_iter_dbpointer (iter,
2277             &value->value.v_dbpointer.collection_len,
2278 0           (const char **)&value->value.v_dbpointer.collection,
2279             &oid);
2280 0           bson_oid_copy (oid, &value->value.v_dbpointer.oid);
2281 0           break;
2282             }
2283             case BSON_TYPE_CODE:
2284 0           value->value.v_code.code =
2285 0           (char *)bson_iter_code (
2286             iter,
2287             &value->value.v_code.code_len);
2288 0           break;
2289             case BSON_TYPE_SYMBOL:
2290 0           value->value.v_symbol.symbol =
2291 0           (char *)bson_iter_symbol (
2292             iter,
2293             &value->value.v_symbol.len);
2294 0           break;
2295             case BSON_TYPE_CODEWSCOPE:
2296 0           value->value.v_codewscope.code =
2297 0           (char *)bson_iter_codewscope (
2298             iter,
2299             &value->value.v_codewscope.code_len,
2300             &value->value.v_codewscope.scope_len,
2301 0           (const uint8_t **)&value->value.v_codewscope.scope_data);
2302 0           break;
2303             case BSON_TYPE_INT32:
2304 0           value->value.v_int32 = bson_iter_int32 (iter);
2305 0           break;
2306             case BSON_TYPE_TIMESTAMP:
2307 0           bson_iter_timestamp (iter,
2308             &value->value.v_timestamp.timestamp,
2309             &value->value.v_timestamp.increment);
2310 0           break;
2311             case BSON_TYPE_INT64:
2312 0           value->value.v_int64 = bson_iter_int64 (iter);
2313 0           break;
2314             case BSON_TYPE_DECIMAL128:
2315 0           bson_iter_decimal128 (iter, &(value->value.v_decimal128));
2316 0           break;
2317             case BSON_TYPE_NULL:
2318             case BSON_TYPE_UNDEFINED:
2319             case BSON_TYPE_MAXKEY:
2320             case BSON_TYPE_MINKEY:
2321 0           break;
2322             case BSON_TYPE_EOD:
2323             default:
2324 0           return NULL;
2325             }
2326              
2327 0           return value;
2328             }