Merge pull request #753 from aviau/official-uuid

dep: use official uuid package
This commit is contained in:
Harald Sitter
2018-06-22 11:14:35 +02:00
committed by GitHub
33 changed files with 755 additions and 3455 deletions
Generated
+7 -7
View File
@@ -155,6 +155,12 @@
] ]
revision = "8e9b10220613abdbc2896808ee6b43e411a4fa6c" revision = "8e9b10220613abdbc2896808ee6b43e411a4fa6c"
[[projects]]
branch = "master"
name = "github.com/pborman/uuid"
packages = ["."]
revision = "c65b2f87fee37d1c7854c9164a450713c28d50cd"
[[projects]] [[projects]]
name = "github.com/pkg/errors" name = "github.com/pkg/errors"
packages = ["."] packages = ["."]
@@ -185,12 +191,6 @@
packages = ["protocol"] packages = ["protocol"]
revision = "066b75c2b70dca7ae10b1b88b47534a3c31ccfaa" revision = "066b75c2b70dca7ae10b1b88b47534a3c31ccfaa"
[[projects]]
branch = "master"
name = "github.com/smira/go-uuid"
packages = ["uuid"]
revision = "ed3ca8a15a931b141440a7e98e4f716eec255f7d"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/smira/go-xz" name = "github.com/smira/go-xz"
@@ -285,6 +285,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "5ab2b384766e62be84d3941971a1d8e99c637f80a2cb1482b3d9704c668b549f" inputs-digest = "3ae43715f5d857c1686ad4b4310a5537afc8d0ab50dc658d11db7c2b36f17fee"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"io" "io"
"github.com/aptly-dev/aptly/database" "github.com/aptly-dev/aptly/database"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
) )
// ContentsIndex calculates mapping from files to packages, with sorting and aggregation // ContentsIndex calculates mapping from files to packages, with sorting and aggregation
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"sync" "sync"
"github.com/aptly-dev/aptly/database" "github.com/aptly-dev/aptly/database"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
) )
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
"github.com/aptly-dev/aptly/aptly" "github.com/aptly-dev/aptly/aptly"
+1 -1
View File
@@ -20,7 +20,7 @@ import (
"github.com/aptly-dev/aptly/http" "github.com/aptly-dev/aptly/http"
"github.com/aptly-dev/aptly/pgp" "github.com/aptly-dev/aptly/pgp"
"github.com/aptly-dev/aptly/utils" "github.com/aptly-dev/aptly/utils"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
) )
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"github.com/aptly-dev/aptly/database" "github.com/aptly-dev/aptly/database"
"github.com/aptly-dev/aptly/utils" "github.com/aptly-dev/aptly/utils"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
) )
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"sync" "sync"
"syscall" "syscall"
"github.com/smira/go-uuid/uuid" "github.com/pborman/uuid"
"github.com/aptly-dev/aptly/aptly" "github.com/aptly-dev/aptly/aptly"
"github.com/aptly-dev/aptly/utils" "github.com/aptly-dev/aptly/utils"
+9
View File
@@ -0,0 +1,9 @@
language: go
go:
- 1.4.3
- 1.5.3
- tip
script:
- go test -v ./...
+10
View File
@@ -0,0 +1,10 @@
# How to contribute
We definitely welcome patches and contribution to this project!
### Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas).
You may have already signed it for other Google projects.
+13
View File
@@ -0,0 +1,13 @@
This project was automatically exported from code.google.com/p/go-uuid
# uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master)
The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services.
###### Install
`go get github.com/pborman/uuid`
###### Documentation
[![GoDoc](https://godoc.org/github.com/pborman/uuid?status.svg)](http://godoc.org/github.com/pborman/uuid)
Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here:
http://godoc.org/github.com/pborman/uuid
View File
View File
@@ -19,7 +19,7 @@ var (
NIL = Parse("00000000-0000-0000-0000-000000000000") NIL = Parse("00000000-0000-0000-0000-000000000000")
) )
// NewHash returns a new UUID dervied from the hash of space concatenated with // NewHash returns a new UUID derived from the hash of space concatenated with
// data generated by h. The hash should be at least 16 byte in length. The // data generated by h. The hash should be at least 16 byte in length. The
// first 16 bytes of the hash are used to form the UUID. The version of the // first 16 bytes of the hash are used to form the UUID. The version of the
// UUID will be the lower 4 bits of version. NewHash is used to implement // UUID will be the lower 4 bits of version. NewHash is used to implement
+83
View File
@@ -0,0 +1,83 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"errors"
"fmt"
)
// MarshalText implements encoding.TextMarshaler.
func (u UUID) MarshalText() ([]byte, error) {
if len(u) != 16 {
return nil, nil
}
var js [36]byte
encodeHex(js[:], u)
return js[:], nil
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (u *UUID) UnmarshalText(data []byte) error {
if len(data) == 0 {
return nil
}
id := Parse(string(data))
if id == nil {
return errors.New("invalid UUID")
}
*u = id
return nil
}
// MarshalBinary implements encoding.BinaryMarshaler.
func (u UUID) MarshalBinary() ([]byte, error) {
return u[:], nil
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (u *UUID) UnmarshalBinary(data []byte) error {
if len(data) == 0 {
return nil
}
if len(data) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
}
var id [16]byte
copy(id[:], data)
*u = id[:]
return nil
}
// MarshalText implements encoding.TextMarshaler.
func (u Array) MarshalText() ([]byte, error) {
var js [36]byte
encodeHex(js[:], u[:])
return js[:], nil
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (u *Array) UnmarshalText(data []byte) error {
id := Parse(string(data))
if id == nil {
return errors.New("invalid UUID")
}
*u = id.Array()
return nil
}
// MarshalBinary implements encoding.BinaryMarshaler.
func (u Array) MarshalBinary() ([]byte, error) {
return u[:], nil
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (u *Array) UnmarshalBinary(data []byte) error {
if len(data) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
}
copy(u[:], data)
return nil
}
+124
View File
@@ -0,0 +1,124 @@
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"bytes"
"encoding/json"
"reflect"
"testing"
)
var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
var testArray = testUUID.Array()
func TestJSON(t *testing.T) {
type S struct {
ID1 UUID
ID2 UUID
}
s1 := S{ID1: testUUID}
data, err := json.Marshal(&s1)
if err != nil {
t.Fatal(err)
}
var s2 S
if err := json.Unmarshal(data, &s2); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(&s1, &s2) {
t.Errorf("got %#v, want %#v", s2, s1)
}
}
func TestJSONArray(t *testing.T) {
type S struct {
ID1 Array
ID2 Array
}
s1 := S{ID1: testArray}
data, err := json.Marshal(&s1)
if err != nil {
t.Fatal(err)
}
var s2 S
if err := json.Unmarshal(data, &s2); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(&s1, &s2) {
t.Errorf("got %#v, want %#v", s2, s1)
}
}
func TestMarshal(t *testing.T) {
data, err := testUUID.MarshalBinary()
if err != nil {
t.Fatalf("MarhsalBinary returned unexpected error %v", err)
}
if !bytes.Equal(data, testUUID) {
t.Fatalf("MarhsalBinary returns %x, want %x", data, testUUID)
}
var u UUID
u.UnmarshalBinary(data)
if !Equal(data, u) {
t.Fatalf("UnmarhsalBinary returns %v, want %v", u, testUUID)
}
}
func TestMarshalArray(t *testing.T) {
data, err := testArray.MarshalBinary()
if err != nil {
t.Fatalf("MarhsalBinary returned unexpected error %v", err)
}
if !bytes.Equal(data, testUUID) {
t.Fatalf("MarhsalBinary returns %x, want %x", data, testUUID)
}
var a Array
a.UnmarshalBinary(data)
if a != testArray {
t.Fatalf("UnmarhsalBinary returns %v, want %v", a, testArray)
}
}
func TestMarshalTextArray(t *testing.T) {
data, err := testArray.MarshalText()
if err != nil {
t.Fatalf("MarhsalText returned unexpected error %v", err)
}
var a Array
a.UnmarshalText(data)
if a != testArray {
t.Fatalf("UnmarhsalText returns %v, want %v", a, testArray)
}
}
func BenchmarkUUID_MarshalJSON(b *testing.B) {
x := &struct {
UUID UUID `json:"uuid"`
}{}
x.UUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if x.UUID == nil {
b.Fatal("invalid uuid")
}
for i := 0; i < b.N; i++ {
js, err := json.Marshal(x)
if err != nil {
b.Fatalf("marshal json: %#v (%v)", js, err)
}
}
}
func BenchmarkUUID_UnmarshalJSON(b *testing.B) {
js := []byte(`{"uuid":"f47ac10b-58cc-0372-8567-0e02b2c3d479"}`)
var x *struct {
UUID UUID `json:"uuid"`
}
for i := 0; i < b.N; i++ {
err := json.Unmarshal(js, &x)
if err != nil {
b.Fatalf("marshal json: %#v (%v)", js, err)
}
}
}
+25 -18
View File
@@ -4,18 +4,22 @@
package uuid package uuid
import "net" import (
"sync"
)
var ( var (
interfaces []net.Interface // cached list of interfaces nodeMu sync.Mutex
ifname string // name of interface being used ifname string // name of interface being used
nodeID []byte // hardware for version 1 UUIDs nodeID []byte // hardware for version 1 UUIDs
) )
// NodeInterface returns the name of the interface from which the NodeID was // NodeInterface returns the name of the interface from which the NodeID was
// derived. The interface "user" is returned if the NodeID was set by // derived. The interface "user" is returned if the NodeID was set by
// SetNodeID. // SetNodeID.
func NodeInterface() string { func NodeInterface() string {
defer nodeMu.Unlock()
nodeMu.Lock()
return ifname return ifname
} }
@@ -26,21 +30,20 @@ func NodeInterface() string {
// //
// SetNodeInterface never fails when name is "". // SetNodeInterface never fails when name is "".
func SetNodeInterface(name string) bool { func SetNodeInterface(name string) bool {
if interfaces == nil { defer nodeMu.Unlock()
var err error nodeMu.Lock()
interfaces, err = net.Interfaces() if nodeID != nil {
if err != nil && name != "" { return true
return false
}
} }
return setNodeInterface(name)
}
for _, ifs := range interfaces { func setNodeInterface(name string) bool {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
if setNodeID(ifs.HardwareAddr) { iname, addr := getHardwareInterface(name) // null implementation for js
ifname = ifs.Name if iname != "" && setNodeID(addr) {
return true ifname = iname
} return true
}
} }
// We found no interfaces with a valid hardware address. If name // We found no interfaces with a valid hardware address. If name
@@ -59,8 +62,10 @@ func SetNodeInterface(name string) bool {
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
// if not already set. // if not already set.
func NodeID() []byte { func NodeID() []byte {
defer nodeMu.Unlock()
nodeMu.Lock()
if nodeID == nil { if nodeID == nil {
SetNodeInterface("") setNodeInterface("")
} }
nid := make([]byte, 6) nid := make([]byte, 6)
copy(nid, nodeID) copy(nid, nodeID)
@@ -71,6 +76,8 @@ func NodeID() []byte {
// of id are used. If id is less than 6 bytes then false is returned and the // of id are used. If id is less than 6 bytes then false is returned and the
// Node ID is not set. // Node ID is not set.
func SetNodeID(id []byte) bool { func SetNodeID(id []byte) bool {
defer nodeMu.Unlock()
nodeMu.Lock()
if setNodeID(id) { if setNodeID(id) {
ifname = "user" ifname = "user"
return true return true
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build js
package uuid
// getHardwareInterface returns nil values for the JS version of the code.
// This remvoves the "net" dependency, because it is not used in the browser.
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
func getHardwareInterface(name string) (string, []byte) { return "", nil }
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2017 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !js
package uuid
import "net"
var interfaces []net.Interface // cached list of interfaces
// getHardwareInterface returns the name and hardware address of interface name.
// If name is "" then the name and hardware address of one of the system's
// interfaces is returned. If no interfaces are found (name does not exist or
// there are no interfaces) then "", nil is returned.
//
// Only addresses of at least 6 bytes are returned.
func getHardwareInterface(name string) (string, []byte) {
if interfaces == nil {
var err error
interfaces, err = net.Interfaces()
if err != nil {
return "", nil
}
}
for _, ifs := range interfaces {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
if setNodeID(ifs.HardwareAddr) {
ifname = ifs.Name
return ifname, nodeID
}
}
}
return "", nil
}
+66
View File
@@ -0,0 +1,66 @@
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"database/sql/driver"
"errors"
"fmt"
)
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
// Currently, database types that map to string and []byte are supported. Please
// consult database-specific driver documentation for matching types.
func (uuid *UUID) Scan(src interface{}) error {
switch src.(type) {
case string:
// if an empty UUID comes from a table, we return a null UUID
if src.(string) == "" {
return nil
}
// see uuid.Parse for required string format
parsed := Parse(src.(string))
if parsed == nil {
return errors.New("Scan: invalid UUID format")
}
*uuid = parsed
case []byte:
b := src.([]byte)
// if an empty UUID comes from a table, we return a null UUID
if len(b) == 0 {
return nil
}
// assumes a simple slice of bytes if 16 bytes
// otherwise attempts to parse
if len(b) == 16 {
*uuid = UUID(b)
} else {
u := Parse(string(b))
if u == nil {
return errors.New("Scan: invalid UUID format")
}
*uuid = u
}
default:
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
}
return nil
}
// Value implements sql.Valuer so that UUIDs can be written to databases
// transparently. Currently, UUIDs map to strings. Please consult
// database-specific driver documentation for matching types.
func (uuid UUID) Value() (driver.Value, error) {
return uuid.String(), nil
}
+96
View File
@@ -0,0 +1,96 @@
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"strings"
"testing"
)
func TestScan(t *testing.T) {
var stringTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d479"
var byteTest []byte = Parse(stringTest)
var badTypeTest int = 6
var invalidTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d4"
// sunny day tests
var uuid UUID
err := (&uuid).Scan(stringTest)
if err != nil {
t.Fatal(err)
}
err = (&uuid).Scan([]byte(stringTest))
if err != nil {
t.Fatal(err)
}
err = (&uuid).Scan(byteTest)
if err != nil {
t.Fatal(err)
}
// bad type tests
err = (&uuid).Scan(badTypeTest)
if err == nil {
t.Error("int correctly parsed and shouldn't have")
}
if !strings.Contains(err.Error(), "unable to scan type") {
t.Error("attempting to parse an int returned an incorrect error message")
}
// invalid/incomplete uuids
err = (&uuid).Scan(invalidTest)
if err == nil {
t.Error("invalid uuid was parsed without error")
}
if !strings.Contains(err.Error(), "invalid UUID") {
t.Error("attempting to parse an invalid UUID returned an incorrect error message")
}
err = (&uuid).Scan(byteTest[:len(byteTest)-2])
if err == nil {
t.Error("invalid byte uuid was parsed without error")
}
if !strings.Contains(err.Error(), "invalid UUID") {
t.Error("attempting to parse an invalid byte UUID returned an incorrect error message")
}
// empty tests
uuid = nil
var emptySlice []byte
err = (&uuid).Scan(emptySlice)
if err != nil {
t.Fatal(err)
}
if uuid != nil {
t.Error("UUID was not nil after scanning empty byte slice")
}
uuid = nil
var emptyString string
err = (&uuid).Scan(emptyString)
if err != nil {
t.Fatal(err)
}
if uuid != nil {
t.Error("UUID was not nil after scanning empty string")
}
}
func TestValue(t *testing.T) {
stringTest := "f47ac10b-58cc-0372-8567-0e02b2c3d479"
uuid := Parse(stringTest)
val, _ := uuid.Value()
if val != stringTest {
t.Error("Value() did not return expected string")
}
}
+7 -7
View File
@@ -23,7 +23,7 @@ const (
) )
var ( var (
mu sync.Mutex timeMu sync.Mutex
lasttime uint64 // last time we returned lasttime uint64 // last time we returned
clock_seq uint16 // clock sequence for this run clock_seq uint16 // clock sequence for this run
@@ -43,8 +43,8 @@ func (t Time) UnixTime() (sec, nsec int64) {
// clock sequence as well as adjusting the clock sequence as needed. An error // clock sequence as well as adjusting the clock sequence as needed. An error
// is returned if the current time cannot be determined. // is returned if the current time cannot be determined.
func GetTime() (Time, uint16, error) { func GetTime() (Time, uint16, error) {
defer mu.Unlock() defer timeMu.Unlock()
mu.Lock() timeMu.Lock()
return getTime() return getTime()
} }
@@ -75,8 +75,8 @@ func getTime() (Time, uint16, error) {
// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated // ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
// for // for
func ClockSequence() int { func ClockSequence() int {
defer mu.Unlock() defer timeMu.Unlock()
mu.Lock() timeMu.Lock()
return clockSequence() return clockSequence()
} }
@@ -90,8 +90,8 @@ func clockSequence() int {
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to // SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
// -1 causes a new sequence to be generated. // -1 causes a new sequence to be generated.
func SetClockSequence(seq int) { func SetClockSequence(seq int) {
defer mu.Unlock() defer timeMu.Unlock()
mu.Lock() timeMu.Lock()
setClockSequence(seq) setClockSequence(seq)
} }
@@ -16,7 +16,7 @@ func randomBits(b []byte) {
} }
// xvalues returns the value of a byte as a hexadecimal digit or 255. // xvalues returns the value of a byte as a hexadecimal digit or 255.
var xvalues = []byte{ var xvalues = [256]byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+52 -14
View File
@@ -7,11 +7,26 @@ package uuid
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"encoding/hex"
"fmt" "fmt"
"io" "io"
"strings" "strings"
) )
// Array is a pass-by-value UUID that can be used as an effecient key in a map.
type Array [16]byte
// UUID converts uuid into a slice.
func (uuid Array) UUID() UUID {
return uuid[:]
}
// String returns the string representation of uuid,
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (uuid Array) String() string {
return uuid.UUID().String()
}
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
// 4122. // 4122.
type UUID []byte type UUID []byte
@@ -54,8 +69,8 @@ func Parse(s string) UUID {
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
return nil return nil
} }
uuid := make([]byte, 16) var uuid [16]byte
for i, x := range []int{ for i, x := range [16]int{
0, 2, 4, 6, 0, 2, 4, 6,
9, 11, 9, 11,
14, 16, 14, 16,
@@ -67,7 +82,7 @@ func Parse(s string) UUID {
uuid[i] = v uuid[i] = v
} }
} }
return uuid return uuid[:]
} }
// Equal returns true if uuid1 and uuid2 are equal. // Equal returns true if uuid1 and uuid2 are equal.
@@ -75,26 +90,50 @@ func Equal(uuid1, uuid2 UUID) bool {
return bytes.Equal(uuid1, uuid2) return bytes.Equal(uuid1, uuid2)
} }
// Array returns an array representation of uuid that can be used as a map key.
// Array panics if uuid is not valid.
func (uuid UUID) Array() Array {
if len(uuid) != 16 {
panic("invalid uuid")
}
var a Array
copy(a[:], uuid)
return a
}
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// , or "" if uuid is invalid. // , or "" if uuid is invalid.
func (uuid UUID) String() string { func (uuid UUID) String() string {
if uuid == nil || len(uuid) != 16 { if len(uuid) != 16 {
return "" return ""
} }
b := []byte(uuid) var buf [36]byte
return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", encodeHex(buf[:], uuid)
b[:4], b[4:6], b[6:8], b[8:10], b[10:]) return string(buf[:])
} }
// URN returns the RFC 2141 URN form of uuid, // URN returns the RFC 2141 URN form of uuid,
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
func (uuid UUID) URN() string { func (uuid UUID) URN() string {
if uuid == nil || len(uuid) != 16 { if len(uuid) != 16 {
return "" return ""
} }
b := []byte(uuid) var buf [36 + 9]byte
return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x", copy(buf[:], "urn:uuid:")
b[:4], b[4:6], b[6:8], b[8:10], b[10:]) encodeHex(buf[9:], uuid)
return string(buf[:])
}
func encodeHex(dst []byte, uuid UUID) {
hex.Encode(dst[:], uuid[:4])
dst[8] = '-'
hex.Encode(dst[9:13], uuid[4:6])
dst[13] = '-'
hex.Encode(dst[14:18], uuid[6:8])
dst[18] = '-'
hex.Encode(dst[19:23], uuid[8:10])
dst[23] = '-'
hex.Encode(dst[24:], uuid[10:])
} }
// Variant returns the variant encoded in uuid. It returns Invalid if // Variant returns the variant encoded in uuid. It returns Invalid if
@@ -113,10 +152,9 @@ func (uuid UUID) Variant() Variant {
default: default:
return Reserved return Reserved
} }
panic("unreachable")
} }
// Version returns the verison of uuid. It returns false if uuid is not // Version returns the version of uuid. It returns false if uuid is not
// valid. // valid.
func (uuid UUID) Version() (Version, bool) { func (uuid UUID) Version() (Version, bool) {
if len(uuid) != 16 { if len(uuid) != 16 {
@@ -148,7 +186,7 @@ func (v Variant) String() string {
return fmt.Sprintf("BadVariant%d", int(v)) return fmt.Sprintf("BadVariant%d", int(v))
} }
// SetRand sets the random number generator to r, which implents io.Reader. // SetRand sets the random number generator to r, which implements io.Reader.
// If r.Read returns an error when the package requests random data then // If r.Read returns an error when the package requests random data then
// a panic will be issued. // a panic will be issued.
// //
+206 -44
View File
@@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"os" "os"
"runtime"
"strings" "strings"
"testing" "testing"
"time" "time"
@@ -112,7 +113,7 @@ func TestConstants(t *testing.T) {
t.Errorf("%x: %v: not a stringer", x, v) t.Errorf("%x: %v: not a stringer", x, v)
} else if s := v.String(); s != tt.name { } else if s := v.String(); s != tt.name {
v, _ := tt.c.(int) v, _ := tt.c.(int)
t.Errorf("%x: Constant %T:%d gives %q, expected %q\n", x, tt.c, v, s, tt.name) t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name)
} }
} }
} }
@@ -123,14 +124,14 @@ func TestRandomUUID(t *testing.T) {
uuid := NewRandom() uuid := NewRandom()
s := uuid.String() s := uuid.String()
if m[s] { if m[s] {
t.Errorf("NewRandom returned duplicated UUID %s\n", s) t.Errorf("NewRandom returned duplicated UUID %s", s)
} }
m[s] = true m[s] = true
if v, _ := uuid.Version(); v != 4 { if v, _ := uuid.Version(); v != 4 {
t.Errorf("Random UUID of version %s\n", v) t.Errorf("Random UUID of version %s", v)
} }
if uuid.Variant() != RFC4122 { if uuid.Variant() != RFC4122 {
t.Errorf("Random UUID is variant %d\n", uuid.Variant()) t.Errorf("Random UUID is variant %d", uuid.Variant())
} }
} }
} }
@@ -140,19 +141,19 @@ func TestNew(t *testing.T) {
for x := 1; x < 32; x++ { for x := 1; x < 32; x++ {
s := New() s := New()
if m[s] { if m[s] {
t.Errorf("New returned duplicated UUID %s\n", s) t.Errorf("New returned duplicated UUID %s", s)
} }
m[s] = true m[s] = true
uuid := Parse(s) uuid := Parse(s)
if uuid == nil { if uuid == nil {
t.Errorf("New returned %q which does not decode\n", s) t.Errorf("New returned %q which does not decode", s)
continue continue
} }
if v, _ := uuid.Version(); v != 4 { if v, _ := uuid.Version(); v != 4 {
t.Errorf("Random UUID of version %s\n", v) t.Errorf("Random UUID of version %s", v)
} }
if uuid.Variant() != RFC4122 { if uuid.Variant() != RFC4122 {
t.Errorf("Random UUID is variant %d\n", uuid.Variant()) t.Errorf("Random UUID is variant %d", uuid.Variant())
} }
} }
} }
@@ -160,7 +161,7 @@ func TestNew(t *testing.T) {
func clockSeq(t *testing.T, uuid UUID) int { func clockSeq(t *testing.T, uuid UUID) int {
seq, ok := uuid.ClockSequence() seq, ok := uuid.ClockSequence()
if !ok { if !ok {
t.Fatalf("%s: invalid clock sequence\n", uuid) t.Fatalf("%s: invalid clock sequence", uuid)
} }
return seq return seq
} }
@@ -179,7 +180,7 @@ func TestClockSeq(t *testing.T) {
uuid2 := NewUUID() uuid2 := NewUUID()
if clockSeq(t, uuid1) != clockSeq(t, uuid2) { if clockSeq(t, uuid1) != clockSeq(t, uuid2) {
t.Errorf("clock sequence %d != %d\n", clockSeq(t, uuid1), clockSeq(t, uuid2)) t.Errorf("clock sequence %d != %d", clockSeq(t, uuid1), clockSeq(t, uuid2))
} }
SetClockSequence(-1) SetClockSequence(-1)
@@ -192,13 +193,13 @@ func TestClockSeq(t *testing.T) {
uuid2 = NewUUID() uuid2 = NewUUID()
} }
if clockSeq(t, uuid1) == clockSeq(t, uuid2) { if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
t.Errorf("Duplicate clock sequence %d\n", clockSeq(t, uuid1)) t.Errorf("Duplicate clock sequence %d", clockSeq(t, uuid1))
} }
SetClockSequence(0x1234) SetClockSequence(0x1234)
uuid1 = NewUUID() uuid1 = NewUUID()
if seq := clockSeq(t, uuid1); seq != 0x1234 { if seq := clockSeq(t, uuid1); seq != 0x1234 {
t.Errorf("%s: expected seq 0x1234 got 0x%04x\n", uuid1, seq) t.Errorf("%s: expected seq 0x1234 got 0x%04x", uuid1, seq)
} }
} }
@@ -213,15 +214,15 @@ func TestCoding(t *testing.T) {
0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2, 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
} }
if v := data.String(); v != text { if v := data.String(); v != text {
t.Errorf("%x: encoded to %s, expected %s\n", data, v, text) t.Errorf("%x: encoded to %s, expected %s", data, v, text)
} }
if v := data.URN(); v != urn { if v := data.URN(); v != urn {
t.Errorf("%x: urn is %s, expected %s\n", data, v, urn) t.Errorf("%x: urn is %s, expected %s", data, v, urn)
} }
uuid := Parse(text) uuid := Parse(text)
if !Equal(uuid, data) { if !Equal(uuid, data) {
t.Errorf("%s: decoded to %s, expected %s\n", text, uuid, data) t.Errorf("%s: decoded to %s, expected %s", text, uuid, data)
} }
} }
@@ -230,30 +231,30 @@ func TestVersion1(t *testing.T) {
uuid2 := NewUUID() uuid2 := NewUUID()
if Equal(uuid1, uuid2) { if Equal(uuid1, uuid2) {
t.Errorf("%s:duplicate uuid\n", uuid1) t.Errorf("%s:duplicate uuid", uuid1)
} }
if v, _ := uuid1.Version(); v != 1 { if v, _ := uuid1.Version(); v != 1 {
t.Errorf("%s: version %s expected 1\n", uuid1, v) t.Errorf("%s: version %s expected 1", uuid1, v)
} }
if v, _ := uuid2.Version(); v != 1 { if v, _ := uuid2.Version(); v != 1 {
t.Errorf("%s: version %s expected 1\n", uuid2, v) t.Errorf("%s: version %s expected 1", uuid2, v)
} }
n1 := uuid1.NodeID() n1 := uuid1.NodeID()
n2 := uuid2.NodeID() n2 := uuid2.NodeID()
if !bytes.Equal(n1, n2) { if !bytes.Equal(n1, n2) {
t.Errorf("Different nodes %x != %x\n", n1, n2) t.Errorf("Different nodes %x != %x", n1, n2)
} }
t1, ok := uuid1.Time() t1, ok := uuid1.Time()
if !ok { if !ok {
t.Errorf("%s: invalid time\n", uuid1) t.Errorf("%s: invalid time", uuid1)
} }
t2, ok := uuid2.Time() t2, ok := uuid2.Time()
if !ok { if !ok {
t.Errorf("%s: invalid time\n", uuid2) t.Errorf("%s: invalid time", uuid2)
} }
q1, ok := uuid1.ClockSequence() q1, ok := uuid1.ClockSequence()
if !ok { if !ok {
t.Errorf("%s: invalid clock sequence\n", uuid1) t.Errorf("%s: invalid clock sequence", uuid1)
} }
q2, ok := uuid2.ClockSequence() q2, ok := uuid2.ClockSequence()
if !ok { if !ok {
@@ -262,11 +263,58 @@ func TestVersion1(t *testing.T) {
switch { switch {
case t1 == t2 && q1 == q2: case t1 == t2 && q1 == q2:
t.Errorf("time stopped\n") t.Error("time stopped")
case t1 > t2 && q1 == q2: case t1 > t2 && q1 == q2:
t.Errorf("time reversed\n") t.Error("time reversed")
case t1 < t2 && q1 != q2: case t1 < t2 && q1 != q2:
t.Errorf("clock sequence chaned unexpectedly\n") t.Error("clock sequence chaned unexpectedly")
}
}
func TestNode(t *testing.T) {
// This test is mostly to make sure we don't leave nodeMu locked.
ifname = ""
if ni := NodeInterface(); ni != "" {
t.Errorf("NodeInterface got %q, want %q", ni, "")
}
nodeID = nil // Reset global state for next test
if SetNodeInterface("xyzzy") {
t.Error("SetNodeInterface succeeded on a bad interface name")
}
nodeID = nil // Reset global state for next test
if !SetNodeInterface("") {
t.Error("SetNodeInterface failed")
}
if runtime.GOARCH != "js" {
if ni := NodeInterface(); ni == "" {
t.Error("NodeInterface returned an empty string")
}
}
ni := NodeID()
if len(ni) != 6 {
t.Errorf("ni got %d bytes, want 6", len(ni))
}
hasData := false
for _, b := range ni {
if b != 0 {
hasData = true
}
}
if !hasData {
t.Error("nodeid is all zeros")
}
id := []byte{1, 2, 3, 4, 5, 6, 7, 8}
SetNodeID(id)
ni = NodeID()
if !bytes.Equal(ni, id[:6]) {
t.Errorf("got nodeid %v, want %v", ni, id[:6])
}
if ni := NodeInterface(); ni != "user" {
t.Errorf("got inteface %q, want %q", ni, "user")
} }
} }
@@ -284,10 +332,10 @@ func TestNodeAndTime(t *testing.T) {
t.Errorf("Got time %v, want %v", c, want) t.Errorf("Got time %v, want %v", c, want)
} }
} else { } else {
t.Errorf("%s: bad time\n", uuid) t.Errorf("%s: bad time", uuid)
} }
if !bytes.Equal(node, uuid.NodeID()) { if !bytes.Equal(node, uuid.NodeID()) {
t.Errorf("Expected node %v got %v\n", node, uuid.NodeID()) t.Errorf("Expected node %v got %v", node, uuid.NodeID())
} }
} }
@@ -295,7 +343,7 @@ func TestMD5(t *testing.T) {
uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String() uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String()
want := "6fa459ea-ee8a-3ca4-894e-db77e160355e" want := "6fa459ea-ee8a-3ca4-894e-db77e160355e"
if uuid != want { if uuid != want {
t.Errorf("MD5: got %q expected %q\n", uuid, want) t.Errorf("MD5: got %q expected %q", uuid, want)
} }
} }
@@ -303,58 +351,61 @@ func TestSHA1(t *testing.T) {
uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String() uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String()
want := "886313e1-3b8a-5372-9b90-0c9aee199e5d" want := "886313e1-3b8a-5372-9b90-0c9aee199e5d"
if uuid != want { if uuid != want {
t.Errorf("SHA1: got %q expected %q\n", uuid, want) t.Errorf("SHA1: got %q expected %q", uuid, want)
} }
} }
func TestNodeID(t *testing.T) { func TestNodeID(t *testing.T) {
nid := []byte{1, 2, 3, 4, 5, 6} nid := []byte{1, 2, 3, 4, 5, 6}
nodeID = nil // Reset global state for next test
SetNodeInterface("") SetNodeInterface("")
s := NodeInterface() s := NodeInterface()
if s == "" || s == "user" { if runtime.GOARCH != "js" {
t.Errorf("NodeInterface %q after SetInteface\n", s) if s == "" || s == "user" {
t.Errorf("NodeInterface %q after SetInterface", s)
}
} }
node1 := NodeID() node1 := NodeID()
if node1 == nil { if node1 == nil {
t.Errorf("NodeID nil after SetNodeInterface\n", s) t.Error("NodeID nil after SetNodeInterface", s)
} }
SetNodeID(nid) SetNodeID(nid)
s = NodeInterface() s = NodeInterface()
if s != "user" { if s != "user" {
t.Errorf("Expected NodeInterface %q got %q\n", "user", s) t.Errorf("Expected NodeInterface %q got %q", "user", s)
} }
node2 := NodeID() node2 := NodeID()
if node2 == nil { if node2 == nil {
t.Errorf("NodeID nil after SetNodeID\n", s) t.Error("NodeID nil after SetNodeID", s)
} }
if bytes.Equal(node1, node2) { if bytes.Equal(node1, node2) {
t.Errorf("NodeID not changed after SetNodeID\n", s) t.Error("NodeID not changed after SetNodeID", s)
} else if !bytes.Equal(nid, node2) { } else if !bytes.Equal(nid, node2) {
t.Errorf("NodeID is %x, expected %x\n", node2, nid) t.Errorf("NodeID is %x, expected %x", node2, nid)
} }
} }
func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) { func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) {
if uuid == nil { if uuid == nil {
t.Errorf("%s failed\n", name) t.Errorf("%s failed", name)
return return
} }
if v, _ := uuid.Version(); v != 2 { if v, _ := uuid.Version(); v != 2 {
t.Errorf("%s: %s: expected version 2, got %s\n", name, uuid, v) t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v)
return return
} }
if v, ok := uuid.Domain(); !ok || v != domain { if v, ok := uuid.Domain(); !ok || v != domain {
if !ok { if !ok {
t.Errorf("%s: %d: Domain failed\n", name, uuid) t.Errorf("%s: %d: Domain failed", name, uuid)
} else { } else {
t.Errorf("%s: %s: expected domain %d, got %d\n", name, uuid, domain, v) t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v)
} }
} }
if v, ok := uuid.Id(); !ok || v != id { if v, ok := uuid.Id(); !ok || v != id {
if !ok { if !ok {
t.Errorf("%s: %d: Id failed\n", name, uuid) t.Errorf("%s: %d: Id failed", name, uuid)
} else { } else {
t.Errorf("%s: %s: expected id %d, got %d\n", name, uuid, id, v) t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v)
} }
} }
} }
@@ -379,12 +430,123 @@ func TestBadRand(t *testing.T) {
uuid1 := New() uuid1 := New()
uuid2 := New() uuid2 := New()
if uuid1 != uuid2 { if uuid1 != uuid2 {
t.Errorf("execpted duplicates, got %q and %q\n", uuid1, uuid2) t.Errorf("expected duplicates, got %q and %q", uuid1, uuid2)
} }
SetRand(nil) SetRand(nil)
uuid1 = New() uuid1 = New()
uuid2 = New() uuid2 = New()
if uuid1 == uuid2 { if uuid1 == uuid2 {
t.Errorf("unexecpted duplicates, got %q\n", uuid1) t.Errorf("unexpected duplicates, got %q", uuid1)
}
}
func TestUUID_Array(t *testing.T) {
expect := Array{
0xf4, 0x7a, 0xc1, 0x0b,
0x58, 0xcc,
0x03, 0x72,
0x85, 0x67,
0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
}
uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if uuid == nil {
t.Fatal("invalid uuid")
}
if uuid.Array() != expect {
t.Fatal("invalid array")
}
}
func TestArray_UUID(t *testing.T) {
array := Array{
0xf4, 0x7a, 0xc1, 0x0b,
0x58, 0xcc,
0x03, 0x72,
0x85, 0x67,
0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
}
expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if expect == nil {
t.Fatal("invalid uuid")
}
if !bytes.Equal(array.UUID(), expect) {
t.Fatal("invalid uuid")
}
}
func BenchmarkParse(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if uuid == nil {
b.Fatal("invalid uuid")
}
}
}
func BenchmarkNew(b *testing.B) {
for i := 0; i < b.N; i++ {
New()
}
}
func BenchmarkUUID_String(b *testing.B) {
uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if uuid == nil {
b.Fatal("invalid uuid")
}
for i := 0; i < b.N; i++ {
if uuid.String() == "" {
b.Fatal("invalid uuid")
}
}
}
func BenchmarkUUID_URN(b *testing.B) {
uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if uuid == nil {
b.Fatal("invalid uuid")
}
for i := 0; i < b.N; i++ {
if uuid.URN() == "" {
b.Fatal("invalid uuid")
}
}
}
func BenchmarkUUID_Array(b *testing.B) {
expect := Array{
0xf4, 0x7a, 0xc1, 0x0b,
0x58, 0xcc,
0x03, 0x72,
0x85, 0x67,
0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
}
uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if uuid == nil {
b.Fatal("invalid uuid")
}
for i := 0; i < b.N; i++ {
if uuid.Array() != expect {
b.Fatal("invalid array")
}
}
}
func BenchmarkArray_UUID(b *testing.B) {
array := Array{
0xf4, 0x7a, 0xc1, 0x0b,
0x58, 0xcc,
0x03, 0x72,
0x85, 0x67,
0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
}
expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if expect == nil {
b.Fatal("invalid uuid")
}
for i := 0; i < b.N; i++ {
if !bytes.Equal(array.UUID(), expect) {
b.Fatal("invalid uuid")
}
} }
} }
@@ -15,9 +15,7 @@ import (
// SetClockSequence then it will be set automatically. If GetTime fails to // SetClockSequence then it will be set automatically. If GetTime fails to
// return the current NewUUID returns nil. // return the current NewUUID returns nil.
func NewUUID() UUID { func NewUUID() UUID {
if nodeID == nil { SetNodeInterface("")
SetNodeInterface("")
}
now, seq, err := GetTime() now, seq, err := GetTime()
if err != nil { if err != nil {
-1
View File
@@ -1 +0,0 @@
defaultcc: borman@google.com
File diff suppressed because it is too large Load Diff
-30
View File
@@ -1,30 +0,0 @@
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "errors"
func (u UUID) MarshalJSON() ([]byte, error) {
if len(u) == 0 {
return []byte(`""`), nil
}
return []byte(`"` + u.String() + `"`), nil
}
func (u *UUID) UnmarshalJSON(data []byte) error {
if len(data) == 0 || string(data) == `""` {
return nil
}
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
return errors.New("invalid UUID format")
}
data = data[1 : len(data)-1]
uu := Parse(string(data))
if uu == nil {
return errors.New("invalid UUID format")
}
*u = uu
return nil
}
-32
View File
@@ -1,32 +0,0 @@
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/json"
"reflect"
"testing"
)
var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
func TestJSON(t *testing.T) {
type S struct {
ID1 UUID
ID2 UUID
}
s1 := S{ID1: testUUID}
data, err := json.Marshal(&s1)
if err != nil {
t.Fatal(err)
}
var s2 S
if err := json.Unmarshal(data, &s2); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(&s1, &s2) {
t.Errorf("got %#v, want %#v", s2, s1)
}
}