github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/protokit/decode.go (about) 1 // Copyright 2020 Insolar Network Ltd. 2 // All rights reserved. 3 // This material is licensed under the Insolar License version 1.0, 4 // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md. 5 6 package protokit 7 8 import ( 9 "errors" 10 "fmt" 11 "io" 12 ) 13 14 var errOverflow = errors.New("proto: uint32 overflow") 15 16 func DecodeVarint(r io.ByteReader) (uint64, error) { 17 b, err := r.ReadByte() 18 if err != nil { 19 return 0, err 20 } 21 return decodeVarint(b, r) 22 } 23 24 // Continues to read Varint that was stated with the given (b) 25 // See also binary.ReadUvarint(r) here 26 func decodeVarint(b byte, r io.ByteReader) (n uint64, err error) { 27 v := uint64(b & 0x7F) 28 29 for i := uint8(7); i < 64; i += 7 { 30 if b&0x80 == 0 { 31 return v, nil 32 } 33 if b, err = r.ReadByte(); err != nil { 34 return 0, err 35 } 36 v |= uint64(b&0x7F) << i 37 } 38 39 if b > 1 { 40 return 0, errOverflow 41 } 42 return v, nil 43 } 44 45 func DecodeFixed64(r io.ByteReader) (uint64, error) { 46 if v, err := DecodeFixed32(r); err != nil { 47 return 0, err 48 } else if v2, err := DecodeFixed32(r); err != nil { 49 return 0, err 50 } else { 51 return v2<<32 | v, nil 52 } 53 } 54 55 func DecodeFixed32(r io.ByteReader) (v uint64, err error) { 56 // NB! uint64 result is NOT a mistake 57 var b byte 58 if b, err = r.ReadByte(); err != nil { 59 return 0, err 60 } 61 v = uint64(b) 62 if b, err = r.ReadByte(); err != nil { 63 return 0, err 64 } 65 v |= uint64(b) << 8 66 if b, err = r.ReadByte(); err != nil { 67 return 0, err 68 } 69 v |= uint64(b) << 16 70 if b, err = r.ReadByte(); err != nil { 71 return 0, err 72 } 73 v |= uint64(b) << 24 74 return v, nil 75 } 76 77 func DecodeFixed64FromBytes(b []byte) (uint64, int) { 78 _ = b[7] 79 v := uint64(b[0]) 80 v |= uint64(b[1]) << 8 81 v |= uint64(b[2]) << 16 82 v |= uint64(b[3]) << 24 83 v |= uint64(b[4]) << 32 84 v |= uint64(b[5]) << 40 85 v |= uint64(b[6]) << 48 86 v |= uint64(b[7]) << 56 87 88 return v, 8 89 } 90 91 func DecodeFixed64FromBytesWithError(b []byte) (v uint64, n int, err error) { 92 if len(b) < 8 { 93 return 0, 0, io.ErrUnexpectedEOF 94 } 95 v, n = DecodeFixed64FromBytes(b) 96 return 97 } 98 99 func DecodeFixed32FromBytes(b []byte) (uint64, int) { 100 // NB! uint64 result is NOT a mistake 101 _ = b[3] 102 v := uint64(b[0]) 103 v |= uint64(b[1]) << 8 104 v |= uint64(b[2]) << 16 105 v |= uint64(b[3]) << 24 106 107 return v, 4 108 } 109 110 func DecodeFixed32FromBytesWithError(b []byte) (v uint64, n int, err error) { 111 // NB! uint64 result is NOT a mistake 112 if len(b) < 4 { 113 return 0, 0, io.ErrUnexpectedEOF 114 } 115 v, n = DecodeFixed32FromBytes(b) 116 return 117 } 118 119 func DecodeVarintFromBytes(bb []byte) (u uint64, n int) { 120 b := bb[0] 121 122 v := uint64(b & 0x7F) 123 124 for i := uint8(7); i < 64; i += 7 { 125 n++ 126 if b&0x80 == 0 { 127 return v, n 128 } 129 b = bb[n] 130 v |= uint64(b&0x7F) << i 131 } 132 133 if b > 1 { 134 return 0, 0 // errOverflow 135 } 136 n++ 137 return v, n 138 } 139 140 func DecodeVarintFromBytesWithError(bb []byte) (u uint64, n int, err error) { 141 if len(bb) == 0 { 142 return 0, 0, io.ErrUnexpectedEOF 143 } 144 b := bb[0] 145 146 v := uint64(b & 0x7F) 147 148 for i := uint8(7); i < 64; i += 7 { 149 n++ 150 if b&0x80 == 0 { 151 return v, n, nil 152 } 153 if len(bb) <= n { 154 return 0, 0, io.ErrUnexpectedEOF 155 } 156 b = bb[n] 157 v |= uint64(b&0x7F) << i 158 } 159 160 if b > 1 { 161 return 0, 0, errOverflow 162 } 163 n++ 164 return v, n, nil 165 } 166 167 func IsValidFirstByteOfTag(firstByte byte) bool { 168 return firstByte > maskWireType && WireType(firstByte&maskWireType).IsValid() 169 } 170 171 func (v WireType) IsValidFirstByte(firstByte byte) bool { 172 return firstByte > maskWireType && firstByte&maskWireType == byte(v) && v.IsValid() 173 } 174 175 func (v WireTag) IsValidFirstByte(firstByte byte) bool { 176 switch { 177 case !IsValidFirstByteOfTag(firstByte): 178 return false 179 case v <= 0xFF: 180 return firstByte == byte(v) 181 default: 182 return firstByte == byte(v)|0x80 183 } 184 } 185 186 func _readTag(firstByte byte, r io.ByteReader) (wt WireTag, err error) { 187 var x uint64 188 x, err = decodeVarint(firstByte, r) 189 if err != nil { 190 return 0, err 191 } 192 return SafeWireTag(x) 193 } 194 195 func TryReadAnyTag(r io.ByteScanner) (wt WireTag, err error) { 196 var b byte 197 b, err = r.ReadByte() 198 switch { 199 case err != nil: 200 return 0, err 201 case !IsValidFirstByteOfTag(b): 202 return 0, r.UnreadByte() 203 } 204 return _readTag(b, r) 205 } 206 207 func MustReadAnyTag(r io.ByteReader) (wt WireTag, err error) { 208 var b byte 209 b, err = r.ReadByte() 210 switch { 211 case err != nil: 212 return 0, err 213 case !IsValidFirstByteOfTag(b): 214 return 0, fmt.Errorf("invalid wire tag, wrong first byte: %x", b) 215 } 216 return _readTag(b, r) 217 } 218 219 func MustReadAnyTagValue(r io.ByteReader) (rt WireTag, u uint64, err error) { 220 rt, err = MustReadAnyTag(r) 221 if err != nil { 222 return 0, 0, err 223 } 224 u, err = rt.ReadValue(r) 225 return 226 } 227 228 func TryReadAnyTagValue(r io.ByteScanner) (rt WireTag, u uint64, err error) { 229 rt, err = TryReadAnyTag(r) 230 if err != nil || rt.IsZero() { 231 return 0, 0, err 232 } 233 u, err = rt.ReadValue(r) 234 return 235 } 236 237 func (v WireTag) TryReadTag(r io.ByteScanner) (WireTag, error) { 238 b, err := r.ReadByte() 239 switch { 240 case err != nil: 241 return 0, err 242 case !v.IsValidFirstByte(b): 243 return 0, r.UnreadByte() 244 } 245 var rt WireTag 246 rt, err = _readTag(b, r) 247 if err != nil { 248 return 0, err 249 } 250 return rt, rt.CheckTag(v) 251 } 252 253 func (v WireType) TryReadTag(r io.ByteScanner) (WireTag, error) { 254 b, err := r.ReadByte() 255 switch { 256 case err != nil: 257 return 0, err 258 case !v.IsValidFirstByte(b): 259 return 0, r.UnreadByte() 260 } 261 var rt WireTag 262 rt, err = _readTag(b, r) 263 if err != nil { 264 return 0, err 265 } 266 return rt, rt.CheckType(v) 267 } 268 269 func (v WireTag) ReadTag(r io.ByteReader) error { 270 rt, err := MustReadAnyTag(r) 271 if err != nil { 272 return err 273 } 274 return rt.CheckTag(v) 275 } 276 277 func (v WireType) ReadTag(r io.ByteReader) (WireTag, error) { 278 rt, err := MustReadAnyTag(r) 279 if err != nil { 280 return rt, err 281 } 282 return rt, rt.CheckType(v) 283 } 284 285 func (v WireTag) ReadTagValue(r io.ByteReader) (uint64, error) { 286 err := v.ReadTag(r) 287 if err != nil { 288 return 0, err 289 } 290 return v.ReadValue(r) 291 } 292 293 func (v WireType) ReadTagValue(r io.ByteReader) (WireTag, uint64, error) { 294 rt, err := v.ReadTag(r) 295 if err != nil { 296 return rt, 0, err 297 } 298 var u uint64 299 u, err = rt.ReadValue(r) 300 return rt, u, err 301 }