Coverage Report

Created: 2025-11-09 06:43

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
13.7k
        {
54
13.7k
            std::memcpy(bytes_.data(),data,12);
55
13.7k
        }
56
57
        oid_t(const string_view& str)
58
8.83k
        {
59
114k
            for (std::size_t i = 0; i < bytes_.size(); i++) 
60
105k
            {
61
105k
               bytes_[i] = ((parse_hex_char (str[2 * i]) << 4) |
62
105k
                           (parse_hex_char (str[2 * i + 1])));
63
105k
            }
64
8.83k
        }
65
66
        const uint8_t* data() const
67
13.7k
        {
68
13.7k
            return bytes_.data();
69
13.7k
        }
70
71
        std::size_t size() const
72
0
        {
73
0
            return bytes_.size();
74
0
        }
75
76
        iterator begin()
77
8.83k
        {
78
8.83k
            return bytes_.begin();
79
8.83k
        }
80
81
        iterator end()
82
8.83k
        {
83
8.83k
            return bytes_.end();
84
8.83k
        }
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
211k
        {
100
211k
           switch (hex) {
101
106k
           case '0':
102
106k
              return 0;
103
4.66k
           case '1':
104
4.66k
              return 1;
105
12.0k
           case '2':
106
12.0k
              return 2;
107
4.73k
           case '3':
108
4.73k
              return 3;
109
3.20k
           case '4':
110
3.20k
              return 4;
111
793
           case '5':
112
793
              return 5;
113
3.17k
           case '6':
114
3.17k
              return 6;
115
61.5k
           case '7':
116
61.5k
              return 7;
117
1.50k
           case '8':
118
1.50k
              return 8;
119
433
           case '9':
120
433
              return 9;
121
3.85k
           case 'a':
122
3.85k
           case 'A':
123
3.85k
              return 0xa;
124
1.26k
           case 'b':
125
1.26k
           case 'B':
126
1.26k
              return 0xb;
127
620
           case 'c':
128
620
           case 'C':
129
620
              return 0xc;
130
2.20k
           case 'd':
131
2.20k
           case 'D':
132
2.20k
              return 0xd;
133
860
           case 'e':
134
860
           case 'E':
135
860
              return 0xe;
136
4.69k
           case 'f':
137
4.69k
           case 'F':
138
4.69k
              return 0xf;
139
0
           default:
140
0
              return 0;
141
211k
           }
142
211k
        }
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 const 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
13.7k
        {
182
13.7k
            static const uint16_t hex_char_pairs[] = {
183
13.7k
                12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880,
184
13.7k
                25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105, 13361, 13617,
185
13.7k
                13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, 12338,
186
13.7k
                12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138,
187
13.7k
                25394, 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875,
188
13.7k
                14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, 12340, 12596,
189
13.7k
                12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396,
190
13.7k
                25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133,
191
13.7k
                14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854,
192
13.7k
                13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654,
193
13.7k
                25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391,
194
13.7k
                14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112,
195
13.7k
                13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912,
196
13.7k
                26168, 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649,
197
13.7k
                24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409,
198
13.7k
                13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209,
199
13.7k
                12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930,
200
13.7k
                25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667,
201
13.7k
                13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388,
202
13.7k
                12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188,
203
13.7k
                25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669, 13925,
204
13.7k
                14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 12390, 12646,
205
13.7k
                12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446,
206
13.7k
                25702, 25958, 26214};
207
208
13.7k
            return hex_char_pairs;
209
13.7k
        }
210
211
        inline
212
        void init_hex_char_pairs(const oid_t& oid, uint16_t* data)
213
13.7k
        {
214
13.7k
            const uint8_t* bytes = oid.data();
215
13.7k
            const uint16_t* gHexCharPairs = get_hex_char_pairs(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>());
216
217
13.7k
            data[0] = gHexCharPairs[bytes[0]];
218
13.7k
            data[1] = gHexCharPairs[bytes[1]];
219
13.7k
            data[2] = gHexCharPairs[bytes[2]];
220
13.7k
            data[3] = gHexCharPairs[bytes[3]];
221
13.7k
            data[4] = gHexCharPairs[bytes[4]];
222
13.7k
            data[5] = gHexCharPairs[bytes[5]];
223
13.7k
            data[6] = gHexCharPairs[bytes[6]];
224
13.7k
            data[7] = gHexCharPairs[bytes[7]];
225
13.7k
            data[8] = gHexCharPairs[bytes[8]];
226
13.7k
            data[9] = gHexCharPairs[bytes[9]];
227
13.7k
            data[10] = gHexCharPairs[bytes[10]];
228
13.7k
            data[11] = gHexCharPairs[bytes[11]];
229
13.7k
        }
230
231
} // namespace detail
232
233
    template <typename StringT>
234
    inline 
235
    void to_string(const oid_t& oid, StringT& s)
236
13.7k
    {
237
13.7k
        s.resize(24);
238
13.7k
        detail::init_hex_char_pairs(oid, reinterpret_cast<uint16_t*>(&s[0]));
239
13.7k
    }
240
241
} // namespace bson
242
} // namespace jsoncons
243
244
#endif // JSONCONS_EXT_BSON_BSON_OID_HPP