File Coverage

bson/bson-oid.c
Criterion Covered Total %
statement 5 78 6.4
branch 2 46 4.3
condition n/a
subroutine n/a
pod n/a
total 7 124 5.6


line stmt bran cond sub pod time code
1             /*
2             * Copyright 2013 MongoDB, Inc.
3             *
4             * Licensed under the Apache License, Version 2.0 (the "License");
5             * you may not use this file except in compliance with the License.
6             * You may obtain a copy of the License at
7             *
8             * http://www.apache.org/licenses/LICENSE-2.0
9             *
10             * Unless required by applicable law or agreed to in writing, software
11             * distributed under the License is distributed on an "AS IS" BASIS,
12             * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13             * See the License for the specific language governing permissions and
14             * limitations under the License.
15             */
16              
17             #include "bson-compat.h"
18              
19             #include
20             #include
21             #include
22             #include
23              
24             #include "bson-context-private.h"
25             #include "bson-md5.h"
26             #include "bson-oid.h"
27             #include "bson-string.h"
28              
29              
30             /*
31             * This table contains an array of two character pairs for every possible
32             * uint8_t. It is used as a lookup table when encoding a bson_oid_t
33             * to hex formatted ASCII. Performing two characters at a time roughly
34             * reduces the number of operations by one-half.
35             */
36             static const uint16_t gHexCharPairs[] = {
37             #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
38             12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345,
39             12385, 12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595,
40             12596, 12597, 12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644,
41             12645, 12646, 12848, 12849, 12850, 12851, 12852, 12853, 12854, 12855,
42             12856, 12857, 12897, 12898, 12899, 12900, 12901, 12902, 13104, 13105,
43             13106, 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13153, 13154,
44             13155, 13156, 13157, 13158, 13360, 13361, 13362, 13363, 13364, 13365,
45             13366, 13367, 13368, 13369, 13409, 13410, 13411, 13412, 13413, 13414,
46             13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623, 13624, 13625,
47             13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874, 13875,
48             13876, 13877, 13878, 13879, 13880, 13881, 13921, 13922, 13923, 13924,
49             13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135,
50             14136, 14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385,
51             14386, 14387, 14388, 14389, 14390, 14391, 14392, 14393, 14433, 14434,
52             14435, 14436, 14437, 14438, 14640, 14641, 14642, 14643, 14644, 14645,
53             14646, 14647, 14648, 14649, 14689, 14690, 14691, 14692, 14693, 14694,
54             24880, 24881, 24882, 24883, 24884, 24885, 24886, 24887, 24888, 24889,
55             24929, 24930, 24931, 24932, 24933, 24934, 25136, 25137, 25138, 25139,
56             25140, 25141, 25142, 25143, 25144, 25145, 25185, 25186, 25187, 25188,
57             25189, 25190, 25392, 25393, 25394, 25395, 25396, 25397, 25398, 25399,
58             25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648, 25649,
59             25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698,
60             25699, 25700, 25701, 25702, 25904, 25905, 25906, 25907, 25908, 25909,
61             25910, 25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958,
62             26160, 26161, 26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169,
63             26209, 26210, 26211, 26212, 26213, 26214
64             #else
65             12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
66             24880, 25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105,
67             13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649,
68             25905, 26161, 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130,
69             14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, 12339, 12595,
70             12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139,
71             25395, 25651, 25907, 26163, 12340, 12596, 12852, 13108, 13364, 13620,
72             13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164,
73             12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
74             24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854, 13110,
75             13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654,
76             25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135,
77             14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600,
78             12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144,
79             25400, 25656, 25912, 26168, 12345, 12601, 12857, 13113, 13369, 13625,
80             13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169,
81             12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689,
82             24929, 25185, 25441, 25697, 25953, 26209, 12386, 12642, 12898, 13154,
83             13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698,
84             25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179,
85             14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388, 12644,
86             12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188,
87             25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669,
88             13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213,
89             12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694,
90             24934, 25190, 25446, 25702, 25958, 26214
91             #endif
92             };
93              
94              
95             /*
96             *--------------------------------------------------------------------------
97             *
98             * bson_oid_init_sequence --
99             *
100             * Initializes @oid with the next oid in the sequence. The first 4
101             * bytes contain the current time and the following 8 contain a 64-bit
102             * integer in big-endian format.
103             *
104             * The bson_oid_t generated by this function is not guaranteed to be
105             * globally unique. Only unique within this context. It is however,
106             * guaranteed to be sequential.
107             *
108             * Returns:
109             * None.
110             *
111             * Side effects:
112             * @oid is initialized.
113             *
114             *--------------------------------------------------------------------------
115             */
116              
117             void
118 0           bson_oid_init_sequence (bson_oid_t *oid, /* OUT */
119             bson_context_t *context) /* IN */
120             {
121 0           uint32_t now = (uint32_t)(time (NULL));
122              
123 0 0         if (!context) {
124 0           context = bson_context_get_default ();
125             }
126              
127 0           now = BSON_UINT32_TO_BE (now);
128              
129 0           memcpy (&oid->bytes[0], &now, sizeof (now));
130 0           context->oid_get_seq64 (context, oid);
131 0           }
132              
133              
134             /*
135             *--------------------------------------------------------------------------
136             *
137             * bson_oid_init --
138             *
139             * Generates bytes for a new bson_oid_t and stores them in @oid. The
140             * bytes will be generated according to the specification and includes
141             * the current time, first 3 bytes of MD5(hostname), pid (or tid), and
142             * monotonic counter.
143             *
144             * The bson_oid_t generated by this function is not guaranteed to be
145             * globally unique. Only unique within this context. It is however,
146             * guaranteed to be sequential.
147             *
148             * Returns:
149             * None.
150             *
151             * Side effects:
152             * @oid is initialized.
153             *
154             *--------------------------------------------------------------------------
155             */
156              
157             void
158 0           bson_oid_init (bson_oid_t *oid, /* OUT */
159             bson_context_t *context) /* IN */
160             {
161 0           uint32_t now = (uint32_t)(time (NULL));
162              
163 0 0         BSON_ASSERT (oid);
164              
165 0 0         if (!context) {
166 0           context = bson_context_get_default ();
167             }
168              
169 0           now = BSON_UINT32_TO_BE (now);
170 0           memcpy (&oid->bytes[0], &now, sizeof (now));
171              
172 0           context->oid_get_host (context, oid);
173 0           context->oid_get_pid (context, oid);
174 0           context->oid_get_seq32 (context, oid);
175 0           }
176              
177              
178             /**
179             * bson_oid_init_from_data:
180             * @oid: A bson_oid_t to initialize.
181             * @bytes: A 12-byte buffer to copy into @oid.
182             *
183             */
184             /*
185             *--------------------------------------------------------------------------
186             *
187             * bson_oid_init_from_data --
188             *
189             * Initializes an @oid from @data. @data MUST be a buffer of at least
190             * 12 bytes. This method is analagous to memcpy()'ing data into @oid.
191             *
192             * Returns:
193             * None.
194             *
195             * Side effects:
196             * @oid is initialized.
197             *
198             *--------------------------------------------------------------------------
199             */
200              
201             void
202 28           bson_oid_init_from_data (bson_oid_t *oid, /* OUT */
203             const uint8_t *data) /* IN */
204             {
205 28 50         BSON_ASSERT (oid);
206 28 50         BSON_ASSERT (data);
207              
208 28           memcpy (oid, data, 12);
209 28           }
210              
211              
212             /*
213             *--------------------------------------------------------------------------
214             *
215             * bson_oid_init_from_string --
216             *
217             * Parses @str containing hex formatted bytes of an object id and
218             * places the bytes in @oid.
219             *
220             * Parameters:
221             * @oid: A bson_oid_t
222             * @str: A string containing at least 24 characters.
223             *
224             * Returns:
225             * None.
226             *
227             * Side effects:
228             * @oid is initialized.
229             *
230             *--------------------------------------------------------------------------
231             */
232              
233             void
234 0           bson_oid_init_from_string (bson_oid_t *oid, /* OUT */
235             const char *str) /* IN */
236             {
237 0 0         BSON_ASSERT (oid);
238 0 0         BSON_ASSERT (str);
239              
240 0           bson_oid_init_from_string_unsafe (oid, str);
241 0           }
242              
243              
244             /*
245             *--------------------------------------------------------------------------
246             *
247             * bson_oid_get_time_t --
248             *
249             * Fetches the time for which @oid was created.
250             *
251             * Returns:
252             * A time_t.
253             *
254             * Side effects:
255             * None.
256             *
257             *--------------------------------------------------------------------------
258             */
259              
260             time_t
261 0           bson_oid_get_time_t (const bson_oid_t *oid) /* IN */
262             {
263 0 0         BSON_ASSERT (oid);
264              
265 0           return bson_oid_get_time_t_unsafe (oid);
266             }
267              
268              
269             /*
270             *--------------------------------------------------------------------------
271             *
272             * bson_oid_to_string --
273             *
274             * Formats a bson_oid_t into a string. @str must contain enough bytes
275             * for the resulting string which is 25 bytes with a terminating
276             * NUL-byte.
277             *
278             * Parameters:
279             * @oid: A bson_oid_t.
280             * @str: A location to store the resulting string.
281             *
282             * Returns:
283             * None.
284             *
285             * Side effects:
286             * None.
287             *
288             *--------------------------------------------------------------------------
289             */
290              
291             void
292 0           bson_oid_to_string
293             (const bson_oid_t *oid, /* IN */
294             char str[BSON_ENSURE_ARRAY_PARAM_SIZE(25)]) /* OUT */
295             {
296             #if !defined(__i386__) && !defined(__x86_64__) && \
297             !defined(_M_IX86) && !defined(_M_X64)
298             BSON_ASSERT (oid);
299             BSON_ASSERT (str);
300              
301             bson_snprintf (str, 25,
302             "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
303             oid->bytes[0],
304             oid->bytes[1],
305             oid->bytes[2],
306             oid->bytes[3],
307             oid->bytes[4],
308             oid->bytes[5],
309             oid->bytes[6],
310             oid->bytes[7],
311             oid->bytes[8],
312             oid->bytes[9],
313             oid->bytes[10],
314             oid->bytes[11]);
315             #else
316             uint16_t *dst;
317 0           uint8_t *id = (uint8_t *)oid;
318              
319 0 0         BSON_ASSERT (oid);
320 0 0         BSON_ASSERT (str);
321              
322 0           dst = (uint16_t *)(void *)str;
323 0           dst[0] = gHexCharPairs[id[0]];
324 0           dst[1] = gHexCharPairs[id[1]];
325 0           dst[2] = gHexCharPairs[id[2]];
326 0           dst[3] = gHexCharPairs[id[3]];
327 0           dst[4] = gHexCharPairs[id[4]];
328 0           dst[5] = gHexCharPairs[id[5]];
329 0           dst[6] = gHexCharPairs[id[6]];
330 0           dst[7] = gHexCharPairs[id[7]];
331 0           dst[8] = gHexCharPairs[id[8]];
332 0           dst[9] = gHexCharPairs[id[9]];
333 0           dst[10] = gHexCharPairs[id[10]];
334 0           dst[11] = gHexCharPairs[id[11]];
335 0           str[24] = '\0';
336             #endif
337 0           }
338              
339              
340             /*
341             *--------------------------------------------------------------------------
342             *
343             * bson_oid_hash --
344             *
345             * Hashes the bytes of the provided bson_oid_t using DJB hash. This
346             * allows bson_oid_t to be used as keys in a hash table.
347             *
348             * Returns:
349             * A hash value corresponding to @oid.
350             *
351             * Side effects:
352             * None.
353             *
354             *--------------------------------------------------------------------------
355             */
356              
357             uint32_t
358 0           bson_oid_hash (const bson_oid_t *oid) /* IN */
359             {
360 0 0         BSON_ASSERT (oid);
361              
362 0           return bson_oid_hash_unsafe (oid);
363             }
364              
365              
366             /*
367             *--------------------------------------------------------------------------
368             *
369             * bson_oid_compare --
370             *
371             * A qsort() style compare function that will return less than zero if
372             * @oid1 is less than @oid2, zero if they are the same, and greater
373             * than zero if @oid2 is greater than @oid1.
374             *
375             * Returns:
376             * A qsort() style compare integer.
377             *
378             * Side effects:
379             * None.
380             *
381             *--------------------------------------------------------------------------
382             */
383              
384             int
385 0           bson_oid_compare (const bson_oid_t *oid1, /* IN */
386             const bson_oid_t *oid2) /* IN */
387             {
388 0 0         BSON_ASSERT (oid1);
389 0 0         BSON_ASSERT (oid2);
390              
391 0           return bson_oid_compare_unsafe (oid1, oid2);
392             }
393              
394              
395             /*
396             *--------------------------------------------------------------------------
397             *
398             * bson_oid_equal --
399             *
400             * Compares for equality of @oid1 and @oid2. If they are equal, then
401             * true is returned, otherwise false.
402             *
403             * Returns:
404             * A boolean indicating the equality of @oid1 and @oid2.
405             *
406             * Side effects:
407             * None.
408             *
409             *--------------------------------------------------------------------------
410             */
411              
412             bool
413 0           bson_oid_equal (const bson_oid_t *oid1, /* IN */
414             const bson_oid_t *oid2) /* IN */
415             {
416 0 0         BSON_ASSERT (oid1);
417 0 0         BSON_ASSERT (oid2);
418              
419 0           return bson_oid_equal_unsafe (oid1, oid2);
420             }
421              
422              
423             /*
424             *--------------------------------------------------------------------------
425             *
426             * bson_oid_copy --
427             *
428             * Copies the contents of @src to @dst.
429             *
430             * Parameters:
431             * @src: A bson_oid_t to copy from.
432             * @dst: A bson_oid_t to copy to.
433             *
434             * Returns:
435             * None.
436             *
437             * Side effects:
438             * @dst will contain a copy of the data in @src.
439             *
440             *--------------------------------------------------------------------------
441             */
442              
443             void
444 0           bson_oid_copy (const bson_oid_t *src, /* IN */
445             bson_oid_t *dst) /* OUT */
446             {
447 0 0         BSON_ASSERT (src);
448 0 0         BSON_ASSERT (dst);
449              
450 0           bson_oid_copy_unsafe (src, dst);
451 0           }
452              
453              
454             /*
455             *--------------------------------------------------------------------------
456             *
457             * bson_oid_is_valid --
458             *
459             * Validates that @str is a valid OID string. @length MUST be 24, but
460             * is provided as a parameter to simplify calling code.
461             *
462             * Parameters:
463             * @str: A string to validate.
464             * @length: The length of @str.
465             *
466             * Returns:
467             * true if @str can be passed to bson_oid_init_from_string().
468             *
469             * Side effects:
470             * None.
471             *
472             *--------------------------------------------------------------------------
473             */
474              
475             bool
476 0           bson_oid_is_valid (const char *str, /* IN */
477             size_t length) /* IN */
478             {
479             size_t i;
480              
481 0 0         BSON_ASSERT (str);
482              
483 0 0         if ((length == 25) && (str [24] == '\0')) {
    0          
484 0           length = 24;
485             }
486              
487 0 0         if (length == 24) {
488 0 0         for (i = 0; i < length; i++) {
489 0 0         switch (str[i]) {
490             case '0': case '1': case '2': case '3': case '4': case '5': case '6':
491             case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd':
492             case 'e': case 'f':
493 0           break;
494             default:
495 0           return false;
496             }
497             }
498 0           return true;
499             }
500              
501 0           return false;
502             }