github.com/m3db/m3@v1.5.0/src/dbnode/encoding/proto/buffer_decode.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 // This file is mostly copy-pasta from: https://github.com/jhump/protoreflect/blob/master/dynamic/codec.go 22 // since the jhump/protoreflect library does not expose the `codedBuffer` type. 23 24 package proto 25 26 import ( 27 "errors" 28 "fmt" 29 "io" 30 "math" 31 ) 32 33 var ( 34 // errOverflow is returned when an integer is too large to be represented. 35 errOverflow = errors.New("proto: integer overflow") 36 ) 37 38 // A reader/writer type that assists with decoding protobuf's binary representation. 39 // This code is largely a fork of proto.Buffer, which cannot be used because it has no exported 40 // field or method that provides access to its underlying reader index. 41 type buffer struct { 42 buf []byte 43 index int 44 } 45 46 func newCodedBuffer(buf []byte) *buffer { 47 return &buffer{buf: buf} 48 } 49 50 func (cb *buffer) reset(b []byte) { 51 cb.buf = b 52 cb.index = 0 53 } 54 55 func (cb *buffer) eof() bool { 56 return cb.index >= len(cb.buf) 57 } 58 59 func (cb *buffer) skip(count int) (int, bool) { 60 newIndex := cb.index + count 61 if newIndex > len(cb.buf) { 62 return 0, false 63 } 64 cb.index = newIndex 65 return 0, true 66 } 67 68 func (cb *buffer) decodeVarintSlow() (x uint64, err error) { 69 i := cb.index 70 l := len(cb.buf) 71 72 for shift := uint(0); shift < 64; shift += 7 { 73 if i >= l { 74 err = io.ErrUnexpectedEOF 75 return 76 } 77 b := cb.buf[i] 78 i++ 79 x |= (uint64(b) & 0x7F) << shift 80 if b < 0x80 { 81 cb.index = i 82 return 83 } 84 } 85 86 // The number is too large to represent in a 64-bit value. 87 err = errOverflow 88 return 89 } 90 91 // DecodeVarint reads a varint-encoded integer from the Buffer. 92 // This is the format for the 93 // int32, int64, uint32, uint64, bool, and enum 94 // protocol buffer types. 95 func (cb *buffer) decodeVarint() (uint64, error) { 96 i := cb.index 97 buf := cb.buf 98 99 if i >= len(buf) { 100 return 0, io.ErrUnexpectedEOF 101 } else if buf[i] < 0x80 { 102 cb.index++ 103 return uint64(buf[i]), nil 104 } else if len(buf)-i < 10 { 105 return cb.decodeVarintSlow() 106 } 107 108 var b uint64 109 // we already checked the first byte 110 x := uint64(buf[i]) - 0x80 111 i++ 112 113 b = uint64(buf[i]) 114 i++ 115 x += b << 7 116 if b&0x80 == 0 { 117 goto done 118 } 119 x -= 0x80 << 7 120 121 b = uint64(buf[i]) 122 i++ 123 x += b << 14 124 if b&0x80 == 0 { 125 goto done 126 } 127 x -= 0x80 << 14 128 129 b = uint64(buf[i]) 130 i++ 131 x += b << 21 132 if b&0x80 == 0 { 133 goto done 134 } 135 x -= 0x80 << 21 136 137 b = uint64(buf[i]) 138 i++ 139 x += b << 28 140 if b&0x80 == 0 { 141 goto done 142 } 143 x -= 0x80 << 28 144 145 b = uint64(buf[i]) 146 i++ 147 x += b << 35 148 if b&0x80 == 0 { 149 goto done 150 } 151 x -= 0x80 << 35 152 153 b = uint64(buf[i]) 154 i++ 155 x += b << 42 156 if b&0x80 == 0 { 157 goto done 158 } 159 x -= 0x80 << 42 160 161 b = uint64(buf[i]) 162 i++ 163 x += b << 49 164 if b&0x80 == 0 { 165 goto done 166 } 167 x -= 0x80 << 49 168 169 b = uint64(buf[i]) 170 i++ 171 x += b << 56 172 if b&0x80 == 0 { 173 goto done 174 } 175 x -= 0x80 << 56 176 177 b = uint64(buf[i]) 178 i++ 179 x += b << 63 180 if b&0x80 == 0 { 181 goto done 182 } 183 // x -= 0x80 << 63 // Always zero. 184 185 return 0, errOverflow 186 187 done: 188 cb.index = i 189 return x, nil 190 } 191 192 func (cb *buffer) decodeTagAndWireType() (tag int32, wireType int8, err error) { 193 var v uint64 194 v, err = cb.decodeVarint() 195 if err != nil { 196 return 197 } 198 // low 7 bits is wire type 199 wireType = int8(v & 7) 200 // rest is int32 tag number 201 v = v >> 3 202 if v > math.MaxInt32 { 203 err = fmt.Errorf("tag number out of range: %d", v) 204 return 205 } 206 tag = int32(v) 207 return 208 } 209 210 // DecodeFixed64 reads a 64-bit integer from the Buffer. 211 // This is the format for the 212 // fixed64, sfixed64, and double protocol buffer types. 213 func (cb *buffer) decodeFixed64() (x uint64, err error) { 214 // x, err already 0 215 i := cb.index + 8 216 if i < 0 || i > len(cb.buf) { 217 err = io.ErrUnexpectedEOF 218 return 219 } 220 cb.index = i 221 222 x = uint64(cb.buf[i-8]) 223 x |= uint64(cb.buf[i-7]) << 8 224 x |= uint64(cb.buf[i-6]) << 16 225 x |= uint64(cb.buf[i-5]) << 24 226 x |= uint64(cb.buf[i-4]) << 32 227 x |= uint64(cb.buf[i-3]) << 40 228 x |= uint64(cb.buf[i-2]) << 48 229 x |= uint64(cb.buf[i-1]) << 56 230 return 231 } 232 233 // DecodeFixed32 reads a 32-bit integer from the Buffer. 234 // This is the format for the 235 // fixed32, sfixed32, and float protocol buffer types. 236 func (cb *buffer) decodeFixed32() (x uint64, err error) { 237 // x, err already 0 238 i := cb.index + 4 239 if i < 0 || i > len(cb.buf) { 240 err = io.ErrUnexpectedEOF 241 return 242 } 243 cb.index = i 244 245 x = uint64(cb.buf[i-4]) 246 x |= uint64(cb.buf[i-3]) << 8 247 x |= uint64(cb.buf[i-2]) << 16 248 x |= uint64(cb.buf[i-1]) << 24 249 return 250 } 251 252 func decodeZigZag32(v uint64) int32 { 253 return int32((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)) 254 } 255 256 func decodeZigZag64(v uint64) int64 { 257 return int64((v >> 1) ^ uint64((int64(v&1)<<63)>>63)) 258 } 259 260 // These are not ValueDecoders: they produce an array of bytes or a string. 261 // bytes, embedded messages 262 263 // DecodeRawBytes reads a count-delimited byte buffer from the Buffer. 264 // This is the format used for the bytes protocol buffer 265 // type and for embedded messages. 266 func (cb *buffer) decodeRawBytes(alloc bool) (buf []byte, err error) { 267 n, err := cb.decodeVarint() 268 if err != nil { 269 return nil, err 270 } 271 272 nb := int(n) 273 if nb < 0 { 274 return nil, fmt.Errorf("proto: bad byte length %d", nb) 275 } 276 end := cb.index + nb 277 if end < cb.index || end > len(cb.buf) { 278 return nil, io.ErrUnexpectedEOF 279 } 280 281 if !alloc { 282 buf = cb.buf[cb.index:end] 283 cb.index += nb 284 return 285 } 286 287 buf = make([]byte, nb) 288 copy(buf, cb.buf[cb.index:]) 289 cb.index += nb 290 return 291 }