1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <errno.h>
9 
10 #include "zcbor_bulk.h"
11 
zcbor_map_decode_bulk(zcbor_state_t * zsd,struct zcbor_map_decode_key_val * map,size_t map_size,size_t * matched)12 int zcbor_map_decode_bulk(zcbor_state_t *zsd, struct zcbor_map_decode_key_val *map,
13                           size_t map_size, size_t *matched)
14 {
15     bool ok;
16     struct zcbor_map_decode_key_val *dptr = map;
17 
18     if (!zcbor_map_start_decode(zsd)) {
19         return -EBADMSG;
20     }
21 
22     *matched = 0;
23     ok = true;
24 
25     do {
26         struct zcbor_string key;
27         bool found = false;
28         size_t map_count = 0;
29 
30         ok = zcbor_tstr_decode(zsd, &key);
31 
32         while (ok && map_count < map_size) {
33             if (dptr >= (map + map_size)) {
34                 dptr = map;
35             }
36 
37             if (key.len == dptr->key.len        &&
38                 memcmp(key.value, dptr->key.value, key.len) == 0) {
39 
40                 if (dptr->found) {
41                     return -EADDRINUSE;
42                 }
43                 if (!dptr->decoder(zsd, dptr->value_ptr)) {
44                     /* Failure to decode value matched to key
45                      * means that either decoder has been
46                      * incorrectly assigned or SMP payload
47                      * is broken anyway.
48                      */
49                     return -ENOMSG;
50                 }
51 
52                 dptr->found = true;
53                 found = true;
54                 ++dptr;
55                 ++(*matched);
56                 break;
57             }
58 
59             ++dptr;
60             ++map_count;
61         }
62 
63         if (!found && ok) {
64             ok = zcbor_any_skip(zsd, NULL);
65         }
66     } while (ok);
67 
68     return zcbor_map_end_decode(zsd) ? 0 : -EBADMSG;
69 }
70