A Discrete-Event Network Simulator
API
uuid.cc
Go to the documentation of this file.
1 
9 #include "uuid.h"
10 
11 #if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
12 #include <windows.h>
13 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
14 #include <uuid/uuid.h>
15 #endif
16 
17 namespace ns3 {
18 
20 namespace Internals {
21 
22 uint8_t unhex(char ch)
23 {
24  if ((ch >= '0') && (ch <= '9'))
25  return ch - '0';
26  else if ((ch >= 'a') && (ch <= 'f'))
27  return 10 + ch - 'a';
28  else if ((ch >= 'A') && (ch <= 'F'))
29  return 10 + ch - 'A';
30  else
31  return 255;
32 }
33 
34 } // namespace Internals
36 
37 UUID::UUID(const std::string& uuid)
38 {
39  char v1 = 0;
40  char v2 = 0;
41  bool pack = false;
42  size_t index = 0;
43 
44  // Parse UUID string
45  for (auto ch : uuid)
46  {
47  if ((ch == '-') || (ch == '{') || (ch == '}'))
48  continue;
49 
50  if (pack)
51  {
52  v2 = ch;
53  pack = false;
54  uint8_t ui1 = Internals::unhex(v1);
55  uint8_t ui2 = Internals::unhex(v2);
56  if ((ui1 > 15) || (ui2 > 15))
57  NS_FATAL_ERROR("Invalid UUID string: " + uuid);
58  _data[index++] = ui1 * 16 + ui2;
59  if (index >= 16)
60  break;
61  }
62  else
63  {
64  v1 = ch;
65  pack = true;
66  }
67  }
68 
69  // Fill remaining data with zeros
70  for (; index < 16; ++index)
71  _data[index++] = 0;
72 }
73 
74 std::string UUID::string() const
75 {
76  const char* digits = "0123456789abcdef";
77 
78  std::string result(36, '0');
79 
80  int index = 0;
81  for (auto value : _data)
82  {
83  result[index++] = digits[(value >> 4) & 0x0F];
84  result[index++] = digits[(value >> 0) & 0x0F];
85  if ((index == 8) || (index == 13) || (index == 18) || (index == 23))
86  result[index++] = '-';
87  }
88 
89  return result;
90 }
91 
93 {
94  UUID result;
95 #if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
96  ::UUID uuid;
97  if (UuidCreateSequential(&uuid) != RPC_S_OK)
98  NS_FATAL_ERROR("Cannot generate sequential UUID!");
99 
100  result._data[0] = (uuid.Data1 >> 24) & 0xFF;
101  result._data[1] = (uuid.Data1 >> 16) & 0xFF;
102  result._data[2] = (uuid.Data1 >> 8) & 0xFF;
103  result._data[3] = (uuid.Data1 >> 0) & 0xFF;
104 
105  result._data[4] = (uuid.Data2 >> 8) & 0xFF;
106  result._data[5] = (uuid.Data2 >> 0) & 0xFF;
107 
108  result._data[6] = (uuid.Data3 >> 8) & 0xFF;
109  result._data[7] = (uuid.Data3 >> 0) & 0xFF;
110 
111  result._data[8] = uuid.Data4[0];
112  result._data[9] = uuid.Data4[1];
113 
114  result._data[10] = uuid.Data4[2];
115  result._data[11] = uuid.Data4[3];
116  result._data[12] = uuid.Data4[4];
117  result._data[13] = uuid.Data4[5];
118  result._data[14] = uuid.Data4[6];
119  result._data[15] = uuid.Data4[7];
120 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
121  uuid_t uuid;
122  uuid_generate_time(uuid);
123 
124  result._data[0] = uuid[0];
125  result._data[1] = uuid[1];
126  result._data[2] = uuid[2];
127  result._data[3] = uuid[3];
128 
129  result._data[4] = uuid[4];
130  result._data[5] = uuid[5];
131 
132  result._data[6] = uuid[6];
133  result._data[7] = uuid[7];
134 
135  result._data[8] = uuid[8];
136  result._data[9] = uuid[9];
137 
138  result._data[10] = uuid[10];
139  result._data[11] = uuid[11];
140  result._data[12] = uuid[12];
141  result._data[13] = uuid[13];
142  result._data[14] = uuid[14];
143  result._data[15] = uuid[15];
144 #endif
145  return result;
146 }
147 
149 {
150  UUID result;
151 #if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
152  ::UUID uuid;
153  if (UuidCreate(&uuid) != RPC_S_OK)
154  NS_FATAL_ERROR("Cannot generate random UUID!");
155 
156  result._data[0] = (uuid.Data1 >> 24) & 0xFF;
157  result._data[1] = (uuid.Data1 >> 16) & 0xFF;
158  result._data[2] = (uuid.Data1 >> 8) & 0xFF;
159  result._data[3] = (uuid.Data1 >> 0) & 0xFF;
160 
161  result._data[4] = (uuid.Data2 >> 8) & 0xFF;
162  result._data[5] = (uuid.Data2 >> 0) & 0xFF;
163 
164  result._data[6] = (uuid.Data3 >> 8) & 0xFF;
165  result._data[7] = (uuid.Data3 >> 0) & 0xFF;
166 
167  result._data[8] = uuid.Data4[0];
168  result._data[9] = uuid.Data4[1];
169 
170  result._data[10] = uuid.Data4[2];
171  result._data[11] = uuid.Data4[3];
172  result._data[12] = uuid.Data4[4];
173  result._data[13] = uuid.Data4[5];
174  result._data[14] = uuid.Data4[6];
175  result._data[15] = uuid.Data4[7];
176 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
177  uuid_t uuid;
178  uuid_generate_random(uuid);
179 
180  result._data[0] = uuid[0];
181  result._data[1] = uuid[1];
182  result._data[2] = uuid[2];
183  result._data[3] = uuid[3];
184 
185  result._data[4] = uuid[4];
186  result._data[5] = uuid[5];
187 
188  result._data[6] = uuid[6];
189  result._data[7] = uuid[7];
190 
191  result._data[8] = uuid[8];
192  result._data[9] = uuid[9];
193 
194  result._data[10] = uuid[10];
195  result._data[11] = uuid[11];
196  result._data[12] = uuid[12];
197  result._data[13] = uuid[13];
198  result._data[14] = uuid[14];
199  result._data[15] = uuid[15];
200 #endif
201  return result;
202 }
203 
204 inline void
205 UUID::swap(UUID& uuid) noexcept
206 {
207  using std::swap;
208  swap(_data, uuid._data);
209 }
210 
211 inline void
212 swap(UUID& uuid1, UUID& uuid2) noexcept
213 {
214  uuid1.swap(uuid2);
215 }
216 
217 
218 } // namespace ns3
219 
220 namespace std {
221 
222 template <>
223 struct hash<ns3::UUID>
224 {
226  typedef size_t result_type;
227 
228  result_type operator() (const argument_type& value) const
229  {
230  result_type result = 17;
231  std::hash<uint8_t> hasher;
232  for (size_t i = 0; i < value.data().size(); ++i)
233  result = result * 31 + hasher(value.data()[i]);
234  return result;
235  }
236 };
237 
238 } // namespace std
239 
240 
Universally unique identifier (UUID)
Definition: uuid.h:35
UUID()
Default constructor.
Definition: uuid.h:38
void swap(UUID &uuid) noexcept
Swap two instances.
Definition: uuid.cc:205
static UUID Random()
Generate random UUID4 (randomly or pseudo-randomly generated version)
Definition: uuid.cc:148
static UUID Sequential()
Generate sequential UUID1 (time based version)
Definition: uuid.cc:92
std::string string() const
Get string from the current UUID in format "00000000-0000-0000-0000-000000000000".
Definition: uuid.cc:74
std::array< uint8_t, 16 > _data
Definition: uuid.h:101
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:4680
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void swap(UUID &uuid1, UUID &uuid2) noexcept
Definition: uuid.cc:212
ns3::UUID argument_type
Definition: uuid.cc:225
Universally unique identifier (UUID) definition.