annotate libphobos/src/std/uuid.d @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 * A $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, UUID), or
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, Universally unique identifier),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * is intended to uniquely identify information in a distributed environment
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * without significant central coordination. It can be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * used to tag objects with very short lifetimes, or to reliably identify very
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * persistent objects across a network.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 $(SCRIPT inhibitQuickIndex = 1;)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 $(DIVC quickindex,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 $(BOOKTABLE ,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 $(TR $(TH Category) $(TH Functions)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 $(TR $(TDNW Parsing UUIDs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 $(TD $(MYREF parseUUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 $(MYREF UUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 $(MYREF UUIDParsingException)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 $(MYREF uuidRegex)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 $(TR $(TDNW Generating UUIDs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 $(TD $(MYREF sha1UUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 $(MYREF randomUUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 $(MYREF md5UUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 $(TR $(TDNW Using UUIDs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 $(TD $(MYREF2 UUID.uuidVersion, uuidVersion)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 $(MYREF2 UUID.variant, variant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 $(MYREF2 UUID.toString, toString)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 $(MYREF2 UUID.data, data)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 $(MYREF2 UUID.swap, swap)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 $(MYREF2 UUID.opEquals, opEquals)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 $(MYREF2 UUID.opCmp, opCmp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 $(MYREF2 UUID.toHash, toHash)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 $(TR $(TDNW UUID namespaces)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 $(TD $(MYREF dnsNamespace)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 $(MYREF urlNamespace)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 $(MYREF oidNamespace)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 $(MYREF x500Namespace)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 * UUIDs have many applications. Some examples follow: Databases may use UUIDs to identify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 * rows or records in order to ensure that they are unique across different
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 * databases, or for publication/subscription services. Network messages may be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 * identified with a UUID to ensure that different parts of a message are put back together
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 * again. Distributed computing may use UUIDs to identify a remote procedure call.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 * Transactions and classes involved in serialization may be identified by UUIDs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 * Microsoft's component object model (COM) uses UUIDs to distinguish different software
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 * component interfaces. UUIDs are inserted into documents from Microsoft Office programs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 * UUIDs identify audio or video streams in the Advanced Systems Format (ASF). UUIDs are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 * also a basis for OIDs (object identifiers), and URNs (uniform resource name).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 * An attractive feature of UUIDs when compared to alternatives is their relative small size,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 * of 128 bits, or 16 bytes. Another is that the creation of UUIDs does not require
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 * a centralized authority.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 * When UUIDs are generated by one of the defined mechanisms, they are either guaranteed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 * to be unique, different from all other generated UUIDs (that is, it has never been
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 * generated before and it will never be generated again), or it is extremely likely
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 * to be unique (depending on the mechanism).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 * For efficiency, UUID is implemented as a struct. UUIDs are therefore empty if not explicitly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 * initialized. An UUID is empty if $(MYREF3 UUID.empty, empty) is true. Empty UUIDs are equal to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 * $(D UUID.init), which is a UUID with all 16 bytes set to 0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 * Use UUID's constructors or the UUID generator functions to get an initialized UUID.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 * This is a port of $(LINK2 http://www.boost.org/doc/libs/1_42_0/libs/uuid/uuid.html,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 * boost._uuid) from the Boost project with some minor additions and API
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 * changes for a more D-like API.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 * Standards:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 * $(LINK2 http://www.ietf.org/rfc/rfc4122.txt, RFC 4122)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 * See_Also:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 * $(LINK http://en.wikipedia.org/wiki/Universally_unique_identifier)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 * Copyright: Copyright Johannes Pfau 2011 - .
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 * Authors: Johannes Pfau
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 * Source: $(PHOBOSSRC std/_uuid.d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 * Macros:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 * MYREF2 = <a href="#$2">$(TT $1)</a>&nbsp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 * MYREF3 = <a href="#$2">$(D $1)</a>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 /* Copyright Johannes Pfau 2011 - 2012.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 * Distributed under the Boost Software License, Version 1.0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 * (See accompanying file LICENSE_1_0.txt or copy at
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 * http://www.boost.org/LICENSE_1_0.txt)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 module std.uuid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 import std.uuid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 UUID[] ids;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 ids ~= randomUUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 ids ~= md5UUID("test.name.123");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 ids ~= sha1UUID("test.name.123");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 foreach (entry; ids)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 assert(entry.variant == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 assert(ids[0].uuidVersion == UUID.Version.randomNumberBased);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 assert(ids[1].toString() == "22390768-cced-325f-8f0f-cfeaa19d0ccd");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 assert(ids[1].data == [34, 57, 7, 104, 204, 237, 50, 95, 143, 15, 207,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 234, 161, 157, 12, 205]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 UUID id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 assert(id.empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 import std.range.primitives;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 import std.traits;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 public struct UUID
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 import std.meta : AliasSeq, allSatisfy;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 alias skipSeq = AliasSeq!(8, 13, 18, 23);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 alias byteSeq = AliasSeq!(0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 @safe pure nothrow @nogc Char toChar(Char)(size_t i) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 if (i <= 9)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 return cast(Char)('0' + i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 return cast(Char)('a' + (i-10));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 @safe pure nothrow unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 assert(UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 179, 189, 251, 70]).toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 // Reinterpret the UUID as an array of some other primitive.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 @trusted ref T[16 / T.sizeof] asArrayOf(T)() return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 if (isIntegral!T)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 return *cast(typeof(return)*)&data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 * RFC 4122 defines different internal data layouts for UUIDs. These are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 * the UUID formats supported by this module. It's
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 * possible to read, compare and use all these Variants, but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 * UUIDs generated by this module will always be in rfc4122 format.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 * Note: Do not confuse this with $(REF _Variant, std,_variant).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 enum Variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 ncs, /// NCS backward compatibility
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 rfc4122, /// Defined in RFC 4122 document
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 microsoft, /// Microsoft Corporation backward compatibility
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 future ///Reserved for future use
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 * RFC 4122 defines different UUID versions. The version shows
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 * how a UUID was generated, e.g. a version 4 UUID was generated
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 * from a random number, a version 3 UUID from an MD5 hash of a name.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 * All of these UUID versions can be read and processed by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 * $(D std.uuid), but only version 3, 4 and 5 UUIDs can be generated.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 enum Version
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 ///Unknown version
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 unknown = -1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 ///Version 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 timeBased = 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 ///Version 2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 dceSecurity = 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 ///Version 3 (Name based + MD5)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 nameBasedMD5 = 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 ///Version 4 (Random)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 randomNumberBased = 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 ///Version 5 (Name based + SHA-1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 nameBasedSHA1 = 5
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 union
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 * It is sometimes useful to get or set the 16 bytes of a UUID
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 * directly.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 * UUID uses a 16-ubyte representation for the UUID data.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 * RFC 4122 defines a UUID as a special structure in big-endian
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 * format. These 16-ubytes always equal the big-endian structure
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 * defined in RFC 4122.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 * Example:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 * -----------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 * auto rawData = uuid.data; //get data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 * rawData[0] = 1; //modify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 * uuid.data = rawData; //set data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 * uuid.data[1] = 2; //modify directly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 * -----------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 ubyte[16] data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 private ulong[2] ulongs;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 static if (size_t.sizeof == 4)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 private uint[4] uints;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 /*
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 * We could use a union here to also provide access to the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 * fields specified in RFC 4122, but as we never have to access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 * those (only necessary for version 1 (and maybe 2) UUIDs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 * that is not needed right now.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 UUID tmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 tmp.data = cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,12,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 13,14,15];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 12,13,14,15]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 tmp.data[2] = 3;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 assert(tmp.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 12,13,14,15]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 auto tmp2 = cast(immutable UUID) tmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 assert(tmp2.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 12,13,14,15]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 * Construct a UUID struct from the 16 byte representation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 * of a UUID.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 @safe pure nothrow @nogc this(ref in ubyte[16] uuidData)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 data = uuidData;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 /// ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 @safe pure nothrow @nogc this(in ubyte[16] uuidData)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 data = uuidData;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 enum ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 auto uuid = UUID(data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 enum ctfe = UUID(data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 assert(uuid.data == data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 assert(ctfe.data == data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 * Construct a UUID struct from the 16 byte representation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 * of a UUID. Variadic constructor to allow a simpler syntax, see examples.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 * You need to pass exactly 16 ubytes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 @safe pure this(T...)(T uuidData)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 if (uuidData.length == 16 && allSatisfy!(isIntegral, T))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 foreach (idx, it; uuidData)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 this.data[idx] = to!ubyte(it);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 auto tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 12,13,14,15]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 UUID tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 12,13,14,15]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 enum UUID ctfeID = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 assert(ctfeID == tmp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 //Too few arguments
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 //Too many arguments
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1))));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 * <a name="UUID(string)"></a>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 * Parse a UUID from its canonical string form. An UUID in its
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 * canonical form looks like this: 8ab3060e-2cba-4f23-b74c-b52db3bdfb46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 * Throws:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 * $(LREF UUIDParsingException) if the input is invalid
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 * CTFE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 * This function is supported in CTFE code. Note that error messages
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 * caused by a malformed UUID parsed at compile time can be cryptic,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 * but errors are detected and reported at
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 * compile time.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 * This is a strict parser. It only accepts the pattern above.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 * It doesn't support any leading or trailing characters. It only
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 * accepts characters used for hex numbers and the string must have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 * hyphens exactly like above.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 * For a less strict parser, see $(LREF parseUUID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 this(T)(in T[] uuid) if (isSomeChar!(Unqual!T))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 import std.conv : to, parse;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 if (uuid.length < 36)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 throw new UUIDParsingException(to!string(uuid), 0,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 UUIDParsingException.Reason.tooLittle, "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 if (uuid.length > 36)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 throw new UUIDParsingException(to!string(uuid), 35, UUIDParsingException.Reason.tooMuch,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 "Input is too long, need exactly 36 characters");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 static immutable skipInd = [skipSeq];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 foreach (pos; skipInd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 if (uuid[pos] != '-')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 throw new UUIDParsingException(to!string(uuid), pos,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 UUIDParsingException.Reason.invalidChar, "Expected '-'");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 ubyte[16] data2; //ctfe bug
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 uint pos = void;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 foreach (i, p; byteSeq)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 enum uint s = 'a'-10-'0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 uint h = uuid[p];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 uint l = uuid[p+1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 pos = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 if (h < '0') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 if (l < '0') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 if (h > '9')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 h |= 0x20; //poorman's tolower
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 if (h < 'a') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 if (h > 'f') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 h -= s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 if (l > '9')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 l |= 0x20; //poorman's tolower
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 if (l < 'a') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 if (l > 'f') goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 l -= s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 h -= '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 l -= '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 data2[i] = cast(ubyte)((h << 4) ^ l);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 this.data = data2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 Lerr: throw new UUIDParsingException(to!string(uuid), pos,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 UUIDParsingException.Reason.invalidChar, "Couldn't parse ubyte");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 auto id = UUID("8AB3060E-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 181, 45, 179, 189, 251, 70]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 assert(id.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 //Can also be used in CTFE, for example as UUID literals:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 enum ctfeID = UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 //here parsing is done at compile time, no runtime overhead!
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 import std.exception;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 import std.meta;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 wchar[], const(wchar)[], immutable(wchar)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 dchar[], const(dchar)[], immutable(dchar)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 immutable(char[]), immutable(wchar[]), immutable(dchar[])))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 //Test valid, working cases
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 assert(UUID(to!S("00000000-0000-0000-0000-000000000000")).empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 auto id = UUID(to!S("8AB3060E-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 181, 45, 179, 189, 251, 70]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 assert(id.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 enum UUID ctfe = UUID(to!S("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 assert(ctfe == id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 assert(UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a")).data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 //Test too short UUIDS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 auto except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886")));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 assert(except && except.reason == UUIDParsingException.Reason.tooLittle);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 //Test too long UUIDS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886aa")));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 assert(except && except.reason == UUIDParsingException.Reason.tooMuch);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 //Test dashes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 UUID(to!S("8ab3060e2cba-4f23-b74c-b52db3bdfb-46")));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 //Test dashes 2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 UUID(to!S("8ab3-060e2cba-4f23-b74c-b52db3bdfb46")));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 //Test invalid characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 //make sure 36 characters in total or we'll get a 'tooMuch' reason
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 UUID(to!S("{8ab3060e-2cba-4f23-b74c-b52db3bdf6}")));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 //Boost test
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 assert(UUID(to!S("01234567-89ab-cdef-0123-456789ABCDEF"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 == UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 * Returns true if and only if the UUID is equal
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 * to {00000000-0000-0000-0000-000000000000}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 @trusted pure nothrow @nogc @property bool empty() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 if (__ctfe)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 return data == (ubyte[16]).init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 auto p = cast(const(size_t*))data.ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 static if (size_t.sizeof == 4)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 return p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 else static if (size_t.sizeof == 8)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 return p[0] == 0 && p[1] == 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 static assert(false, "nonsense, it's not 32 or 64 bit");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 UUID id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 assert(id.empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 id = UUID("00000000-0000-0000-0000-000000000001");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 assert(!id.empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 ubyte[16] getData(size_t i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 ubyte[16] data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 data[i] = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 return data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 for (size_t i = 0; i < 16; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 assert(!UUID(getData(i)).empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 enum ctfeEmpty = UUID.init.empty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 assert(ctfeEmpty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 bool ctfeTest()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 for (size_t i = 0; i < 16; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 auto ctfeEmpty2 = UUID(getData(i)).empty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 assert(!ctfeEmpty2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 enum res = ctfeTest();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 * RFC 4122 defines different internal data layouts for UUIDs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 * Returns the format used by this UUID.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 * Note: Do not confuse this with $(REF _Variant, std,_variant).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 * The type of this property is $(MYREF3 std.uuid.UUID.Variant, _Variant).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 * See_Also:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 * $(MYREF3 UUID.Variant, Variant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 @safe pure nothrow @nogc @property Variant variant() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 //variant is stored in octet 7
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 //which is index 8, since indexes count backwards
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 immutable octet7 = data[8]; //octet 7 is array index 8
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 if ((octet7 & 0x80) == 0x00) //0b0xxxxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 return Variant.ncs;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 else if ((octet7 & 0xC0) == 0x80) //0b10xxxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 return Variant.rfc4122;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 else if ((octet7 & 0xE0) == 0xC0) //0b110xxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 return Variant.microsoft;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 //assert((octet7 & 0xE0) == 0xE0, "Unknown UUID variant!") //0b111xxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 return Variant.future;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 assert(UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46").variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 @system pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 // @system due to Variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 Variant[ubyte] tests = cast(Variant[ubyte])[0x00 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 0x10 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 0x20 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 0x30 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 0x40 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 0x50 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 0x60 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 0x70 : Variant.ncs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 0x80 : Variant.rfc4122,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 0x90 : Variant.rfc4122,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 0xa0 : Variant.rfc4122,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 0xb0 : Variant.rfc4122,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 0xc0 : Variant.microsoft,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 0xd0 : Variant.microsoft,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 0xe0 : Variant.future,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 0xf0 : Variant.future];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 foreach (key, value; tests)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 UUID u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 u.data[8] = key;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 assert(u.variant == value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 * RFC 4122 defines different UUID versions. The version shows
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 * how a UUID was generated, e.g. a version 4 UUID was generated
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 * from a random number, a version 3 UUID from an MD5 hash of a name.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 * Returns the version used by this UUID.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 * See_Also:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 * $(MYREF3 UUID.Version, Version)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 @safe pure nothrow @nogc @property Version uuidVersion() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 //version is stored in octet 9
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 //which is index 6, since indexes count backwards
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 immutable octet9 = data[6];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 if ((octet9 & 0xF0) == 0x10)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 return Version.timeBased;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 else if ((octet9 & 0xF0) == 0x20)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 return Version.dceSecurity;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 else if ((octet9 & 0xF0) == 0x30)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 return Version.nameBasedMD5;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 else if ((octet9 & 0xF0) == 0x40)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 return Version.randomNumberBased;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 else if ((octet9 & 0xF0) == 0x50)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 return Version.nameBasedSHA1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 return Version.unknown;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 assert(UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46").uuidVersion
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 == UUID.Version.randomNumberBased);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 @system unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 // @system due to cast
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 Version[ubyte] tests = cast(Version[ubyte]) [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 0x00 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 0x10 : UUID.Version.timeBased,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 0x20 : UUID.Version.dceSecurity,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 0x30 : UUID.Version.nameBasedMD5,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 0x40 : UUID.Version.randomNumberBased,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 0x50 : UUID.Version.nameBasedSHA1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 0x60 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 0x70 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 0x80 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 0x90 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 0xa0 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 0xb0 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 0xc0 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 0xd0 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 0xe0 : UUID.Version.unknown,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 0xf0 : UUID.Version.unknown];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 foreach (key, value; tests)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 UUID u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 u.data[6] = key;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 assert(u.uuidVersion == value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 * Swap the data of this UUID with the data of rhs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 @safe pure nothrow @nogc void swap(ref UUID rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 immutable bck = data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 data = rhs.data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 rhs.data = bck;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 immutable ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 UUID u1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 UUID u2 = UUID(data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 u1.swap(u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 assert(u1 == UUID(data));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 assert(u2 == UUID.init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 * All of the standard numeric operators are defined for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 * the UUID struct.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 @safe pure nothrow @nogc bool opEquals(in UUID s) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 //compare UUIDs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 assert(UUID("00000000-0000-0000-0000-000000000000") == UUID.init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 //UUIDs in associative arrays:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 int[UUID] test = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0") : 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a") : 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1") : 3];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 assert(test[UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")] == 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 //UUIDS can be sorted:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 import std.algorithm;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 UUID[] ids = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 sort(ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 @safe pure nothrow @nogc bool opEquals(ref in UUID s) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 @safe pure nothrow @nogc int opCmp(in UUID s) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 import std.algorithm.comparison : cmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 return cmp(this.data[], s.data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 @safe pure nothrow @nogc int opCmp(ref in UUID s) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 import std.algorithm.comparison : cmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 return cmp(this.data[], s.data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 @safe pure nothrow @nogc UUID opAssign(in UUID s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 ulongs[0] = s.ulongs[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 ulongs[1] = s.ulongs[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 return this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 @safe pure nothrow @nogc UUID opAssign(ref in UUID s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 ulongs[0] = s.ulongs[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 ulongs[1] = s.ulongs[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 return this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 * ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 //MurmurHash2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 @safe pure nothrow @nogc size_t toHash() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 static if (size_t.sizeof == 4)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 enum uint m = 0x5bd1e995;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 enum uint n = 16;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 enum uint r = 24;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 uint h = n;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 uint k = uints[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 k = uints[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 k = uints[2];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 k = uints[3];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 enum ulong m = 0xc6a4a7935bd1e995UL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 enum ulong n = m * 16;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 enum uint r = 47;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 ulong h = n;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 ulong k = ulongs[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 k = ulongs[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 k ^= k >> r;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 k *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 h ^= k;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 h *= m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 return h;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 assert(UUID("00000000-0000-0000-0000-000000000000") == UUID.init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 int[UUID] test = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0") : 1,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a") : 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1") : 3];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 assert(test[UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")] == 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 import std.algorithm;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 UUID[] ids = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 sort(ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 auto id2 = ids.dup;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 ids = [UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 sort(ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 assert(ids == id2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 //test comparsion
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 UUID u1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 UUID u2 = UUID(cast(ubyte[16])[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 UUID u3 = UUID(cast(ubyte[16])[255,255,255,255,255,255,255,255,255,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 255,255,255,255,255,255,255]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 assert(u1 == u1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 assert(u1 != u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 assert(u1 < u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 assert(u2 < u3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 assert(u1 <= u1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 assert(u1 <= u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 assert(u2 <= u3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 assert(u2 >= u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 assert(u3 >= u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 assert(u3 >= u3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 assert(u2 >= u1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 assert(u3 >= u1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 // test hash
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 assert(u1.toHash() != u2.toHash());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 assert(u2.toHash() != u3.toHash());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 assert(u3.toHash() != u1.toHash());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 * Write the UUID into `sink` as an ASCII string in the canonical form,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 * which is 36 characters in the form "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 * sink = OutputRange or writeable array at least 36 entries long
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 void toString(Writer)(scope Writer sink) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 char[36] result = void;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 foreach (pos; skipSeq)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 result[pos] = '-';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 foreach (i, pos; byteSeq)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 const uint entry = this.data[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 const uint hi = entry >> 4;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 result[pos ] = toChar!char(hi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 const uint lo = (entry) & 0x0F;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 result[pos+1] = toChar!char(lo);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 foreach (i, c; result)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 static if (__traits(compiles, put(sink, c)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 put(sink, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 sink[i] = cast(typeof(sink[i]))c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 * Return the UUID as a string in the canonical form.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 @trusted pure nothrow string toString() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 import std.exception : assumeUnique;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 auto result = new char[36];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 toString(result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 return result.assumeUnique;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 immutable str = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 auto id = UUID(str);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 assert(id.toString() == str);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911 @safe pure nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 import std.meta : AliasSeq;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 foreach (Char; AliasSeq!(char, wchar, dchar))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 alias String = immutable(Char)[];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 //CTFE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 enum String s = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 enum id = UUID(s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 static if (is(Char == char))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 enum p = id.toString();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 static assert(s == p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 //nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 Char[36] str;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 id.toString(str[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 assert(str == s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 @system pure nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 // @system due to cast
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 import std.encoding : Char = AsciiChar;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 enum utfstr = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 alias String = immutable(Char)[];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 enum String s = cast(String) utfstr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 enum id = UUID(utfstr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 //nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 Char[36] str;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 id.toString(str[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 assert(str == s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 auto u1 = UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 35, 183, 76, 181, 45, 179, 189, 251, 70]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 assert(u1.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 u1 = UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 assert(u1.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 char[] buf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 void sink(const(char)[] data)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 buf ~= data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 u1.toString(&sink);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 assert(buf == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 * This function generates a name based (Version 3) UUID from a namespace UUID and a name.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 * If no namespace UUID was passed, the empty UUID $(D UUID.init) is used.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 * The default namespaces ($(LREF dnsNamespace), ...) defined by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 * this module should be used when appropriate.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 * RFC 4122 recommends to use Version 5 UUIDs (SHA-1) instead of Version 3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 * UUIDs (MD5) for new applications.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 * CTFE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 * CTFE is not supported.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 * RFC 4122 isn't very clear on how UUIDs should be generated from names.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 * It is possible that different implementations return different UUIDs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 * for the same input, so be warned. The implementation for UTF-8 strings
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 * and byte arrays used by $(D std.uuid) is compatible with Boost's implementation.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 * $(D std.uuid) guarantees that the same input to this function will generate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 * the same output at any time, on any system (this especially means endianness
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 * doesn't matter).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 * This function does not provide overloads for wstring and dstring, as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 * there's no clear answer on how that should be implemented. It could be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 * argued, that string, wstring and dstring input should have the same output,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 * but that wouldn't be compatible with Boost, which generates different output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 * for strings and wstrings. It's always possible to pass wstrings and dstrings
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 * by using the ubyte[] function overload (but be aware of endianness issues!).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 @safe pure nothrow @nogc UUID md5UUID(const(char[]) name, const UUID namespace = UUID.init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 return md5UUID(cast(const(ubyte[]))name, namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 /// ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 @safe pure nothrow @nogc UUID md5UUID(const(ubyte[]) data, const UUID namespace = UUID.init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 import std.digest.md : MD5;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 MD5 hash;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 hash.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 /*
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 * NOTE: RFC 4122 says namespace should be converted to big-endian.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 * We always keep the UUID data in big-endian representation, so
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 * that's fine
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 hash.put(namespace.data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 hash.put(data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 UUID u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 u.data = hash.finish();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 //set variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021 //must be 0b10xxxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 u.data[8] &= 0b10111111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 u.data[8] |= 0b10000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 //set version
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 //must be 0b0011xxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 u.data[6] &= 0b00111111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 u.data[6] |= 0b00110000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 return u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 //Use default UUID.init namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 auto simpleID = md5UUID("test.uuid.any.string");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 //use a name-based id as namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 auto namespace = md5UUID("my.app");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 auto id = md5UUID("some-description", namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046 auto simpleID = md5UUID("test.uuid.any.string");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 assert(simpleID.data == cast(ubyte[16])[126, 206, 86, 72, 29, 233, 62, 213, 178, 139, 198, 136,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 188, 135, 153, 123]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 auto namespace = md5UUID("my.app");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 auto id = md5UUID("some-description", namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 assert(id.data == cast(ubyte[16])[166, 138, 167, 79, 48, 219, 55, 166, 170, 103, 39, 73, 216,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 150, 144, 164]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 auto constTest = md5UUID(cast(const(char)[])"test");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 constTest = md5UUID(cast(const(char[]))"test");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 char[] mutable = "test".dup;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 id = md5UUID(mutable, namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 id = md5UUID(data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 assert(id.data == cast(ubyte[16])[16, 50, 29, 247, 243, 185, 61, 178, 157, 100, 253, 236, 73,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 76, 51, 47]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 assert(id.variant == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 assert(id.uuidVersion == UUID.Version.nameBasedMD5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 auto correct = UUID("3d813cbb-47fb-32ba-91df-831e1593ac29");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 auto u = md5UUID("www.widgets.com", dnsNamespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 //enum ctfeId = md5UUID("www.widgets.com", dnsNamespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 //assert(ctfeId == u);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 assert(u == correct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074 assert(u.variant == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 assert(u.uuidVersion == UUID.Version.nameBasedMD5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079 * This function generates a name based (Version 5) UUID from a namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 * UUID and a name.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 * If no namespace UUID was passed, the empty UUID $(D UUID.init) is used.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 * The default namespaces ($(LREF dnsNamespace), ...) defined by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 * this module should be used when appropriate.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 * CTFE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 * CTFE is not supported.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 * RFC 4122 isn't very clear on how UUIDs should be generated from names.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 * It is possible that different implementations return different UUIDs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 * for the same input, so be warned. The implementation for UTF-8 strings
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 * and byte arrays used by $(D std.uuid) is compatible with Boost's implementation.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 * $(D std.uuid) guarantees that the same input to this function will generate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 * the same output at any time, on any system (this especially means endianness
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 * doesn't matter).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 * This function does not provide overloads for wstring and dstring, as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 * there's no clear answer on how that should be implemented. It could be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 * argued, that string, wstring and dstring input should have the same output,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 * but that wouldn't be compatible with Boost, which generates different output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 * for strings and wstrings. It's always possible to pass wstrings and dstrings
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 * by using the ubyte[] function overload (but be aware of endianness issues!).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 @safe pure nothrow @nogc UUID sha1UUID(in char[] name, const UUID namespace = UUID.init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109 return sha1UUID(cast(const(ubyte[]))name, namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112 /// ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 @safe pure nothrow @nogc UUID sha1UUID(in ubyte[] data, const UUID namespace = UUID.init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 import std.digest.sha : SHA1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 SHA1 sha;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 sha.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 /*
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121 * NOTE: RFC 4122 says namespace should be converted to big-endian.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122 * We always keep the UUID data in big-endian representation, so
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 * that's fine
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125 sha.put(namespace.data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 sha.put(data[]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 auto hash = sha.finish();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129 auto u = UUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 u.data[] = hash[0 .. 16];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132 //set variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 //must be 0b10xxxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 u.data[8] &= 0b10111111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 u.data[8] |= 0b10000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 //set version
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138 //must be 0b0101xxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 u.data[6] &= 0b01011111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 u.data[6] |= 0b01010000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 return u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 //Use default UUID.init namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 auto simpleID = sha1UUID("test.uuid.any.string");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 //use a name-based id as namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 auto namespace = sha1UUID("my.app");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 auto id = sha1UUID("some-description", namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 auto simpleID = sha1UUID("test.uuid.any.string");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 assert(simpleID.data == cast(ubyte[16])[16, 209, 239, 61, 99, 12, 94, 70, 159, 79, 255, 250,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 131, 79, 14, 147]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 auto namespace = sha1UUID("my.app");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 auto id = sha1UUID("some-description", namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 assert(id.data == cast(ubyte[16])[225, 94, 195, 219, 126, 75, 83, 71, 157, 52, 247, 43, 238, 248,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 148, 46]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 auto constTest = sha1UUID(cast(const(char)[])"test");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 constTest = sha1UUID(cast(const(char[]))"test");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 char[] mutable = "test".dup;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 id = sha1UUID(mutable, namespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172 const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 id = sha1UUID(data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 assert(id.data == cast(ubyte[16])[60, 65, 92, 240, 96, 46, 95, 238, 149, 100, 12, 64, 199, 194,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 243, 12]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 auto correct = UUID("21f7f8de-8051-5b89-8680-0195ef798b6a");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 auto u = sha1UUID("www.widgets.com", dnsNamespace);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 assert(u == correct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 assert(u.variant == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 assert(u.uuidVersion == UUID.Version.nameBasedSHA1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 * This function generates a random number based UUID from a random
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 * number generator.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 * This function is not supported at compile time.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192 * randomGen = uniform RNG
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193 * See_Also: $(REF isUniformRNG, std,random)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 @safe UUID randomUUID()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 import std.random : rndGen;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 return randomUUID(rndGen);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 /// ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 UUID randomUUID(RNG)(ref RNG randomGen)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203 if (isInputRange!RNG && isIntegral!(ElementType!RNG))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 import std.random : isUniformRNG;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 static assert(isUniformRNG!RNG, "randomGen must be a uniform RNG");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 alias E = ElementEncodingType!RNG;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209 enum size_t elemSize = E.sizeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 static assert(elemSize <= 16);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 static assert(16 % elemSize == 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 UUID u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 foreach (ref E e ; u.asArrayOf!E())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 e = randomGen.front;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 randomGen.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220 //set variant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 //must be 0b10xxxxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222 u.data[8] &= 0b10111111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 u.data[8] |= 0b10000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 //set version
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 //must be 0b0100xxxx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 u.data[6] &= 0b01001111;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228 u.data[6] |= 0b01000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 return u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 import std.random : Xorshift192, unpredictableSeed;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 //simple call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 auto uuid = randomUUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 //provide a custom RNG. Must be seeded manually.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 Xorshift192 gen;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 gen.seed(unpredictableSeed);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 auto uuid3 = randomUUID(gen);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248 /*
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 * Original boost.uuid used Mt19937, we don't want
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250 * to use anything worse than that. If Random is changed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 * to something else, this assert and the randomUUID function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 * have to be updated.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 import std.random : rndGen, Mt19937;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 static assert(is(typeof(rndGen) == Mt19937));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 import std.random : Xorshift192, unpredictableSeed;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 //simple call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 auto uuid = randomUUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 //provide a custom RNG. Must be seeded manually.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267 Xorshift192 gen;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 gen.seed(unpredictableSeed);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 auto uuid3 = randomUUID(gen);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 auto u1 = randomUUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 auto u2 = randomUUID();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273 assert(u1 != u2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274 assert(u1.variant == UUID.Variant.rfc4122);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 assert(u1.uuidVersion == UUID.Version.randomNumberBased);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 * This is a less strict parser compared to the parser used in the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 * UUID constructor. It enforces the following rules:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 * $(UL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 * $(LI hex numbers are always two hexdigits([0-9a-fA-F]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 * $(LI there must be exactly 16 such pairs in the input, not less, not more)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285 * $(LI there can be exactly one dash between two hex-pairs, but not more)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 * $(LI there can be multiple characters enclosing the 16 hex pairs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287 * as long as these characters do not contain [0-9a-fA-F])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 * )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 * Note:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 * Like most parsers, it consumes its argument. This means:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 * -------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 * string s = "8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 * parseUUID(s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295 * assert(s == "");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 * -------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 * Throws:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 * $(LREF UUIDParsingException) if the input is invalid
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 * CTFE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302 * This function is supported in CTFE code. Note that error messages
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 * caused by a malformed UUID parsed at compile time can be cryptic,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 * but errors are detected and reported at compile time.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 UUID parseUUID(T)(T uuidString)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 if (isSomeString!T)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 return parseUUID(uuidString);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312 ///ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 UUID parseUUID(Range)(ref Range uuidRange)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 if (isInputRange!Range
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 && is(Unqual!(ElementType!Range) == dchar))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 import std.ascii : isHexDigit;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318 import std.conv : ConvException, parse;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 static if (isForwardRange!Range)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 auto errorCopy = uuidRange.save;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 void parserError()(size_t pos, UUIDParsingException.Reason reason, string message, Throwable next = null,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 string file = __FILE__, size_t line = __LINE__)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 static if (isForwardRange!Range)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 static if (isInfinite!Range)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 throw new UUIDParsingException(to!string(take(errorCopy, pos)), pos, reason, message,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 next, file, line);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 throw new UUIDParsingException(to!string(errorCopy), pos, reason, message, next, file,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 line);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 throw new UUIDParsingException("", pos, reason, message, next, file, line);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 static if (hasLength!Range)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 if (uuidRange.length < 32)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351 throw new UUIDParsingException(to!string(uuidRange), 0, UUIDParsingException.Reason.tooLittle,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 UUID result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 size_t consumed;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 size_t element = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360 //skip garbage
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 size_t skip()()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 size_t skipped;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 while (!uuidRange.empty && !isHexDigit(uuidRange.front))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 skipped++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367 uuidRange.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 return skipped;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 consumed += skip();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374 if (uuidRange.empty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 parserError(consumed, UUIDParsingException.Reason.tooLittle, "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 bool dashAllowed = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 parseLoop: while (!uuidRange.empty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 immutable character = uuidRange.front;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 if (character == '-')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385 if (!dashAllowed)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 parserError(consumed, UUIDParsingException.Reason.invalidChar, "Unexpected '-'");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 dashAllowed = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 consumed++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 else if (!isHexDigit(character))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 parserError(consumed, UUIDParsingException.Reason.invalidChar,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395 "Unexpected character (wanted a hexDigit)");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399 try
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 consumed += 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402 static if (isSomeString!Range)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 if (uuidRange.length < 2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406 parserError(consumed, UUIDParsingException.Reason.tooLittle,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 auto part = uuidRange[0 .. 2];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 result.data[element++] = parse!ubyte(part, 16);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 uuidRange.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 dchar[2] copyBuf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 copyBuf[0] = character;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 uuidRange.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418 if (uuidRange.empty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420 parserError(consumed, UUIDParsingException.Reason.tooLittle,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 copyBuf[1] = uuidRange.front;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 auto part = copyBuf[];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425 result.data[element++] = parse!ubyte(part, 16);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 if (element == 16)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 uuidRange.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431 break parseLoop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 dashAllowed = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 catch (ConvException e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 parserError(consumed, UUIDParsingException.Reason.invalidChar,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439 "Couldn't parse ubyte", e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 uuidRange.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 assert(element <= 16);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 if (element < 16)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 parserError(consumed, UUIDParsingException.Reason.tooLittle, "Insufficient Input");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 consumed += skip();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 if (!uuidRange.empty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 parserError(consumed, UUIDParsingException.Reason.invalidChar, "Unexpected character");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459 auto id = parseUUID("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 //no dashes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 id = parseUUID("8ab3060e2cba4f23b74cb52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 //dashes at different positions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 id = parseUUID("8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 //leading / trailing characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 id = parseUUID("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 //unicode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467 id = parseUUID("ü8ab3060e2cba4f23b74cb52db3bdfb46ü");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 //multiple trailing/leading characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 id = parseUUID("///8ab3060e2cba4f23b74cb52db3bdfb46||");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 //Can also be used in CTFE, for example as UUID literals:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472 enum ctfeID = parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 //here parsing is done at compile time, no runtime overhead!
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 @safe pure unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 import std.exception;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 import std.meta;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482 struct TestRange(bool forward)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484 dstring input;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 @property dchar front()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 return input.front;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 void popFront()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 input.popFront();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 @property bool empty()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 return input.empty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 static if (forward)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 @property TestRange!true save()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 return this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 alias TestInputRange = TestRange!false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510 alias TestForwardRange = TestRange!true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 assert(isInputRange!TestInputRange);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 assert(is(ElementType!TestInputRange == dchar));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 assert(isInputRange!TestForwardRange);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 assert(isForwardRange!TestForwardRange);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 assert(is(ElementType!TestForwardRange == dchar));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518 //Helper function for unittests - Need to pass ranges by ref
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 UUID parseHelper(T)(string input)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 static if (is(T == TestInputRange) || is(T == TestForwardRange))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 T range = T(to!dstring(input));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 return parseUUID(range);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 return parseUUID(to!T(input));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 wchar[], const(wchar)[], immutable(wchar)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532 dchar[], const(dchar)[], immutable(dchar)[],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 immutable(char[]), immutable(wchar[]), immutable(dchar[]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 TestForwardRange, TestInputRange))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 //Verify examples.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 auto id = parseHelper!S("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 //no dashes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 id = parseHelper!S("8ab3060e2cba4f23b74cb52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 //dashes at different positions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541 id = parseHelper!S("8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 //leading / trailing characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 id = parseHelper!S("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544 //unicode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 id = parseHelper!S("ü8ab3060e2cba4f23b74cb52db3bdfb46ü");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 //multiple trailing/leading characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 id = parseHelper!S("///8ab3060e2cba4f23b74cb52db3bdfb46||");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 enum ctfeId = parseHelper!S("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 assert(parseHelper!S("8AB3060E-2cba-4f23-b74c-b52db3bdfb46") == ctfeId);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551 //Test valid, working cases
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 assert(parseHelper!S("00000000-0000-0000-0000-000000000000").empty);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 assert(parseHelper!S("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46").data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45, 179, 189, 251, 70]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 //wstring / dstring
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561 == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562 assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 //Test too short UUIDS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 auto except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 assert(except && except.reason == UUIDParsingException.Reason.tooLittle);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 //Test too long UUIDS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572 parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886aa"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 //Test too long UUIDS 2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577 parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a-aa"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 //Test dashes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 assert(parseHelper!S("8ab3060e2cba-4f23-b74c-b52db3bdfb46")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 assert(parseHelper!S("8ab3-060e2cba-4f23-b74c-b52db3bdfb46")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 assert(parseHelper!S("8ab3060e2cba4f23b74cb52db3bdfb46")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 except = collectException!UUIDParsingException(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 parseHelper!S("8-ab3060e2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 assert(except && except.reason == UUIDParsingException.Reason.invalidChar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 //Test leading/trailing characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 assert(parseHelper!S("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 assert(parseHelper!S("{8ab3060e2cba4f23b74cb52db3bdfb46}")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 //Boost test
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 auto u_increasing = UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600 0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 assert(parseHelper!S("0123456789abcdef0123456789ABCDEF") == UUID(cast(ubyte[16])[0x01,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 //unicode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 assert(parseHelper!S("ü8ab3060e2cba4f23b74cb52db3bdfb46ü")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 //multiple trailing/leading characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 assert(parseHelper!S("///8ab3060e2cba4f23b74cb52db3bdfb46||")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 * Default namespace from RFC 4122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 * Name string is a fully-qualified domain name
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619 enum dnsNamespace = UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 * Default namespace from RFC 4122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 * Name string is a URL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 enum urlNamespace = UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 * Default namespace from RFC 4122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 * Name string is an ISO OID
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 enum oidNamespace = UUID("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 * Default namespace from RFC 4122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 * Name string is an X.500 DN (in DER or a text output format)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640 enum x500Namespace = UUID("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 * Regex string to extract UUIDs from text.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 enum uuidRegex = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}"~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646 "-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 import std.algorithm;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 import std.regex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 string test = "Lorem ipsum dolor sit amet, consetetur "~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655 "6ba7b814-9dad-11d1-80b4-00c04fd430c8 sadipscing \n"~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656 "elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore \r\n"~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 "magna aliquyam erat, sed diam voluptua. "~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658 "8ab3060e-2cba-4f23-b74c-b52db3bdfb46 At vero eos et accusam et "~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 "justo duo dolores et ea rebum.";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661 auto r = regex(uuidRegex, "g");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662 UUID[] found;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 foreach (c; match(test, r))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 found ~= UUID(c.hit);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 assert(found == [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668 UUID("6ba7b814-9dad-11d1-80b4-00c04fd430c8"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 ]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 * This exception is thrown if an error occurs when parsing a UUID
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675 * from a string.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 public class UUIDParsingException : Exception
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 * The reason why parsing the UUID string failed (if known)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 enum Reason
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 unknown, ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 tooLittle, ///The passed in input was correct, but more input was expected.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686 tooMuch, ///The input data is too long (There's no guarantee the first part of the data is valid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 invalidChar, ///Encountered an invalid character
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 ///ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691 Reason reason;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 ///The original input string which should have been parsed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693 string input;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 ///The position in the input string where the error occurred.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 size_t position;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697 private this(string input, size_t pos, Reason why = Reason.unknown, string msg = "",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 Throwable next = null, string file = __FILE__, size_t line = __LINE__) pure @trusted
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 import std.array : replace;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701 import std.format : format;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 this.input = input;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 this.position = pos;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 this.reason = why;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 string message = format("An error occured in the UUID parser: %s\n" ~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706 " * Input:\t'%s'\n * Position:\t%s", msg, replace(replace(input,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707 "\r", "\\r"), "\n", "\\n"), pos);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 super(message, file, line, next);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 import std.exception : collectException;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 const inputUUID = "this-is-an-invalid-uuid";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 auto ex = collectException!UUIDParsingException(UUID(inputUUID));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719 assert(ex !is null); // check that exception was thrown
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 assert(ex.input == inputUUID);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721 assert(ex.position == 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 assert(ex.reason == UUIDParsingException.Reason.tooLittle);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 auto ex = new UUIDParsingException("foo", 10, UUIDParsingException.Reason.tooMuch);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728 assert(ex.input == "foo");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729 assert(ex.position == 10);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 assert(ex.reason == UUIDParsingException.Reason.tooMuch);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 }