From b390f3a890fd4cb9e5b58899230c07fc2e2b96ac Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Thu, 11 Jan 2018 16:31:24 +0000 Subject: [PATCH] Vendoring github.com/marstr/guid --- vendor/github.com/marstr/guid/LICENSE.txt | 21 ++ vendor/github.com/marstr/guid/README.md | 27 ++ vendor/github.com/marstr/guid/guid.go | 301 ++++++++++++++++++++++ vendor/vendor.json | 6 + 4 files changed, 355 insertions(+) create mode 100644 vendor/github.com/marstr/guid/LICENSE.txt create mode 100644 vendor/github.com/marstr/guid/README.md create mode 100644 vendor/github.com/marstr/guid/guid.go diff --git a/vendor/github.com/marstr/guid/LICENSE.txt b/vendor/github.com/marstr/guid/LICENSE.txt new file mode 100644 index 000000000000..e18a0841a1c4 --- /dev/null +++ b/vendor/github.com/marstr/guid/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Martin Strobel + +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. \ No newline at end of file diff --git a/vendor/github.com/marstr/guid/README.md b/vendor/github.com/marstr/guid/README.md new file mode 100644 index 000000000000..355fad16d273 --- /dev/null +++ b/vendor/github.com/marstr/guid/README.md @@ -0,0 +1,27 @@ +[![Build Status](https://travis-ci.org/marstr/guid.svg?branch=master)](https://travis-ci.org/marstr/guid) +[![GoDoc](https://godoc.org/github.com/marstr/guid?status.svg)](https://godoc.org/github.com/marstr/guid) +[![Go Report Card](https://goreportcard.com/badge/github.com/marstr/guid)](https://goreportcard.com/report/github.com/marstr/guid) + +# Guid +Globally unique identifiers offer a quick means of generating non-colliding values across a distributed system. For this implemenation, [RFC 4122](http://ietf.org/rfc/rfc4122.txt) governs the desired behavior. + +## What's in a name? +You have likely already noticed that RFC and some implementations refer to these structures as UUIDs (Universally Unique Identifiers), where as this project is annotated as GUIDs (Globally Unique Identifiers). The name Guid was selected to make clear this project's ties to the [.NET struct Guid.](https://msdn.microsoft.com/en-us/library/system.guid(v=vs.110).aspx) The most obvious relationship is the desire to have the same format specifiers available in this library's Format and Parse methods as .NET would have in its ToString and Parse methods. + +# Installation +- Ensure you have the [Go Programming Language](https://golang.org/) installed on your system. +- Run the command: `go get -u github.com/marstr/guid` + +# Contribution +Contributions are welcome! Feel free to send Pull Requests. Continuous Integration will ensure that you have conformed to Go conventions. Please remember to add tests for your changes. + +# Versioning +This library will adhere to the +[Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html) specification. It may be worth noting this should allow for tools like [glide](https://glide.readthedocs.io/en/latest/) to pull in this library with ease. + +The Release Notes portion of this file will be updated to reflect the most recent major/minor updates, with the option to tag particular bug-fixes as well. Updates to the Release Notes for patches should be addative, where as major/minor updates should replace the previous version. If one desires to see the release notes for an older version, checkout that version of code and open this file. + +# Release Notes 1.1.* + +## v1.1.0 +Adding support for JSON marshaling and unmarshaling. diff --git a/vendor/github.com/marstr/guid/guid.go b/vendor/github.com/marstr/guid/guid.go new file mode 100644 index 000000000000..51b038b75cdc --- /dev/null +++ b/vendor/github.com/marstr/guid/guid.go @@ -0,0 +1,301 @@ +package guid + +import ( + "bytes" + "crypto/rand" + "errors" + "fmt" + "net" + "strings" + "sync" + "time" +) + +// GUID is a unique identifier designed to virtually guarantee non-conflict between values generated +// across a distributed system. +type GUID struct { + timeHighAndVersion uint16 + timeMid uint16 + timeLow uint32 + clockSeqHighAndReserved uint8 + clockSeqLow uint8 + node [6]byte +} + +// Format enumerates the values that are supported by Parse and Format +type Format string + +// These constants define the possible string formats available via this implementation of Guid. +const ( + FormatB Format = "B" // {00000000-0000-0000-0000-000000000000} + FormatD Format = "D" // 00000000-0000-0000-0000-000000000000 + FormatN Format = "N" // 00000000000000000000000000000000 + FormatP Format = "P" // (00000000-0000-0000-0000-000000000000) + FormatX Format = "X" // {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} + FormatDefault Format = FormatD +) + +// CreationStrategy enumerates the values that are supported for populating the bits of a new Guid. +type CreationStrategy string + +// These constants define the possible creation strategies available via this implementation of Guid. +const ( + CreationStrategyVersion1 CreationStrategy = "version1" + CreationStrategyVersion2 CreationStrategy = "version2" + CreationStrategyVersion3 CreationStrategy = "version3" + CreationStrategyVersion4 CreationStrategy = "version4" + CreationStrategyVersion5 CreationStrategy = "version5" +) + +var emptyGUID GUID + +// NewGUID generates and returns a new globally unique identifier +func NewGUID() GUID { + result, err := version4() + if err != nil { + panic(err) //Version 4 (pseudo-random GUID) doesn't use anything that could fail. + } + return result +} + +var knownStrategies = map[CreationStrategy]func() (GUID, error){ + CreationStrategyVersion1: version1, + CreationStrategyVersion4: version4, +} + +// NewGUIDs generates and returns a new globally unique identifier that conforms to the given strategy. +func NewGUIDs(strategy CreationStrategy) (GUID, error) { + if creator, present := knownStrategies[strategy]; present { + result, err := creator() + return result, err + } + return emptyGUID, errors.New("Unsupported CreationStrategy") +} + +// Empty returns a copy of the default and empty GUID. +func Empty() GUID { + return emptyGUID +} + +var knownFormats = map[Format]string{ + FormatN: "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x", + FormatD: "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + FormatB: "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + FormatP: "(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + FormatX: "{0x%08x,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}}", +} + +// MarshalJSON writes a GUID as a JSON string. +func (guid GUID) MarshalJSON() (marshaled []byte, err error) { + buf := bytes.Buffer{} + + _, err = buf.WriteRune('"') + buf.WriteString(guid.String()) + buf.WriteRune('"') + + marshaled = buf.Bytes() + return +} + +// Parse instantiates a GUID from a text representation of the same GUID. +// This is the inverse of function family String() +func Parse(value string) (GUID, error) { + var guid GUID + for _, fullFormat := range knownFormats { + parity, err := fmt.Sscanf( + value, + fullFormat, + &guid.timeLow, + &guid.timeMid, + &guid.timeHighAndVersion, + &guid.clockSeqHighAndReserved, + &guid.clockSeqLow, + &guid.node[0], + &guid.node[1], + &guid.node[2], + &guid.node[3], + &guid.node[4], + &guid.node[5]) + if parity == 11 && err == nil { + return guid, err + } + } + return emptyGUID, fmt.Errorf("\"%s\" is not in a recognized format", value) +} + +// String returns a text representation of a GUID in the default format. +func (guid GUID) String() string { + return guid.Stringf(FormatDefault) +} + +// Stringf returns a text representation of a GUID that conforms to the specified format. +// If an unrecognized format is provided, the empty string is returned. +func (guid GUID) Stringf(format Format) string { + if format == "" { + format = FormatDefault + } + fullFormat, present := knownFormats[format] + if !present { + return "" + } + return fmt.Sprintf( + fullFormat, + guid.timeLow, + guid.timeMid, + guid.timeHighAndVersion, + guid.clockSeqHighAndReserved, + guid.clockSeqLow, + guid.node[0], + guid.node[1], + guid.node[2], + guid.node[3], + guid.node[4], + guid.node[5]) +} + +// UnmarshalJSON parses a GUID from a JSON string token. +func (guid *GUID) UnmarshalJSON(marshaled []byte) (err error) { + if len(marshaled) < 2 { + err = errors.New("JSON GUID must be surrounded by quotes") + return + } + stripped := marshaled[1 : len(marshaled)-1] + *guid, err = Parse(string(stripped)) + return +} + +// Version reads a GUID to parse which mechanism of generating GUIDS was employed. +// Values returned here are documented in rfc4122.txt. +func (guid GUID) Version() uint { + return uint(guid.timeHighAndVersion >> 12) +} + +var unixToGregorianOffset = time.Date(1970, 01, 01, 0, 0, 00, 0, time.UTC).Sub(time.Date(1582, 10, 15, 0, 0, 0, 0, time.UTC)) + +// getRFC4122Time returns a 60-bit count of 100-nanosecond intervals since 00:00:00.00 October 15th, 1582 +func getRFC4122Time() int64 { + currentTime := time.Now().UTC().Add(unixToGregorianOffset).UnixNano() + currentTime /= 100 + return currentTime & 0x0FFFFFFFFFFFFFFF +} + +var clockSeqVal uint16 +var clockSeqKey sync.Mutex + +func getClockSequence() (uint16, error) { + clockSeqKey.Lock() + defer clockSeqKey.Unlock() + + if 0 == clockSeqVal { + var temp [2]byte + if parity, err := rand.Read(temp[:]); !(2 == parity && nil == err) { + return 0, err + } + clockSeqVal = uint16(temp[0])<<8 | uint16(temp[1]) + } + clockSeqVal++ + return clockSeqVal, nil +} + +func getMACAddress() (mac [6]byte, err error) { + var hostNICs []net.Interface + + hostNICs, err = net.Interfaces() + if err != nil { + return + } + + for _, nic := range hostNICs { + var parity int + + parity, err = fmt.Sscanf( + strings.ToLower(nic.HardwareAddr.String()), + "%02x:%02x:%02x:%02x:%02x:%02x", + &mac[0], + &mac[1], + &mac[2], + &mac[3], + &mac[4], + &mac[5]) + + if parity == len(mac) { + return + } + } + + err = fmt.Errorf("No suitable address found") + + return +} + +func version1() (result GUID, err error) { + var localMAC [6]byte + var clockSeq uint16 + + currentTime := getRFC4122Time() + + result.timeLow = uint32(currentTime) + result.timeMid = uint16(currentTime >> 32) + result.timeHighAndVersion = uint16(currentTime >> 48) + if err = result.setVersion(1); err != nil { + return emptyGUID, err + } + + if localMAC, err = getMACAddress(); nil != err { + if parity, err := rand.Read(localMAC[:]); !(len(localMAC) != parity && err == nil) { + return emptyGUID, err + } + localMAC[0] |= 0x1 + } + copy(result.node[:], localMAC[:]) + + if clockSeq, err = getClockSequence(); nil != err { + return emptyGUID, err + } + + result.clockSeqLow = uint8(clockSeq) + result.clockSeqHighAndReserved = uint8(clockSeq >> 8) + + result.setReservedBits() + + return +} + +func version4() (GUID, error) { + var retval GUID + var bits [10]byte + + if parity, err := rand.Read(bits[:]); !(len(bits) == parity && err == nil) { + return emptyGUID, err + } + retval.timeHighAndVersion |= uint16(bits[0]) | uint16(bits[1])<<8 + retval.timeMid |= uint16(bits[2]) | uint16(bits[3])<<8 + retval.timeLow |= uint32(bits[4]) | uint32(bits[5])<<8 | uint32(bits[6])<<16 | uint32(bits[7])<<24 + retval.clockSeqHighAndReserved = uint8(bits[8]) + retval.clockSeqLow = uint8(bits[9]) + + //Randomly set clock-sequence, reserved, and node + if written, err := rand.Read(retval.node[:]); !(nil == err && written == len(retval.node)) { + retval = emptyGUID + return retval, err + } + + if err := retval.setVersion(4); nil != err { + return emptyGUID, err + } + retval.setReservedBits() + + return retval, nil +} + +func (guid *GUID) setVersion(version uint16) error { + if version > 5 || version == 0 { + return fmt.Errorf("While setting GUID version, unsupported version: %d", version) + } + guid.timeHighAndVersion = (guid.timeHighAndVersion & 0x0fff) | version<<12 + return nil +} + +func (guid *GUID) setReservedBits() { + guid.clockSeqHighAndReserved = (guid.clockSeqHighAndReserved & 0x3f) | 0x80 +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 1cd7f14fc81c..81df23ee51e0 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -940,6 +940,12 @@ "revision": "bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d", "revisionTime": "2016-08-03T19:07:31Z" }, + { + "checksumSHA1": "T9E+5mKBQ/BX4wlNxgaPfetxdeI=", + "path": "github.com/marstr/guid", + "revision": "8bdf7d1a087ccc975cf37dd6507da50698fd19ca", + "revisionTime": "2017-04-27T23:51:15Z" + }, { "checksumSHA1": "y/A5iuvwjytQE2CqVuphQRXR2nI=", "path": "github.com/mattn/go-isatty",