ires 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/ires/ires.go +114 -0
- data/ext/main.go +22 -76
- data/ext/operate/image.go +54 -17
- data/ext/vendor/github.com/satori/go.uuid/LICENSE +20 -0
- data/ext/vendor/github.com/satori/go.uuid/README.md +65 -0
- data/ext/vendor/github.com/satori/go.uuid/benchmarks_test.go +121 -0
- data/ext/vendor/github.com/satori/go.uuid/uuid.go +488 -0
- data/ext/vendor/github.com/satori/go.uuid/uuid_test.go +633 -0
- data/lib/ires/version.rb +1 -1
- data/shared/darwin/ires.so +0 -0
- data/shared/linux/ires.so +0 -0
- metadata +8 -2
@@ -0,0 +1,121 @@
|
|
1
|
+
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
// a copy of this software and associated documentation files (the
|
5
|
+
// "Software"), to deal in the Software without restriction, including
|
6
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
// distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
// permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
// the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be
|
12
|
+
// included in all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
package uuid
|
23
|
+
|
24
|
+
import (
|
25
|
+
"testing"
|
26
|
+
)
|
27
|
+
|
28
|
+
func BenchmarkFromBytes(b *testing.B) {
|
29
|
+
bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
|
30
|
+
for i := 0; i < b.N; i++ {
|
31
|
+
FromBytes(bytes)
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
func BenchmarkFromString(b *testing.B) {
|
36
|
+
s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
37
|
+
for i := 0; i < b.N; i++ {
|
38
|
+
FromString(s)
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
func BenchmarkFromStringUrn(b *testing.B) {
|
43
|
+
s := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
44
|
+
for i := 0; i < b.N; i++ {
|
45
|
+
FromString(s)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
func BenchmarkFromStringWithBrackets(b *testing.B) {
|
50
|
+
s := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
|
51
|
+
for i := 0; i < b.N; i++ {
|
52
|
+
FromString(s)
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
func BenchmarkNewV1(b *testing.B) {
|
57
|
+
for i := 0; i < b.N; i++ {
|
58
|
+
NewV1()
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
func BenchmarkNewV2(b *testing.B) {
|
63
|
+
for i := 0; i < b.N; i++ {
|
64
|
+
NewV2(DomainPerson)
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
func BenchmarkNewV3(b *testing.B) {
|
69
|
+
for i := 0; i < b.N; i++ {
|
70
|
+
NewV3(NamespaceDNS, "www.example.com")
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
func BenchmarkNewV4(b *testing.B) {
|
75
|
+
for i := 0; i < b.N; i++ {
|
76
|
+
NewV4()
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
func BenchmarkNewV5(b *testing.B) {
|
81
|
+
for i := 0; i < b.N; i++ {
|
82
|
+
NewV5(NamespaceDNS, "www.example.com")
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
func BenchmarkMarshalBinary(b *testing.B) {
|
87
|
+
u := NewV4()
|
88
|
+
for i := 0; i < b.N; i++ {
|
89
|
+
u.MarshalBinary()
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
func BenchmarkMarshalText(b *testing.B) {
|
94
|
+
u := NewV4()
|
95
|
+
for i := 0; i < b.N; i++ {
|
96
|
+
u.MarshalText()
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
func BenchmarkUnmarshalBinary(b *testing.B) {
|
101
|
+
bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
|
102
|
+
u := UUID{}
|
103
|
+
for i := 0; i < b.N; i++ {
|
104
|
+
u.UnmarshalBinary(bytes)
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
func BenchmarkUnmarshalText(b *testing.B) {
|
109
|
+
bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
110
|
+
u := UUID{}
|
111
|
+
for i := 0; i < b.N; i++ {
|
112
|
+
u.UnmarshalText(bytes)
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
func BenchmarkMarshalToString(b *testing.B) {
|
117
|
+
u := NewV4()
|
118
|
+
for i := 0; i < b.N; i++ {
|
119
|
+
u.String()
|
120
|
+
}
|
121
|
+
}
|
@@ -0,0 +1,488 @@
|
|
1
|
+
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
// a copy of this software and associated documentation files (the
|
5
|
+
// "Software"), to deal in the Software without restriction, including
|
6
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
// distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
// permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
// the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be
|
12
|
+
// included in all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
// Package uuid provides implementation of Universally Unique Identifier (UUID).
|
23
|
+
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
|
24
|
+
// version 2 (as specified in DCE 1.1).
|
25
|
+
package uuid
|
26
|
+
|
27
|
+
import (
|
28
|
+
"bytes"
|
29
|
+
"crypto/md5"
|
30
|
+
"crypto/rand"
|
31
|
+
"crypto/sha1"
|
32
|
+
"database/sql/driver"
|
33
|
+
"encoding/binary"
|
34
|
+
"encoding/hex"
|
35
|
+
"fmt"
|
36
|
+
"hash"
|
37
|
+
"net"
|
38
|
+
"os"
|
39
|
+
"sync"
|
40
|
+
"time"
|
41
|
+
)
|
42
|
+
|
43
|
+
// UUID layout variants.
|
44
|
+
const (
|
45
|
+
VariantNCS = iota
|
46
|
+
VariantRFC4122
|
47
|
+
VariantMicrosoft
|
48
|
+
VariantFuture
|
49
|
+
)
|
50
|
+
|
51
|
+
// UUID DCE domains.
|
52
|
+
const (
|
53
|
+
DomainPerson = iota
|
54
|
+
DomainGroup
|
55
|
+
DomainOrg
|
56
|
+
)
|
57
|
+
|
58
|
+
// Difference in 100-nanosecond intervals between
|
59
|
+
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
60
|
+
const epochStart = 122192928000000000
|
61
|
+
|
62
|
+
// Used in string method conversion
|
63
|
+
const dash byte = '-'
|
64
|
+
|
65
|
+
// UUID v1/v2 storage.
|
66
|
+
var (
|
67
|
+
storageMutex sync.Mutex
|
68
|
+
storageOnce sync.Once
|
69
|
+
epochFunc = unixTimeFunc
|
70
|
+
clockSequence uint16
|
71
|
+
lastTime uint64
|
72
|
+
hardwareAddr [6]byte
|
73
|
+
posixUID = uint32(os.Getuid())
|
74
|
+
posixGID = uint32(os.Getgid())
|
75
|
+
)
|
76
|
+
|
77
|
+
// String parse helpers.
|
78
|
+
var (
|
79
|
+
urnPrefix = []byte("urn:uuid:")
|
80
|
+
byteGroups = []int{8, 4, 4, 4, 12}
|
81
|
+
)
|
82
|
+
|
83
|
+
func initClockSequence() {
|
84
|
+
buf := make([]byte, 2)
|
85
|
+
safeRandom(buf)
|
86
|
+
clockSequence = binary.BigEndian.Uint16(buf)
|
87
|
+
}
|
88
|
+
|
89
|
+
func initHardwareAddr() {
|
90
|
+
interfaces, err := net.Interfaces()
|
91
|
+
if err == nil {
|
92
|
+
for _, iface := range interfaces {
|
93
|
+
if len(iface.HardwareAddr) >= 6 {
|
94
|
+
copy(hardwareAddr[:], iface.HardwareAddr)
|
95
|
+
return
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
// Initialize hardwareAddr randomly in case
|
101
|
+
// of real network interfaces absence
|
102
|
+
safeRandom(hardwareAddr[:])
|
103
|
+
|
104
|
+
// Set multicast bit as recommended in RFC 4122
|
105
|
+
hardwareAddr[0] |= 0x01
|
106
|
+
}
|
107
|
+
|
108
|
+
func initStorage() {
|
109
|
+
initClockSequence()
|
110
|
+
initHardwareAddr()
|
111
|
+
}
|
112
|
+
|
113
|
+
func safeRandom(dest []byte) {
|
114
|
+
if _, err := rand.Read(dest); err != nil {
|
115
|
+
panic(err)
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
// Returns difference in 100-nanosecond intervals between
|
120
|
+
// UUID epoch (October 15, 1582) and current time.
|
121
|
+
// This is default epoch calculation function.
|
122
|
+
func unixTimeFunc() uint64 {
|
123
|
+
return epochStart + uint64(time.Now().UnixNano()/100)
|
124
|
+
}
|
125
|
+
|
126
|
+
// UUID representation compliant with specification
|
127
|
+
// described in RFC 4122.
|
128
|
+
type UUID [16]byte
|
129
|
+
|
130
|
+
// NullUUID can be used with the standard sql package to represent a
|
131
|
+
// UUID value that can be NULL in the database
|
132
|
+
type NullUUID struct {
|
133
|
+
UUID UUID
|
134
|
+
Valid bool
|
135
|
+
}
|
136
|
+
|
137
|
+
// The nil UUID is special form of UUID that is specified to have all
|
138
|
+
// 128 bits set to zero.
|
139
|
+
var Nil = UUID{}
|
140
|
+
|
141
|
+
// Predefined namespace UUIDs.
|
142
|
+
var (
|
143
|
+
NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
144
|
+
NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
|
145
|
+
NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
|
146
|
+
NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
|
147
|
+
)
|
148
|
+
|
149
|
+
// And returns result of binary AND of two UUIDs.
|
150
|
+
func And(u1 UUID, u2 UUID) UUID {
|
151
|
+
u := UUID{}
|
152
|
+
for i := 0; i < 16; i++ {
|
153
|
+
u[i] = u1[i] & u2[i]
|
154
|
+
}
|
155
|
+
return u
|
156
|
+
}
|
157
|
+
|
158
|
+
// Or returns result of binary OR of two UUIDs.
|
159
|
+
func Or(u1 UUID, u2 UUID) UUID {
|
160
|
+
u := UUID{}
|
161
|
+
for i := 0; i < 16; i++ {
|
162
|
+
u[i] = u1[i] | u2[i]
|
163
|
+
}
|
164
|
+
return u
|
165
|
+
}
|
166
|
+
|
167
|
+
// Equal returns true if u1 and u2 equals, otherwise returns false.
|
168
|
+
func Equal(u1 UUID, u2 UUID) bool {
|
169
|
+
return bytes.Equal(u1[:], u2[:])
|
170
|
+
}
|
171
|
+
|
172
|
+
// Version returns algorithm version used to generate UUID.
|
173
|
+
func (u UUID) Version() uint {
|
174
|
+
return uint(u[6] >> 4)
|
175
|
+
}
|
176
|
+
|
177
|
+
// Variant returns UUID layout variant.
|
178
|
+
func (u UUID) Variant() uint {
|
179
|
+
switch {
|
180
|
+
case (u[8] & 0x80) == 0x00:
|
181
|
+
return VariantNCS
|
182
|
+
case (u[8]&0xc0)|0x80 == 0x80:
|
183
|
+
return VariantRFC4122
|
184
|
+
case (u[8]&0xe0)|0xc0 == 0xc0:
|
185
|
+
return VariantMicrosoft
|
186
|
+
}
|
187
|
+
return VariantFuture
|
188
|
+
}
|
189
|
+
|
190
|
+
// Bytes returns bytes slice representation of UUID.
|
191
|
+
func (u UUID) Bytes() []byte {
|
192
|
+
return u[:]
|
193
|
+
}
|
194
|
+
|
195
|
+
// Returns canonical string representation of UUID:
|
196
|
+
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
197
|
+
func (u UUID) String() string {
|
198
|
+
buf := make([]byte, 36)
|
199
|
+
|
200
|
+
hex.Encode(buf[0:8], u[0:4])
|
201
|
+
buf[8] = dash
|
202
|
+
hex.Encode(buf[9:13], u[4:6])
|
203
|
+
buf[13] = dash
|
204
|
+
hex.Encode(buf[14:18], u[6:8])
|
205
|
+
buf[18] = dash
|
206
|
+
hex.Encode(buf[19:23], u[8:10])
|
207
|
+
buf[23] = dash
|
208
|
+
hex.Encode(buf[24:], u[10:])
|
209
|
+
|
210
|
+
return string(buf)
|
211
|
+
}
|
212
|
+
|
213
|
+
// SetVersion sets version bits.
|
214
|
+
func (u *UUID) SetVersion(v byte) {
|
215
|
+
u[6] = (u[6] & 0x0f) | (v << 4)
|
216
|
+
}
|
217
|
+
|
218
|
+
// SetVariant sets variant bits as described in RFC 4122.
|
219
|
+
func (u *UUID) SetVariant() {
|
220
|
+
u[8] = (u[8] & 0xbf) | 0x80
|
221
|
+
}
|
222
|
+
|
223
|
+
// MarshalText implements the encoding.TextMarshaler interface.
|
224
|
+
// The encoding is the same as returned by String.
|
225
|
+
func (u UUID) MarshalText() (text []byte, err error) {
|
226
|
+
text = []byte(u.String())
|
227
|
+
return
|
228
|
+
}
|
229
|
+
|
230
|
+
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
231
|
+
// Following formats are supported:
|
232
|
+
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
233
|
+
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
|
234
|
+
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
235
|
+
func (u *UUID) UnmarshalText(text []byte) (err error) {
|
236
|
+
if len(text) < 32 {
|
237
|
+
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
238
|
+
return
|
239
|
+
}
|
240
|
+
|
241
|
+
t := text[:]
|
242
|
+
braced := false
|
243
|
+
|
244
|
+
if bytes.Equal(t[:9], urnPrefix) {
|
245
|
+
t = t[9:]
|
246
|
+
} else if t[0] == '{' {
|
247
|
+
braced = true
|
248
|
+
t = t[1:]
|
249
|
+
}
|
250
|
+
|
251
|
+
b := u[:]
|
252
|
+
|
253
|
+
for i, byteGroup := range byteGroups {
|
254
|
+
if i > 0 && t[0] == '-' {
|
255
|
+
t = t[1:]
|
256
|
+
} else if i > 0 && t[0] != '-' {
|
257
|
+
err = fmt.Errorf("uuid: invalid string format")
|
258
|
+
return
|
259
|
+
}
|
260
|
+
|
261
|
+
if i == 2 {
|
262
|
+
if !bytes.Contains([]byte("012345"), []byte{t[0]}) {
|
263
|
+
err = fmt.Errorf("uuid: invalid version number: %s", t[0])
|
264
|
+
return
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
if len(t) < byteGroup {
|
269
|
+
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
270
|
+
return
|
271
|
+
}
|
272
|
+
|
273
|
+
if i == 4 && len(t) > byteGroup &&
|
274
|
+
((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
|
275
|
+
err = fmt.Errorf("uuid: UUID string too long: %s", t)
|
276
|
+
return
|
277
|
+
}
|
278
|
+
|
279
|
+
_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
|
280
|
+
|
281
|
+
if err != nil {
|
282
|
+
return
|
283
|
+
}
|
284
|
+
|
285
|
+
t = t[byteGroup:]
|
286
|
+
b = b[byteGroup/2:]
|
287
|
+
}
|
288
|
+
|
289
|
+
return
|
290
|
+
}
|
291
|
+
|
292
|
+
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
293
|
+
func (u UUID) MarshalBinary() (data []byte, err error) {
|
294
|
+
data = u.Bytes()
|
295
|
+
return
|
296
|
+
}
|
297
|
+
|
298
|
+
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
299
|
+
// It will return error if the slice isn't 16 bytes long.
|
300
|
+
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
|
301
|
+
if len(data) != 16 {
|
302
|
+
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
|
303
|
+
return
|
304
|
+
}
|
305
|
+
copy(u[:], data)
|
306
|
+
|
307
|
+
return
|
308
|
+
}
|
309
|
+
|
310
|
+
// Value implements the driver.Valuer interface.
|
311
|
+
func (u UUID) Value() (driver.Value, error) {
|
312
|
+
return u.String(), nil
|
313
|
+
}
|
314
|
+
|
315
|
+
// Scan implements the sql.Scanner interface.
|
316
|
+
// A 16-byte slice is handled by UnmarshalBinary, while
|
317
|
+
// a longer byte slice or a string is handled by UnmarshalText.
|
318
|
+
func (u *UUID) Scan(src interface{}) error {
|
319
|
+
switch src := src.(type) {
|
320
|
+
case []byte:
|
321
|
+
if len(src) == 16 {
|
322
|
+
return u.UnmarshalBinary(src)
|
323
|
+
}
|
324
|
+
return u.UnmarshalText(src)
|
325
|
+
|
326
|
+
case string:
|
327
|
+
return u.UnmarshalText([]byte(src))
|
328
|
+
}
|
329
|
+
|
330
|
+
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
|
331
|
+
}
|
332
|
+
|
333
|
+
// Value implements the driver.Valuer interface.
|
334
|
+
func (u NullUUID) Value() (driver.Value, error) {
|
335
|
+
if !u.Valid {
|
336
|
+
return nil, nil
|
337
|
+
}
|
338
|
+
// Delegate to UUID Value function
|
339
|
+
return u.UUID.Value()
|
340
|
+
}
|
341
|
+
|
342
|
+
// Scan implements the sql.Scanner interface.
|
343
|
+
func (u *NullUUID) Scan(src interface{}) error {
|
344
|
+
if src == nil {
|
345
|
+
u.UUID, u.Valid = Nil, false
|
346
|
+
return nil
|
347
|
+
}
|
348
|
+
|
349
|
+
// Delegate to UUID Scan function
|
350
|
+
u.Valid = true
|
351
|
+
return u.UUID.Scan(src)
|
352
|
+
}
|
353
|
+
|
354
|
+
// FromBytes returns UUID converted from raw byte slice input.
|
355
|
+
// It will return error if the slice isn't 16 bytes long.
|
356
|
+
func FromBytes(input []byte) (u UUID, err error) {
|
357
|
+
err = u.UnmarshalBinary(input)
|
358
|
+
return
|
359
|
+
}
|
360
|
+
|
361
|
+
// FromBytesOrNil returns UUID converted from raw byte slice input.
|
362
|
+
// Same behavior as FromBytes, but returns a Nil UUID on error.
|
363
|
+
func FromBytesOrNil(input []byte) UUID {
|
364
|
+
uuid, err := FromBytes(input)
|
365
|
+
if err != nil {
|
366
|
+
return Nil
|
367
|
+
}
|
368
|
+
return uuid
|
369
|
+
}
|
370
|
+
|
371
|
+
// FromString returns UUID parsed from string input.
|
372
|
+
// Input is expected in a form accepted by UnmarshalText.
|
373
|
+
func FromString(input string) (u UUID, err error) {
|
374
|
+
err = u.UnmarshalText([]byte(input))
|
375
|
+
return
|
376
|
+
}
|
377
|
+
|
378
|
+
// FromStringOrNil returns UUID parsed from string input.
|
379
|
+
// Same behavior as FromString, but returns a Nil UUID on error.
|
380
|
+
func FromStringOrNil(input string) UUID {
|
381
|
+
uuid, err := FromString(input)
|
382
|
+
if err != nil {
|
383
|
+
return Nil
|
384
|
+
}
|
385
|
+
return uuid
|
386
|
+
}
|
387
|
+
|
388
|
+
// Returns UUID v1/v2 storage state.
|
389
|
+
// Returns epoch timestamp, clock sequence, and hardware address.
|
390
|
+
func getStorage() (uint64, uint16, []byte) {
|
391
|
+
storageOnce.Do(initStorage)
|
392
|
+
|
393
|
+
storageMutex.Lock()
|
394
|
+
defer storageMutex.Unlock()
|
395
|
+
|
396
|
+
timeNow := epochFunc()
|
397
|
+
// Clock changed backwards since last UUID generation.
|
398
|
+
// Should increase clock sequence.
|
399
|
+
if timeNow <= lastTime {
|
400
|
+
clockSequence++
|
401
|
+
}
|
402
|
+
lastTime = timeNow
|
403
|
+
|
404
|
+
return timeNow, clockSequence, hardwareAddr[:]
|
405
|
+
}
|
406
|
+
|
407
|
+
// NewV1 returns UUID based on current timestamp and MAC address.
|
408
|
+
func NewV1() UUID {
|
409
|
+
u := UUID{}
|
410
|
+
|
411
|
+
timeNow, clockSeq, hardwareAddr := getStorage()
|
412
|
+
|
413
|
+
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
|
414
|
+
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
415
|
+
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
416
|
+
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
417
|
+
|
418
|
+
copy(u[10:], hardwareAddr)
|
419
|
+
|
420
|
+
u.SetVersion(1)
|
421
|
+
u.SetVariant()
|
422
|
+
|
423
|
+
return u
|
424
|
+
}
|
425
|
+
|
426
|
+
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
|
427
|
+
func NewV2(domain byte) UUID {
|
428
|
+
u := UUID{}
|
429
|
+
|
430
|
+
timeNow, clockSeq, hardwareAddr := getStorage()
|
431
|
+
|
432
|
+
switch domain {
|
433
|
+
case DomainPerson:
|
434
|
+
binary.BigEndian.PutUint32(u[0:], posixUID)
|
435
|
+
case DomainGroup:
|
436
|
+
binary.BigEndian.PutUint32(u[0:], posixGID)
|
437
|
+
}
|
438
|
+
|
439
|
+
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
440
|
+
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
441
|
+
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
442
|
+
u[9] = domain
|
443
|
+
|
444
|
+
copy(u[10:], hardwareAddr)
|
445
|
+
|
446
|
+
u.SetVersion(2)
|
447
|
+
u.SetVariant()
|
448
|
+
|
449
|
+
return u
|
450
|
+
}
|
451
|
+
|
452
|
+
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
|
453
|
+
func NewV3(ns UUID, name string) UUID {
|
454
|
+
u := newFromHash(md5.New(), ns, name)
|
455
|
+
u.SetVersion(3)
|
456
|
+
u.SetVariant()
|
457
|
+
|
458
|
+
return u
|
459
|
+
}
|
460
|
+
|
461
|
+
// NewV4 returns random generated UUID.
|
462
|
+
func NewV4() UUID {
|
463
|
+
u := UUID{}
|
464
|
+
safeRandom(u[:])
|
465
|
+
u.SetVersion(4)
|
466
|
+
u.SetVariant()
|
467
|
+
|
468
|
+
return u
|
469
|
+
}
|
470
|
+
|
471
|
+
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
|
472
|
+
func NewV5(ns UUID, name string) UUID {
|
473
|
+
u := newFromHash(sha1.New(), ns, name)
|
474
|
+
u.SetVersion(5)
|
475
|
+
u.SetVariant()
|
476
|
+
|
477
|
+
return u
|
478
|
+
}
|
479
|
+
|
480
|
+
// Returns UUID based on hashing of namespace UUID and name.
|
481
|
+
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
482
|
+
u := UUID{}
|
483
|
+
h.Write(ns[:])
|
484
|
+
h.Write([]byte(name))
|
485
|
+
copy(u[:], h.Sum(nil))
|
486
|
+
|
487
|
+
return u
|
488
|
+
}
|