1
0
Fork 0
mirror of https://github.com/Luzifer/tex-api.git synced 2024-11-08 16:20:04 +00:00

Update imports

- Sirupsen/logrus was renamed
- satori/go.uuid is deprecated

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2018-09-17 11:54:14 +02:00
parent 22bfae955d
commit 5e470b62fe
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
27 changed files with 525 additions and 353 deletions

20
Gopkg.lock generated
View file

@ -18,12 +18,12 @@
version = "v2.1.0" version = "v2.1.0"
[[projects]] [[projects]]
digest = "1:b2339e83ce9b5c4f79405f949429a7f68a9a904fed903c672aac1e7ceb7f5f02" digest = "1:100f874677364387717ee2becf81bede9b2475634958a54accac40a2b8866773"
name = "github.com/Sirupsen/logrus" name = "github.com/gofrs/uuid"
packages = ["."] packages = ["."]
pruneopts = "NUT" pruneopts = "NUT"
revision = "3e01752db0189b9157070a0e1668a620f9a85da2" revision = "370558f003bfe29580cd0f698d8640daccdcc45c"
version = "v1.0.6" version = "v3.1.1"
[[projects]] [[projects]]
digest = "1:c01767916c59f084bb7c41a7d5877c0f3099b1595cfa066e84ec6ad6b084dd89" digest = "1:c01767916c59f084bb7c41a7d5877c0f3099b1595cfa066e84ec6ad6b084dd89"
@ -42,12 +42,12 @@
version = "v1.6.2" version = "v1.6.2"
[[projects]] [[projects]]
digest = "1:6bc0652ea6e39e22ccd522458b8bdd8665bf23bdc5a20eec90056e4dc7e273ca" digest = "1:b2339e83ce9b5c4f79405f949429a7f68a9a904fed903c672aac1e7ceb7f5f02"
name = "github.com/satori/go.uuid" name = "github.com/sirupsen/logrus"
packages = ["."] packages = ["."]
pruneopts = "NUT" pruneopts = "NUT"
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
version = "v1.2.0" version = "v1.0.6"
[[projects]] [[projects]]
digest = "1:e3707aeaccd2adc89eba6c062fec72116fe1fc1ba71097da85b4d8ae1668a675" digest = "1:e3707aeaccd2adc89eba6c062fec72116fe1fc1ba71097da85b4d8ae1668a675"
@ -98,9 +98,9 @@
input-imports = [ input-imports = [
"github.com/Luzifer/go_helpers/str", "github.com/Luzifer/go_helpers/str",
"github.com/Luzifer/rconfig", "github.com/Luzifer/rconfig",
"github.com/Sirupsen/logrus", "github.com/gofrs/uuid",
"github.com/gorilla/mux", "github.com/gorilla/mux",
"github.com/satori/go.uuid", "github.com/sirupsen/logrus",
] ]
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View file

@ -34,16 +34,16 @@
version = "2.1.0" version = "2.1.0"
[[constraint]] [[constraint]]
name = "github.com/Sirupsen/logrus" name = "github.com/gofrs/uuid"
version = "1.0.6" version = "3.1.1"
[[constraint]] [[constraint]]
name = "github.com/gorilla/mux" name = "github.com/gorilla/mux"
version = "1.6.2" version = "1.6.2"
[[constraint]] [[constraint]]
name = "github.com/satori/go.uuid" name = "github.com/sirupsen/logrus"
version = "1.2.0" version = "1.0.6"
[prune] [prune]
non-go = true non-go = true

View file

@ -11,7 +11,8 @@ import (
"strings" "strings"
"github.com/Luzifer/go_helpers/str" "github.com/Luzifer/go_helpers/str"
uuid "github.com/satori/go.uuid"
"github.com/gofrs/uuid"
) )
func shouldPackFile(extension string) bool { func shouldPackFile(extension string) bool {

View file

@ -14,9 +14,10 @@ import (
"time" "time"
"github.com/Luzifer/rconfig" "github.com/Luzifer/rconfig"
log "github.com/Sirupsen/logrus"
"github.com/gofrs/uuid"
"github.com/gorilla/mux" "github.com/gorilla/mux"
uuid "github.com/satori/go.uuid" log "github.com/sirupsen/logrus"
) )
var ( var (
@ -129,7 +130,7 @@ func apiDocs(res http.ResponseWriter, r *http.Request) {
} }
func startNewJob(res http.ResponseWriter, r *http.Request) { func startNewJob(res http.ResponseWriter, r *http.Request) {
jobUUID := uuid.NewV4() jobUUID := uuid.Must(uuid.NewV4())
inputFile := pathFromUUID(jobUUID, filenameInput) inputFile := pathFromUUID(jobUUID, filenameInput)
statusFile := pathFromUUID(jobUUID, filenameStatus) statusFile := pathFromUUID(jobUUID, filenameStatus)

View file

@ -27,15 +27,16 @@ import (
"fmt" "fmt"
) )
// FromBytes returns UUID converted from raw byte slice input. // FromBytes returns a UUID generated from the raw byte slice input.
// It will return error if the slice isn't 16 bytes long. // It will return an error if the slice isn't 16 bytes long.
func FromBytes(input []byte) (u UUID, err error) { func FromBytes(input []byte) (UUID, error) {
err = u.UnmarshalBinary(input) u := UUID{}
return err := u.UnmarshalBinary(input)
return u, err
} }
// FromBytesOrNil returns UUID converted from raw byte slice input. // FromBytesOrNil returns a UUID generated from the raw byte slice input.
// Same behavior as FromBytes, but returns a Nil UUID on error. // Same behavior as FromBytes(), but returns uuid.Nil instead of an error.
func FromBytesOrNil(input []byte) UUID { func FromBytesOrNil(input []byte) UUID {
uuid, err := FromBytes(input) uuid, err := FromBytes(input)
if err != nil { if err != nil {
@ -44,15 +45,16 @@ func FromBytesOrNil(input []byte) UUID {
return uuid return uuid
} }
// FromString returns UUID parsed from string input. // FromString returns a UUID parsed from the input string.
// Input is expected in a form accepted by UnmarshalText. // Input is expected in a form accepted by UnmarshalText.
func FromString(input string) (u UUID, err error) { func FromString(input string) (UUID, error) {
err = u.UnmarshalText([]byte(input)) u := UUID{}
return err := u.UnmarshalText([]byte(input))
return u, err
} }
// FromStringOrNil returns UUID parsed from string input. // FromStringOrNil returns a UUID parsed from the input string.
// Same behavior as FromString, but returns a Nil UUID on error. // Same behavior as FromString(), but returns uuid.Nil instead of an error.
func FromStringOrNil(input string) UUID { func FromStringOrNil(input string) UUID {
uuid, err := FromString(input) uuid, err := FromString(input)
if err != nil { if err != nil {
@ -62,55 +64,63 @@ func FromStringOrNil(input string) UUID {
} }
// MarshalText implements the encoding.TextMarshaler interface. // MarshalText implements the encoding.TextMarshaler interface.
// The encoding is the same as returned by String. // The encoding is the same as returned by the String() method.
func (u UUID) MarshalText() (text []byte, err error) { func (u UUID) MarshalText() ([]byte, error) {
text = []byte(u.String()) return []byte(u.String()), nil
return
} }
// UnmarshalText implements the encoding.TextUnmarshaler interface. // UnmarshalText implements the encoding.TextUnmarshaler interface.
// Following formats are supported: // Following formats are supported:
//
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", // "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
// "6ba7b8109dad11d180b400c04fd430c8" // "6ba7b8109dad11d180b400c04fd430c8"
// "{6ba7b8109dad11d180b400c04fd430c8}",
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8"
//
// ABNF for supported UUID text representation follows: // ABNF for supported UUID text representation follows:
// uuid := canonical | hashlike | braced | urn //
// plain := canonical | hashlike
// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
// hashlike := 12hexoct
// braced := '{' plain '}'
// urn := URN ':' UUID-NID ':' plain
// URN := 'urn' // URN := 'urn'
// UUID-NID := 'uuid' // UUID-NID := 'uuid'
// 12hexoct := 6hexoct 6hexoct //
// 6hexoct := 4hexoct 2hexoct
// 4hexoct := 2hexoct 2hexoct
// 2hexoct := hexoct hexoct
// hexoct := hexdig hexdig
// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | // hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | // 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' // 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
func (u *UUID) UnmarshalText(text []byte) (err error) { //
// hexoct := hexdig hexdig
// 2hexoct := hexoct hexoct
// 4hexoct := 2hexoct 2hexoct
// 6hexoct := 4hexoct 2hexoct
// 12hexoct := 6hexoct 6hexoct
//
// hashlike := 12hexoct
// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
//
// plain := canonical | hashlike
// uuid := canonical | hashlike | braced | urn
//
// braced := '{' plain '}' | '{' hashlike '}'
// urn := URN ':' UUID-NID ':' plain
//
func (u *UUID) UnmarshalText(text []byte) error {
switch len(text) { switch len(text) {
case 32: case 32:
return u.decodeHashLike(text) return u.decodeHashLike(text)
case 34, 38:
return u.decodeBraced(text)
case 36: case 36:
return u.decodeCanonical(text) return u.decodeCanonical(text)
case 38: case 41, 45:
return u.decodeBraced(text)
case 41:
fallthrough
case 45:
return u.decodeURN(text) return u.decodeURN(text)
default: default:
return fmt.Errorf("uuid: incorrect UUID length: %s", text) return fmt.Errorf("uuid: incorrect UUID length: %s", text)
} }
} }
// decodeCanonical decodes UUID string in format // decodeCanonical decodes UUID strings that are formatted as defined in RFC-4122 (section 3):
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8". // "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
func (u *UUID) decodeCanonical(t []byte) (err error) { func (u *UUID) decodeCanonical(t []byte) error {
if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' {
return fmt.Errorf("uuid: incorrect UUID format %s", t) return fmt.Errorf("uuid: incorrect UUID format %s", t)
} }
@ -122,33 +132,33 @@ func (u *UUID) decodeCanonical(t []byte) (err error) {
if i > 0 { if i > 0 {
src = src[1:] // skip dash src = src[1:] // skip dash
} }
_, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup]) _, err := hex.Decode(dst[:byteGroup/2], src[:byteGroup])
if err != nil { if err != nil {
return return err
} }
src = src[byteGroup:] src = src[byteGroup:]
dst = dst[byteGroup/2:] dst = dst[byteGroup/2:]
} }
return return nil
} }
// decodeHashLike decodes UUID string in format // decodeHashLike decodes UUID strings that are using the following format:
// "6ba7b8109dad11d180b400c04fd430c8". // "6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodeHashLike(t []byte) (err error) { func (u *UUID) decodeHashLike(t []byte) error {
src := t[:] src := t[:]
dst := u[:] dst := u[:]
if _, err = hex.Decode(dst, src); err != nil { if _, err := hex.Decode(dst, src); err != nil {
return err return err
} }
return return nil
} }
// decodeBraced decodes UUID string in format // decodeBraced decodes UUID strings that are using the following formats:
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
// "{6ba7b8109dad11d180b400c04fd430c8}". // "{6ba7b8109dad11d180b400c04fd430c8}".
func (u *UUID) decodeBraced(t []byte) (err error) { func (u *UUID) decodeBraced(t []byte) error {
l := len(t) l := len(t)
if t[0] != '{' || t[l-1] != '}' { if t[0] != '{' || t[l-1] != '}' {
@ -158,25 +168,25 @@ func (u *UUID) decodeBraced(t []byte) (err error) {
return u.decodePlain(t[1 : l-1]) return u.decodePlain(t[1 : l-1])
} }
// decodeURN decodes UUID string in format // decodeURN decodes UUID strings that are using the following formats:
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". // "urn:uuid:6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodeURN(t []byte) (err error) { func (u *UUID) decodeURN(t []byte) error {
total := len(t) total := len(t)
urn_uuid_prefix := t[:9] urnUUIDPrefix := t[:9]
if !bytes.Equal(urn_uuid_prefix, urnPrefix) { if !bytes.Equal(urnUUIDPrefix, urnPrefix) {
return fmt.Errorf("uuid: incorrect UUID format: %s", t) return fmt.Errorf("uuid: incorrect UUID format: %s", t)
} }
return u.decodePlain(t[9:total]) return u.decodePlain(t[9:total])
} }
// decodePlain decodes UUID string in canonical format // decodePlain decodes UUID strings that are using the following formats:
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format // "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format
// "6ba7b8109dad11d180b400c04fd430c8". // "6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodePlain(t []byte) (err error) { func (u *UUID) decodePlain(t []byte) error {
switch len(t) { switch len(t) {
case 32: case 32:
return u.decodeHashLike(t) return u.decodeHashLike(t)
@ -188,19 +198,17 @@ func (u *UUID) decodePlain(t []byte) (err error) {
} }
// MarshalBinary implements the encoding.BinaryMarshaler interface. // MarshalBinary implements the encoding.BinaryMarshaler interface.
func (u UUID) MarshalBinary() (data []byte, err error) { func (u UUID) MarshalBinary() ([]byte, error) {
data = u.Bytes() return u.Bytes(), nil
return
} }
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
// It will return error if the slice isn't 16 bytes long. // It will return an error if the slice isn't 16 bytes long.
func (u *UUID) UnmarshalBinary(data []byte) (err error) { func (u *UUID) UnmarshalBinary(data []byte) error {
if len(data) != Size { if len(data) != Size {
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) return fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
return
} }
copy(u[:], data) copy(u[:], data)
return return nil
} }

47
vendor/github.com/gofrs/uuid/fuzz.go generated vendored Normal file
View file

@ -0,0 +1,47 @@
// Copyright (c) 2018 Andrei Tudor Călin <mail@acln.ro>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// +build gofuzz
package uuid
// Fuzz implements a simple fuzz test for FromString / UnmarshalText.
//
// To run:
//
// $ go get github.com/dvyukov/go-fuzz/...
// $ cd $GOPATH/src/github.com/gofrs/uuid
// $ go-fuzz-build github.com/gofrs/uuid
// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata
//
// If you make significant changes to FromString / UnmarshalText and add
// new cases to fromStringTests (in codec_test.go), please run
//
// $ go test -seed_fuzz_corpus
//
// to seed the corpus with the new interesting inputs, then run the fuzzer.
func Fuzz(data []byte) int {
_, err := FromString(string(data))
if err != nil {
return 0
}
return 1
}

299
vendor/github.com/gofrs/uuid/generator.go generated vendored Normal file
View file

@ -0,0 +1,299 @@
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"encoding/binary"
"fmt"
"hash"
"io"
"net"
"os"
"sync"
"time"
)
// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
type epochFunc func() time.Time
// HWAddrFunc is the function type used to provide hardware (MAC) addresses.
type HWAddrFunc func() (net.HardwareAddr, error)
// DefaultGenerator is the default UUID Generator used by this package.
var DefaultGenerator Generator = NewGen()
var (
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// NewV1 returns a UUID based on the current timestamp and MAC address.
func NewV1() (UUID, error) {
return DefaultGenerator.NewV1()
}
// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
func NewV2(domain byte) (UUID, error) {
return DefaultGenerator.NewV2(domain)
}
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
return DefaultGenerator.NewV3(ns, name)
}
// NewV4 returns a randomly generated UUID.
func NewV4() (UUID, error) {
return DefaultGenerator.NewV4()
}
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
return DefaultGenerator.NewV5(ns, name)
}
// Generator provides an interface for generating UUIDs.
type Generator interface {
NewV1() (UUID, error)
NewV2(domain byte) (UUID, error)
NewV3(ns UUID, name string) UUID
NewV4() (UUID, error)
NewV5(ns UUID, name string) UUID
}
// Gen is a reference UUID generator based on the specifications laid out in
// RFC-4122 and DCE 1.1: Authentication and Security Services. This type
// satisfies the Generator interface as defined in this package.
//
// For consumers who are generating V1 UUIDs, but don't want to expose the MAC
// address of the node generating the UUIDs, the NewGenWithHWAF() function has been
// provided as a convenience. See the function's documentation for more info.
//
// The authors of this package do not feel that the majority of users will need
// to obfuscate their MAC address, and so we recommend using NewGen() to create
// a new generator.
type Gen struct {
clockSequenceOnce sync.Once
hardwareAddrOnce sync.Once
storageMutex sync.Mutex
rand io.Reader
epochFunc epochFunc
hwAddrFunc HWAddrFunc
lastTime uint64
clockSequence uint16
hardwareAddr [6]byte
}
// interface check -- build will fail if *Gen doesn't satisfy Generator
var _ Generator = (*Gen)(nil)
// NewGen returns a new instance of Gen with some default values set. Most
// people should use this.
func NewGen() *Gen {
return NewGenWithHWAF(defaultHWAddrFunc)
}
// NewGenWithHWAF builds a new UUID generator with the HWAddrFunc provided. Most
// consumers should use NewGen() instead.
//
// This is used so that consumers can generate their own MAC addresses, for use
// in the generated UUIDs, if there is some concern about exposing the physical
// address of the machine generating the UUID.
//
// The Gen generator will only invoke the HWAddrFunc once, and cache that MAC
// address for all the future UUIDs generated by it. If you'd like to switch the
// MAC address being used, you'll need to create a new generator using this
// function.
func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
return &Gen{
epochFunc: time.Now,
hwAddrFunc: hwaf,
rand: rand.Reader,
}
}
// NewV1 returns a UUID based on the current timestamp and MAC address.
func (g *Gen) NewV1() (UUID, error) {
u := UUID{}
timeNow, clockSeq, err := g.getClockSequence()
if err != nil {
return Nil, err
}
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
hardwareAddr, err := g.getHardwareAddr()
if err != nil {
return Nil, err
}
copy(u[10:], hardwareAddr)
u.SetVersion(V1)
u.SetVariant(VariantRFC4122)
return u, nil
}
// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
func (g *Gen) NewV2(domain byte) (UUID, error) {
u, err := g.NewV1()
if err != nil {
return Nil, err
}
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[:], posixGID)
}
u[9] = domain
u.SetVersion(V2)
u.SetVariant(VariantRFC4122)
return u, nil
}
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
func (g *Gen) NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(V3)
u.SetVariant(VariantRFC4122)
return u
}
// NewV4 returns a randomly generated UUID.
func (g *Gen) NewV4() (UUID, error) {
u := UUID{}
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
return Nil, err
}
u.SetVersion(V4)
u.SetVariant(VariantRFC4122)
return u, nil
}
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
func (g *Gen) NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(V5)
u.SetVariant(VariantRFC4122)
return u
}
// Returns the epoch and clock sequence.
func (g *Gen) getClockSequence() (uint64, uint16, error) {
var err error
g.clockSequenceOnce.Do(func() {
buf := make([]byte, 2)
if _, err = io.ReadFull(g.rand, buf); err != nil {
return
}
g.clockSequence = binary.BigEndian.Uint16(buf)
})
if err != nil {
return 0, 0, err
}
g.storageMutex.Lock()
defer g.storageMutex.Unlock()
timeNow := g.getEpoch()
// Clock didn't change since last UUID generation.
// Should increase clock sequence.
if timeNow <= g.lastTime {
g.clockSequence++
}
g.lastTime = timeNow
return timeNow, g.clockSequence, nil
}
// Returns the hardware address.
func (g *Gen) getHardwareAddr() ([]byte, error) {
var err error
g.hardwareAddrOnce.Do(func() {
var hwAddr net.HardwareAddr
if hwAddr, err = g.hwAddrFunc(); err == nil {
copy(g.hardwareAddr[:], hwAddr)
return
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence.
if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
return
}
// Set multicast bit as recommended by RFC-4122
g.hardwareAddr[0] |= 0x01
})
if err != nil {
return []byte{}, err
}
return g.hardwareAddr[:], nil
}
// Returns the difference between UUID epoch (October 15, 1582)
// and current time in 100-nanosecond intervals.
func (g *Gen) getEpoch() uint64 {
return epochStart + uint64(g.epochFunc().UnixNano()/100)
}
// Returns the UUID based on the hashing of the namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))
return u
}
// Returns the hardware address.
func defaultHWAddrFunc() (net.HardwareAddr, error) {
ifaces, err := net.Interfaces()
if err != nil {
return []byte{}, err
}
for _, iface := range ifaces {
if len(iface.HardwareAddr) >= 6 {
return iface.HardwareAddr, nil
}
}
return []byte{}, fmt.Errorf("uuid: no HW address found")
}

View file

@ -22,7 +22,9 @@
package uuid package uuid
import ( import (
"bytes"
"database/sql/driver" "database/sql/driver"
"encoding/json"
"fmt" "fmt"
) )
@ -32,8 +34,8 @@ func (u UUID) Value() (driver.Value, error) {
} }
// Scan implements the sql.Scanner interface. // Scan implements the sql.Scanner interface.
// A 16-byte slice is handled by UnmarshalBinary, while // A 16-byte slice will be handled by UnmarshalBinary, while
// a longer byte slice or a string is handled by UnmarshalText. // a longer byte slice or a string will be handled by UnmarshalText.
func (u *UUID) Scan(src interface{}) error { func (u *UUID) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case []byte: case []byte:
@ -50,7 +52,7 @@ func (u *UUID) Scan(src interface{}) error {
} }
// NullUUID can be used with the standard sql package to represent a // NullUUID can be used with the standard sql package to represent a
// UUID value that can be NULL in the database // UUID value that can be NULL in the database.
type NullUUID struct { type NullUUID struct {
UUID UUID UUID UUID
Valid bool Valid bool
@ -76,3 +78,28 @@ func (u *NullUUID) Scan(src interface{}) error {
u.Valid = true u.Valid = true
return u.UUID.Scan(src) return u.UUID.Scan(src)
} }
// MarshalJSON marshals the NullUUID as null or the nested UUID
func (u NullUUID) MarshalJSON() ([]byte, error) {
if !u.Valid {
return json.Marshal(nil)
}
return json.Marshal(u.UUID)
}
// UnmarshalJSON unmarshals a NullUUID
func (u *NullUUID) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("null")) {
u.UUID, u.Valid = Nil, false
return nil
}
if err := json.Unmarshal(b, &u.UUID); err != nil {
return err
}
u.Valid = true
return nil
}

View file

@ -19,31 +19,37 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Package uuid provides implementation of Universally Unique Identifier (UUID). // Package uuid provides implementations of the Universally Unique Identifier (UUID), as specified in RFC-4122 and DCE 1.1.
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and //
// version 2 (as specified in DCE 1.1). // RFC-4122[1] provides the specification for versions 1, 3, 4, and 5.
//
// DCE 1.1[2] provides the specification for version 2.
//
// [1] https://tools.ietf.org/html/rfc4122
// [2] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01
package uuid package uuid
import ( import (
"bytes" "encoding/binary"
"encoding/hex" "encoding/hex"
"fmt"
"time"
) )
// Size of a UUID in bytes. // Size of a UUID in bytes.
const Size = 16 const Size = 16
// UUID representation compliant with specification // UUID is an array type to represent the value of a UUID, as defined in RFC-4122.
// described in RFC 4122.
type UUID [Size]byte type UUID [Size]byte
// UUID versions // UUID versions.
const ( const (
_ byte = iota _ byte = iota
V1 V1 // Version 1 (date-time and MAC address)
V2 V2 // Version 2 (date-time and MAC address, DCE security version)
V3 V3 // Version 3 (namespace name-based)
V4 V4 // Version 4 (random)
V5 V5 // Version 5 (namespace name-based)
) )
// UUID layout variants. // UUID layout variants.
@ -61,14 +67,41 @@ const (
DomainOrg DomainOrg
) )
// Timestamp is the count of 100-nanosecond intervals since 00:00:00.00,
// 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5
// UUIDs since they don't have an embedded timestamp.
type Timestamp uint64
const _100nsPerSecond = 10000000
// Time returns the UTC time.Time representation of a Timestamp
func (t Timestamp) Time() (time.Time, error) {
secs := uint64(t) / _100nsPerSecond
nsecs := 100 * (uint64(t) % _100nsPerSecond)
return time.Unix(int64(secs)-(epochStart/_100nsPerSecond), int64(nsecs)), nil
}
// TimestampFromV1 returns the Timestamp embedded within a V1 UUID.
// Returns an error if the UUID is any version other than 1.
func TimestampFromV1(u UUID) (Timestamp, error) {
if u.Version() != 1 {
err := fmt.Errorf("uuid: %s is version %d, not version 1", u, u.Version())
return 0, err
}
low := binary.BigEndian.Uint32(u[0:4])
mid := binary.BigEndian.Uint16(u[4:6])
hi := binary.BigEndian.Uint16(u[6:8]) & 0xfff
return Timestamp(uint64(low) + (uint64(mid) << 32) + (uint64(hi) << 48)), nil
}
// String parse helpers. // String parse helpers.
var ( var (
urnPrefix = []byte("urn:uuid:") urnPrefix = []byte("urn:uuid:")
byteGroups = []int{8, 4, 4, 4, 12} byteGroups = []int{8, 4, 4, 4, 12}
) )
// Nil is special form of UUID that is specified to have all // Nil is the nil UUID, as specified in RFC-4122, that has all 128 bits set to
// 128 bits set to zero. // zero.
var Nil = UUID{} var Nil = UUID{}
// Predefined namespace UUIDs. // Predefined namespace UUIDs.
@ -79,17 +112,12 @@ var (
NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
) )
// Equal returns true if u1 and u2 equals, otherwise returns false. // Version returns the algorithm version used to generate the UUID.
func Equal(u1 UUID, u2 UUID) bool {
return bytes.Equal(u1[:], u2[:])
}
// Version returns algorithm version used to generate UUID.
func (u UUID) Version() byte { func (u UUID) Version() byte {
return u[6] >> 4 return u[6] >> 4
} }
// Variant returns UUID layout variant. // Variant returns the UUID layout variant.
func (u UUID) Variant() byte { func (u UUID) Variant() byte {
switch { switch {
case (u[8] >> 7) == 0x00: case (u[8] >> 7) == 0x00:
@ -105,12 +133,12 @@ func (u UUID) Variant() byte {
} }
} }
// Bytes returns bytes slice representation of UUID. // Bytes returns a byte slice representation of the UUID.
func (u UUID) Bytes() []byte { func (u UUID) Bytes() []byte {
return u[:] return u[:]
} }
// Returns canonical string representation of UUID: // String returns a canonical RFC-4122 string representation of the UUID:
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (u UUID) String() string { func (u UUID) String() string {
buf := make([]byte, 36) buf := make([]byte, 36)
@ -128,12 +156,12 @@ func (u UUID) String() string {
return string(buf) return string(buf)
} }
// SetVersion sets version bits. // SetVersion sets the version bits.
func (u *UUID) SetVersion(v byte) { func (u *UUID) SetVersion(v byte) {
u[6] = (u[6] & 0x0f) | (v << 4) u[6] = (u[6] & 0x0f) | (v << 4)
} }
// SetVariant sets variant bits. // SetVariant sets the variant bits.
func (u *UUID) SetVariant(v byte) { func (u *UUID) SetVariant(v byte) {
switch v { switch v {
case VariantNCS: case VariantNCS:
@ -152,7 +180,7 @@ func (u *UUID) SetVariant(v byte) {
// Must is a helper that wraps a call to a function returning (UUID, error) // Must is a helper that wraps a call to a function returning (UUID, error)
// and panics if the error is non-nil. It is intended for use in variable // and panics if the error is non-nil. It is intended for use in variable
// initializations such as // initializations such as
// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")); // var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"))
func Must(u UUID, err error) UUID { func Must(u UUID, err error) UUID {
if err != nil { if err != nil {
panic(err) panic(err)

View file

@ -1,239 +0,0 @@
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"encoding/binary"
"hash"
"net"
"os"
"sync"
"time"
)
// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
var (
global = newDefaultGenerator()
epochFunc = unixTimeFunc
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
return global.NewV1()
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
return global.NewV2(domain)
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
return global.NewV3(ns, name)
}
// NewV4 returns random generated UUID.
func NewV4() UUID {
return global.NewV4()
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
return global.NewV5(ns, name)
}
// Generator provides interface for generating UUIDs.
type Generator interface {
NewV1() UUID
NewV2(domain byte) UUID
NewV3(ns UUID, name string) UUID
NewV4() UUID
NewV5(ns UUID, name string) UUID
}
// Default generator implementation.
type generator struct {
storageOnce sync.Once
storageMutex sync.Mutex
lastTime uint64
clockSequence uint16
hardwareAddr [6]byte
}
func newDefaultGenerator() Generator {
return &generator{}
}
// NewV1 returns UUID based on current timestamp and MAC address.
func (g *generator) NewV1() UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
copy(u[10:], hardwareAddr)
u.SetVersion(V1)
u.SetVariant(VariantRFC4122)
return u
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func (g *generator) NewV2(domain byte) UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[0:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[0:], posixGID)
}
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
u[9] = domain
copy(u[10:], hardwareAddr)
u.SetVersion(V2)
u.SetVariant(VariantRFC4122)
return u
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func (g *generator) NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(V3)
u.SetVariant(VariantRFC4122)
return u
}
// NewV4 returns random generated UUID.
func (g *generator) NewV4() UUID {
u := UUID{}
g.safeRandom(u[:])
u.SetVersion(V4)
u.SetVariant(VariantRFC4122)
return u
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func (g *generator) NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(V5)
u.SetVariant(VariantRFC4122)
return u
}
func (g *generator) initStorage() {
g.initClockSequence()
g.initHardwareAddr()
}
func (g *generator) initClockSequence() {
buf := make([]byte, 2)
g.safeRandom(buf)
g.clockSequence = binary.BigEndian.Uint16(buf)
}
func (g *generator) initHardwareAddr() {
interfaces, err := net.Interfaces()
if err == nil {
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
copy(g.hardwareAddr[:], iface.HardwareAddr)
return
}
}
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence
g.safeRandom(g.hardwareAddr[:])
// Set multicast bit as recommended in RFC 4122
g.hardwareAddr[0] |= 0x01
}
func (g *generator) safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}
// Returns UUID v1/v2 storage state.
// Returns epoch timestamp, clock sequence, and hardware address.
func (g *generator) getStorage() (uint64, uint16, []byte) {
g.storageOnce.Do(g.initStorage)
g.storageMutex.Lock()
defer g.storageMutex.Unlock()
timeNow := epochFunc()
// Clock changed backwards since last UUID generation.
// Should increase clock sequence.
if timeNow <= g.lastTime {
g.clockSequence++
}
g.lastTime = timeNow
return timeNow, g.clockSequence, g.hardwareAddr[:]
}
// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
return epochStart + uint64(time.Now().UnixNano()/100)
}
// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))
return u
}