Coverage Report

Created: 2025-12-20 06:39

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