github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/util/codec/number.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package codec 15 16 import ( 17 "encoding/binary" 18 19 "github.com/insionng/yougam/libraries/juju/errors" 20 ) 21 22 const signMask uint64 = 0x8000000000000000 23 24 func encodeIntToCmpUint(v int64) uint64 { 25 return uint64(v) ^ signMask 26 } 27 28 func decodeCmpUintToInt(u uint64) int64 { 29 return int64(u ^ signMask) 30 } 31 32 // EncodeInt appends the encoded value to slice b and returns the appended slice. 33 // EncodeInt guarantees that the encoded value is in ascending order for comparison. 34 func EncodeInt(b []byte, v int64) []byte { 35 var data [8]byte 36 u := encodeIntToCmpUint(v) 37 binary.BigEndian.PutUint64(data[:], u) 38 return append(b, data[:]...) 39 } 40 41 // EncodeIntDesc appends the encoded value to slice b and returns the appended slice. 42 // EncodeIntDesc guarantees that the encoded value is in descending order for comparison. 43 func EncodeIntDesc(b []byte, v int64) []byte { 44 var data [8]byte 45 u := encodeIntToCmpUint(v) 46 binary.BigEndian.PutUint64(data[:], ^u) 47 return append(b, data[:]...) 48 } 49 50 // DecodeInt decodes value encoded by EncodeInt before. 51 // It returns the leftover un-decoded slice, decoded value if no error. 52 func DecodeInt(b []byte) ([]byte, int64, error) { 53 if len(b) < 8 { 54 return nil, 0, errors.New("insufficient bytes to decode value") 55 } 56 57 u := binary.BigEndian.Uint64(b[:8]) 58 v := decodeCmpUintToInt(u) 59 b = b[8:] 60 return b, v, nil 61 } 62 63 // DecodeIntDesc decodes value encoded by EncodeInt before. 64 // It returns the leftover un-decoded slice, decoded value if no error. 65 func DecodeIntDesc(b []byte) ([]byte, int64, error) { 66 if len(b) < 8 { 67 return nil, 0, errors.New("insufficient bytes to decode value") 68 } 69 70 u := binary.BigEndian.Uint64(b[:8]) 71 v := decodeCmpUintToInt(^u) 72 b = b[8:] 73 return b, v, nil 74 } 75 76 // EncodeUint appends the encoded value to slice b and returns the appended slice. 77 // EncodeUint guarantees that the encoded value is in ascending order for comparison. 78 func EncodeUint(b []byte, v uint64) []byte { 79 var data [8]byte 80 binary.BigEndian.PutUint64(data[:], v) 81 return append(b, data[:]...) 82 } 83 84 // EncodeUintDesc appends the encoded value to slice b and returns the appended slice. 85 // EncodeUintDesc guarantees that the encoded value is in descending order for comparison. 86 func EncodeUintDesc(b []byte, v uint64) []byte { 87 var data [8]byte 88 binary.BigEndian.PutUint64(data[:], ^v) 89 return append(b, data[:]...) 90 } 91 92 // DecodeUint decodes value encoded by EncodeUint before. 93 // It returns the leftover un-decoded slice, decoded value if no error. 94 func DecodeUint(b []byte) ([]byte, uint64, error) { 95 if len(b) < 8 { 96 return nil, 0, errors.New("insufficient bytes to decode value") 97 } 98 99 v := binary.BigEndian.Uint64(b[:8]) 100 b = b[8:] 101 return b, v, nil 102 } 103 104 // DecodeUintDesc decodes value encoded by EncodeInt before. 105 // It returns the leftover un-decoded slice, decoded value if no error. 106 func DecodeUintDesc(b []byte) ([]byte, uint64, error) { 107 if len(b) < 8 { 108 return nil, 0, errors.New("insufficient bytes to decode value") 109 } 110 111 data := b[:8] 112 v := binary.BigEndian.Uint64(data) 113 b = b[8:] 114 return b, ^v, nil 115 } 116 117 // EncodeVarint appends the encoded value to slice b and returns the appended slice. 118 // Note that the encoded result is not memcomparable. 119 func EncodeVarint(b []byte, v int64) []byte { 120 var data [binary.MaxVarintLen64]byte 121 n := binary.PutVarint(data[:], v) 122 return append(b, data[:n]...) 123 } 124 125 // DecodeVarint decodes value encoded by EncodeVarint before. 126 // It returns the leftover un-decoded slice, decoded value if no error. 127 func DecodeVarint(b []byte) ([]byte, int64, error) { 128 v, n := binary.Varint(b) 129 if n > 0 { 130 return b[n:], v, nil 131 } 132 if n < 0 { 133 return nil, 0, errors.New("value larger than 64 bits") 134 } 135 return nil, 0, errors.New("insufficient bytes to decode value") 136 } 137 138 // EncodeUvarint appends the encoded value to slice b and returns the appended slice. 139 // Note that the encoded result is not memcomparable. 140 func EncodeUvarint(b []byte, v uint64) []byte { 141 var data [binary.MaxVarintLen64]byte 142 n := binary.PutUvarint(data[:], v) 143 return append(b, data[:n]...) 144 } 145 146 // DecodeUvarint decodes value encoded by EncodeUvarint before. 147 // It returns the leftover un-decoded slice, decoded value if no error. 148 func DecodeUvarint(b []byte) ([]byte, uint64, error) { 149 v, n := binary.Uvarint(b) 150 if n > 0 { 151 return b[n:], v, nil 152 } 153 if n < 0 { 154 return nil, 0, errors.New("value larger than 64 bits") 155 } 156 return nil, 0, errors.New("insufficient bytes to decode value") 157 }