Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 1996, 1997 Theodore Ts'o.
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <string.h>
7 : : #include <stdint.h>
8 : : #include <stdlib.h>
9 : : #include <ctype.h>
10 : :
11 : : #include <rte_uuid.h>
12 : :
13 : : /* UUID packed form */
14 : : struct uuid {
15 : : uint32_t time_low;
16 : : uint16_t time_mid;
17 : : uint16_t time_hi_and_version;
18 : : uint16_t clock_seq;
19 : : uint8_t node[6];
20 : : };
21 : :
22 : 0 : static void uuid_pack(const struct uuid *uu, rte_uuid_t ptr)
23 : : {
24 : : uint32_t tmp;
25 : : uint8_t *out = ptr;
26 : :
27 : 0 : tmp = uu->time_low;
28 : 0 : out[3] = (uint8_t) tmp;
29 : 0 : tmp >>= 8;
30 : 0 : out[2] = (uint8_t) tmp;
31 : 0 : tmp >>= 8;
32 : 0 : out[1] = (uint8_t) tmp;
33 : 0 : tmp >>= 8;
34 : 0 : out[0] = (uint8_t) tmp;
35 : :
36 : 0 : tmp = uu->time_mid;
37 : 0 : out[5] = (uint8_t) tmp;
38 : 0 : tmp >>= 8;
39 : 0 : out[4] = (uint8_t) tmp;
40 : :
41 : 0 : tmp = uu->time_hi_and_version;
42 : 0 : out[7] = (uint8_t) tmp;
43 : 0 : tmp >>= 8;
44 : 0 : out[6] = (uint8_t) tmp;
45 : :
46 : 0 : tmp = uu->clock_seq;
47 : 0 : out[9] = (uint8_t) tmp;
48 : 0 : tmp >>= 8;
49 : 0 : out[8] = (uint8_t) tmp;
50 : :
51 : 0 : memcpy(out+10, uu->node, 6);
52 : 0 : }
53 : :
54 : 198 : static void uuid_unpack(const rte_uuid_t in, struct uuid *uu)
55 : : {
56 : : const uint8_t *ptr = in;
57 : : uint32_t tmp;
58 : :
59 : 198 : tmp = *ptr++;
60 : 198 : tmp = (tmp << 8) | *ptr++;
61 : 198 : tmp = (tmp << 8) | *ptr++;
62 : 198 : tmp = (tmp << 8) | *ptr++;
63 : 198 : uu->time_low = tmp;
64 : :
65 : 198 : tmp = *ptr++;
66 : 198 : tmp = (tmp << 8) | *ptr++;
67 : 198 : uu->time_mid = tmp;
68 : :
69 : 198 : tmp = *ptr++;
70 : 198 : tmp = (tmp << 8) | *ptr++;
71 : 198 : uu->time_hi_and_version = tmp;
72 : :
73 : 198 : tmp = *ptr++;
74 : 198 : tmp = (tmp << 8) | *ptr++;
75 : 198 : uu->clock_seq = tmp;
76 : :
77 : 198 : memcpy(uu->node, ptr, 6);
78 : 198 : }
79 : :
80 : 0 : bool rte_uuid_is_null(const rte_uuid_t uu)
81 : : {
82 : : const uint8_t *cp = uu;
83 : : int i;
84 : :
85 [ # # ]: 0 : for (i = 0; i < 16; i++)
86 [ # # ]: 0 : if (*cp++)
87 : : return false;
88 : : return true;
89 : : }
90 : :
91 : : /*
92 : : * rte_uuid_compare() - compare two UUIDs.
93 : : */
94 : 0 : int rte_uuid_compare(const rte_uuid_t uu1, const rte_uuid_t uu2)
95 : : {
96 : : struct uuid uuid1, uuid2;
97 : :
98 : 0 : uuid_unpack(uu1, &uuid1);
99 : 0 : uuid_unpack(uu2, &uuid2);
100 : :
101 : : #define UUCMP(u1, u2) \
102 : : do { if (u1 != u2) return (u1 < u2) ? -1 : 1; } while (0)
103 : :
104 [ # # # # ]: 0 : UUCMP(uuid1.time_low, uuid2.time_low);
105 [ # # # # ]: 0 : UUCMP(uuid1.time_mid, uuid2.time_mid);
106 [ # # # # ]: 0 : UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
107 [ # # # # ]: 0 : UUCMP(uuid1.clock_seq, uuid2.clock_seq);
108 : : #undef UUCMP
109 : :
110 : 0 : return memcmp(uuid1.node, uuid2.node, 6);
111 : : }
112 : :
113 : 15 : int rte_uuid_parse(const char *in, rte_uuid_t uu)
114 : : {
115 : : struct uuid uuid;
116 : : int i;
117 : : const char *cp;
118 : : char buf[3];
119 : :
120 [ - + ]: 15 : if (strlen(in) != 36)
121 : : return -1;
122 : :
123 [ # # ]: 0 : for (i = 0, cp = in; i <= 36; i++, cp++) {
124 [ # # # ]: 0 : if ((i == 8) || (i == 13) || (i == 18) ||
125 : : (i == 23)) {
126 [ # # ]: 0 : if (*cp == '-')
127 : 0 : continue;
128 : : else
129 : : return -1;
130 : : }
131 : : if (i == 36)
132 [ # # ]: 0 : if (*cp == 0)
133 : 0 : continue;
134 [ # # ]: 0 : if (!isxdigit(*cp))
135 : : return -1;
136 : : }
137 : :
138 : 0 : uuid.time_low = strtoul(in, NULL, 16);
139 : 0 : uuid.time_mid = strtoul(in+9, NULL, 16);
140 : 0 : uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
141 : 0 : uuid.clock_seq = strtoul(in+19, NULL, 16);
142 : 0 : cp = in+24;
143 : 0 : buf[2] = 0;
144 : :
145 [ # # ]: 0 : for (i = 0; i < 6; i++) {
146 : 0 : buf[0] = *cp++;
147 : 0 : buf[1] = *cp++;
148 : 0 : uuid.node[i] = strtoul(buf, NULL, 16);
149 : : }
150 : :
151 : 0 : uuid_pack(&uuid, uu);
152 : 0 : return 0;
153 : : }
154 : :
155 : 198 : void rte_uuid_unparse(const rte_uuid_t uu, char *out, size_t len)
156 : : {
157 : : struct uuid uuid;
158 : :
159 : 198 : uuid_unpack(uu, &uuid);
160 : :
161 : 198 : snprintf(out, len,
162 : : "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
163 : 198 : uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
164 : 198 : uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
165 : 198 : uuid.node[0], uuid.node[1], uuid.node[2],
166 : 198 : uuid.node[3], uuid.node[4], uuid.node[5]);
167 : 198 : }
|