github.com/gogo/protobuf@v1.3.2/test/combos/marshaler/uuid.go (about) 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 29 package test 30 31 import ( 32 "bytes" 33 "encoding/hex" 34 "encoding/json" 35 ) 36 37 func 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 48 type Uuid []byte 49 50 func (uuid Uuid) Bytes() []byte { 51 return uuid 52 } 53 54 func (uuid Uuid) Marshal() ([]byte, error) { 55 if len(uuid) == 0 { 56 return nil, nil 57 } 58 return []byte(uuid), nil 59 } 60 61 func (uuid Uuid) MarshalTo(data []byte) (n int, err error) { 62 if len(uuid) == 0 { 63 return 0, nil 64 } 65 copy(data, uuid) 66 return 16, nil 67 } 68 69 func (uuid *Uuid) Unmarshal(data []byte) error { 70 if len(data) == 0 { 71 uuid = nil 72 return nil 73 } 74 id := Uuid(make([]byte, 16)) 75 copy(id, data) 76 *uuid = id 77 return nil 78 } 79 80 func (uuid *Uuid) Size() int { 81 if uuid == nil { 82 return 0 83 } 84 if len(*uuid) == 0 { 85 return 0 86 } 87 return 16 88 } 89 90 func (uuid Uuid) MarshalJSON() ([]byte, error) { 91 s := hex.EncodeToString([]byte(uuid)) 92 return json.Marshal(s) 93 } 94 95 func (uuid *Uuid) UnmarshalJSON(data []byte) error { 96 var s string 97 err := json.Unmarshal(data, &s) 98 if err != nil { 99 return err 100 } 101 d, err := hex.DecodeString(s) 102 if err != nil { 103 return err 104 } 105 *uuid = Uuid(d) 106 return nil 107 } 108 109 func (uuid Uuid) Equal(other Uuid) bool { 110 return bytes.Equal(uuid[0:], other[0:]) 111 } 112 113 func (uuid Uuid) Compare(other Uuid) int { 114 return bytes.Compare(uuid[0:], other[0:]) 115 } 116 117 type int63 interface { 118 Int63() int64 119 } 120 121 func NewPopulatedUuid(r int63) *Uuid { 122 u := RandV4(r) 123 return &u 124 } 125 126 func RandV4(r int63) Uuid { 127 uuid := make(Uuid, 16) 128 uuid.RandV4(r) 129 return uuid 130 } 131 132 func (uuid Uuid) RandV4(r int63) { 133 PutLittleEndianUint64(uuid, 0, uint64(r.Int63())) 134 PutLittleEndianUint64(uuid, 8, uint64(r.Int63())) 135 uuid[6] = (uuid[6] & 0xf) | 0x40 136 uuid[8] = (uuid[8] & 0x3f) | 0x80 137 }