Added FromString parser

This commit is contained in:
Maxim Bublis 2013-12-04 19:01:44 +04:00
parent 349e66f415
commit 3f8b0b0fa2
3 changed files with 90 additions and 0 deletions

View File

@ -32,6 +32,27 @@ func BenchmarkFromBytes(b *testing.B) {
} }
} }
func BenchmarkFromString(b *testing.B) {
s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkFromStringUrn(b *testing.B) {
s := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkFromStringWithBrackets(b *testing.B) {
s := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkNewV1(b *testing.B) { func BenchmarkNewV1(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
NewV1() NewV1()

29
uuid.go
View File

@ -30,10 +30,12 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha1" "crypto/sha1"
"encoding/binary" "encoding/binary"
"encoding/hex"
"fmt" "fmt"
"hash" "hash"
"net" "net"
"os" "os"
"strings"
"time" "time"
) )
@ -192,6 +194,31 @@ func FromBytes(input []byte) (u UUID, err error) {
return return
} }
// FromString returns UUID parsed from string input.
// Following formats are supported:
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
func FromString(input string) (u UUID, err error) {
s := strings.Replace(input, "-", "", -1)
if len(s) == 41 && s[:9] == "urn:uuid:" {
s = s[9:]
} else if len(s) == 34 && s[0] == '{' && s[33] == '}' {
s = s[1:33]
}
if len(s) != 32 {
err = fmt.Errorf("Invalid UUID string: %s", input)
return
}
b := []byte(s)
_, err = hex.Decode(u[:], b)
return
}
// NewV1 returns UUID based on current timestamp and MAC address. // NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID { func NewV1() UUID {
u := UUID{} u := UUID{}
@ -228,7 +255,9 @@ func NewV2(domain byte) UUID {
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSequence) binary.BigEndian.PutUint16(u[8:], clockSequence)
u[9] = domain u[9] = domain
copy(u[10:], hardwareAddr[:]) copy(u[10:], hardwareAddr[:])
u.SetVersion(2) u.SetVersion(2)
u.SetVariant() u.SetVariant()

View File

@ -137,6 +137,46 @@ func TestFromBytes(t *testing.T) {
} }
} }
func TestFromString(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
_, err := FromString("")
if err == nil {
t.Errorf("Should return error trying to parse empty string, got %s", err)
}
u1, err := FromString(s1)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
u2, err := FromString(s2)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u2) {
t.Errorf("UUIDs should be equal: %s and %s", u, u2)
}
u3, err := FromString(s3)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u3) {
t.Errorf("UUIDs should be equal: %s and %s", u, u3)
}
}
func TestNewV1(t *testing.T) { func TestNewV1(t *testing.T) {
u := NewV1() u := NewV1()