Coverage Report

Created: 2026-08-17 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp
Line
Count
Source
1
#ifndef JSONCONS_EXT_BSON_BSON_OID_HPP
2
#define JSONCONS_EXT_BSON_BSON_OID_HPP
3
4
/*
5
 *  Implements class oid_t and non member function bson_oid_to_string
6
 *  
7
 *  Based on the libjson functions bson_oid_to_string 
8
 *  and bson_oid_init_from_string_unsafe , available at
9
 *  https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-oid.h
10
 *  and https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-oid.c
11
 *  
12
*/
13
14
/*
15
 * Copyright 2015 MongoDB, Inc.
16
 *
17
 * Licensed under the Apache License, Version 2.0 (the "License");
18
 * you may not use this file except in compliance with the License.
19
 * You may obtain a copy of the License at
20
 *
21
 *   http://www.apache.org/licenses/LICENSE-2.0
22
 *
23
 * Unless required by applicable law or agreed to in writing, software
24
 * distributed under the License is distributed on an "AS IS" BASIS,
25
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26
 * See the License for the specific language governing permissions and
27
 * limitations under the License.
28
 */
29
30
#include <array>
31
#include <cstdint>
32
#include <cstdlib>
33
#include <cstring>
34
#include <type_traits>
35
36
#include <jsoncons/config/jsoncons_config.hpp>
37
38
namespace jsoncons { 
39
namespace bson {
40
41
    class oid_t
42
    {
43
        std::array<uint8_t,12> bytes_;
44
    public:
45
        using iterator = std::array<uint8_t,12>::iterator;
46
        using const_iterator = std::array<uint8_t,12>::const_iterator;
47
48
        oid_t(const std::array<uint8_t,12>& bytes)
49
            : bytes_(bytes)
50
0
        {
51
0
        }
52
        oid_t(uint8_t data[12])
53
34.7k
        {
54
34.7k
            std::memcpy(bytes_.data(),data,12);
55
34.7k
        }
56
57
        oid_t(const string_view& str)
58
28.9k
        {
59
376k
            for (std::size_t i = 0; i < bytes_.size(); i++) 
60
347k
            {
61
347k
               bytes_[i] = ((parse_hex_char (str[2 * i]) << 4) |
62
347k
                           (parse_hex_char (str[2 * i + 1])));
63
347k
            }
64
28.9k
        }
65
66
        const uint8_t* data() const
67
34.7k
        {
68
34.7k
            return bytes_.data();
69
34.7k
        }
70
71
        std::size_t size() const
72
0
        {
73
0
            return bytes_.size();
74
0
        }
75
76
        iterator begin()
77
28.9k
        {
78
28.9k
            return bytes_.begin();
79
28.9k
        }
80
81
        iterator end()
82
28.9k
        {
83
28.9k
            return bytes_.end();
84
28.9k
        }
85
86
        const_iterator begin() const
87
0
        {
88
0
            return bytes_.begin();
89
0
        }
90
91
        const_iterator end() const
92
0
        {
93
0
            return bytes_.end();
94
0
        }
95
96
    private:
97
98
        static uint8_t parse_hex_char (char hex)
99
694k
        {
100
694k
           switch (hex) {
101
359k
           case '0':
102
359k
              return 0;
103
22.0k
           case '1':
104
22.0k
              return 1;
105
15.6k
           case '2':
106
15.6k
              return 2;
107
17.7k
           case '3':
108
17.7k
              return 3;
109
8.46k
           case '4':
110
8.46k
              return 4;
111
7.19k
           case '5':
112
7.19k
              return 5;
113
6.66k
           case '6':
114
6.66k
              return 6;
115
202k
           case '7':
116
202k
              return 7;
117
2.20k
           case '8':
118
2.20k
              return 8;
119
2.98k
           case '9':
120
2.98k
              return 9;
121
11.2k
           case 'a':
122
11.2k
           case 'A':
123
11.2k
              return 0xa;
124
3.67k
           case 'b':
125
3.67k
           case 'B':
126
3.67k
              return 0xb;
127
1.49k
           case 'c':
128
1.49k
           case 'C':
129
1.49k
              return 0xc;
130
2.85k
           case 'd':
131
2.85k
           case 'D':
132
2.85k
              return 0xd;
133
4.20k
           case 'e':
134
4.20k
           case 'E':
135
4.20k
              return 0xe;
136
26.6k
           case 'f':
137
26.6k
           case 'F':
138
26.6k
              return 0xf;
139
0
           default:
140
0
              return 0;
141
694k
           }
142
694k
        }
143
    };
144
145
namespace detail {
146
147
        inline
148
        const uint16_t* get_hex_char_pairs(std::true_type) // big endian
149
0
        {
150
0
            static constexpr uint16_t hex_char_pairs[] = {
151
0
               12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385,
152
0
               12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595, 12596, 12597,
153
0
               12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644, 12645, 12646, 12848,
154
0
               12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12897, 12898,
155
0
               12899, 12900, 12901, 12902, 13104, 13105, 13106, 13107, 13108, 13109, 13110,
156
0
               13111, 13112, 13113, 13153, 13154, 13155, 13156, 13157, 13158, 13360, 13361,
157
0
               13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13409, 13410, 13411,
158
0
               13412, 13413, 13414, 13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623,
159
0
               13624, 13625, 13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874,
160
0
               13875, 13876, 13877, 13878, 13879, 13880, 13881, 13921, 13922, 13923, 13924,
161
0
               13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136,
162
0
               14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385, 14386, 14387,
163
0
               14388, 14389, 14390, 14391, 14392, 14393, 14433, 14434, 14435, 14436, 14437,
164
0
               14438, 14640, 14641, 14642, 14643, 14644, 14645, 14646, 14647, 14648, 14649,
165
0
               14689, 14690, 14691, 14692, 14693, 14694, 24880, 24881, 24882, 24883, 24884,
166
0
               24885, 24886, 24887, 24888, 24889, 24929, 24930, 24931, 24932, 24933, 24934,
167
0
               25136, 25137, 25138, 25139, 25140, 25141, 25142, 25143, 25144, 25145, 25185,
168
0
               25186, 25187, 25188, 25189, 25190, 25392, 25393, 25394, 25395, 25396, 25397,
169
0
               25398, 25399, 25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648,
170
0
               25649, 25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698,
171
0
               25699, 25700, 25701, 25702, 25904, 25905, 25906, 25907, 25908, 25909, 25910,
172
0
               25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958, 26160, 26161,
173
0
               26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169, 26209, 26210, 26211,
174
0
               26212, 26213, 26214};
175
0
176
0
            return hex_char_pairs;
177
0
        }
178
179
        inline
180
        const uint16_t* get_hex_char_pairs(std::false_type) // little endian
181
34.7k
        {
182
34.7k
            static constexpr uint16_t hex_char_pairs[] = {
183
34.7k
                12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880,
184
34.7k
                25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105, 13361, 13617,
185
34.7k
                13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, 12338,
186
34.7k
                12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138,
187
34.7k
                25394, 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875,
188
34.7k
                14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, 12340, 12596,
189
34.7k
                12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396,
190
34.7k
                25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133,
191
34.7k
                14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854,
192
34.7k
                13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654,
193
34.7k
                25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391,
194
34.7k
                14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112,
195
34.7k
                13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912,
196
34.7k
                26168, 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649,
197
34.7k
                24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409,
198
34.7k
                13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209,
199
34.7k
                12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930,
200
34.7k
                25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667,
201
34.7k
                13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388,
202
34.7k
                12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188,
203
34.7k
                25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669, 13925,
204
34.7k
                14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 12390, 12646,
205
34.7k
                12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446,
206
34.7k
                25702, 25958, 26214};
207
208
34.7k
            return hex_char_pairs;
209
34.7k
        }
210
211
        inline
212
        void init_hex_char_pairs(const oid_t& oid, uint16_t* data)
213
34.7k
        {
214
34.7k
            const uint8_t* bytes = oid.data();
215
34.7k
            const uint16_t* gHexCharPairs = get_hex_char_pairs(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>());
216
217
34.7k
            data[0] = gHexCharPairs[bytes[0]];
218
34.7k
            data[1] = gHexCharPairs[bytes[1]];
219
34.7k
            data[2] = gHexCharPairs[bytes[2]];
220
34.7k
            data[3] = gHexCharPairs[bytes[3]];
221
34.7k
            data[4] = gHexCharPairs[bytes[4]];
222
34.7k
            data[5] = gHexCharPairs[bytes[5]];
223
34.7k
            data[6] = gHexCharPairs[bytes[6]];
224
34.7k
            data[7] = gHexCharPairs[bytes[7]];
225
34.7k
            data[8] = gHexCharPairs[bytes[8]];
226
34.7k
            data[9] = gHexCharPairs[bytes[9]];
227
34.7k
            data[10] = gHexCharPairs[bytes[10]];
228
34.7k
            data[11] = gHexCharPairs[bytes[11]];
229
34.7k
        }
230
231
} // namespace detail
232
233
    template <typename StringT>
234
    inline 
235
    void to_string(const oid_t& oid, StringT& s)
236
34.7k
    {
237
34.7k
        s.resize(24);
238
34.7k
        detail::init_hex_char_pairs(oid, reinterpret_cast<uint16_t*>(&s[0]));
239
34.7k
    }
240
241
} // namespace bson
242
} // namespace jsoncons
243
244
#endif // JSONCONS_EXT_BSON_BSON_OID_HPP