Coverage Report

Created: 2025-11-24 06:07

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