1// Protocol Buffers for Go with Gadgets 2// 3// Copyright (c) 2013, The GoGo Authors. All rights reserved. 4// http://github.com/gogo/protobuf 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: 9// 10// * Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// * Redistributions in binary form must reproduce the above 13// copyright notice, this list of conditions and the following disclaimer 14// in the documentation and/or other materials provided with the 15// distribution. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29package test 30 31import ( 32 "bytes" 33 "encoding/hex" 34 "encoding/json" 35) 36 37func PutLittleEndianUint64(b []byte, offset int, v uint64) { 38 b[offset] = byte(v) 39 b[offset+1] = byte(v >> 8) 40 b[offset+2] = byte(v >> 16) 41 b[offset+3] = byte(v >> 24) 42 b[offset+4] = byte(v >> 32) 43 b[offset+5] = byte(v >> 40) 44 b[offset+6] = byte(v >> 48) 45 b[offset+7] = byte(v >> 56) 46} 47 48type Uuid []byte 49 50func (uuid Uuid) Marshal() ([]byte, error) { 51 if len(uuid) == 0 { 52 return nil, nil 53 } 54 return []byte(uuid), nil 55} 56 57func (uuid Uuid) MarshalTo(data []byte) (n int, err error) { 58 if len(uuid) == 0 { 59 return 0, nil 60 } 61 copy(data, uuid) 62 return 16, nil 63} 64 65func (uuid *Uuid) Unmarshal(data []byte) error { 66 if len(data) == 0 { 67 uuid = nil 68 return nil 69 } 70 id := Uuid(make([]byte, 16)) 71 copy(id, data) 72 *uuid = id 73 return nil 74} 75 76func (uuid *Uuid) Size() int { 77 if uuid == nil { 78 return 0 79 } 80 if len(*uuid) == 0 { 81 return 0 82 } 83 return 16 84} 85 86func (uuid Uuid) MarshalJSON() ([]byte, error) { 87 s := hex.EncodeToString([]byte(uuid)) 88 return json.Marshal(s) 89} 90 91func (uuid *Uuid) UnmarshalJSON(data []byte) error { 92 var s string 93 err := json.Unmarshal(data, &s) 94 if err != nil { 95 return err 96 } 97 d, err := hex.DecodeString(s) 98 if err != nil { 99 return err 100 } 101 *uuid = Uuid(d) 102 return nil 103} 104 105func (uuid Uuid) Equal(other Uuid) bool { 106 return bytes.Equal(uuid[0:], other[0:]) 107} 108 109func (uuid Uuid) Compare(other Uuid) int { 110 return bytes.Compare(uuid[0:], other[0:]) 111} 112 113type int63 interface { 114 Int63() int64 115} 116 117func NewPopulatedUuid(r int63) *Uuid { 118 u := RandV4(r) 119 return &u 120} 121 122func RandV4(r int63) Uuid { 123 uuid := make(Uuid, 16) 124 uuid.RandV4(r) 125 return uuid 126} 127 128func (uuid Uuid) RandV4(r int63) { 129 PutLittleEndianUint64(uuid, 0, uint64(r.Int63())) 130 PutLittleEndianUint64(uuid, 8, uint64(r.Int63())) 131 uuid[6] = (uuid[6] & 0xf) | 0x40 132 uuid[8] = (uuid[8] & 0x3f) | 0x80 133} 134