github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/protowire/decode.go (about) 1 package protowire 2 3 import ( 4 "math" 5 ) 6 7 const ( 8 _ = -iota 9 errCodeTruncated 10 errCodeFieldNumber 11 errCodeOverflow 12 errCodeReserved 13 errCodeEndGroup 14 errCodeRecursionDepth 15 ) 16 17 type BinaryDecoder struct{} 18 19 // ConsumeVarint parses b as a varint-encoded uint64, reporting its length. 20 // This returns a negative length upon an error (see ParseError). 21 func ConsumeVarint(b []byte) (v uint64, n int) { 22 var y uint64 23 if len(b) <= 0 { 24 return 0, errCodeTruncated 25 } 26 v = uint64(b[0]) 27 if v < 0x80 { 28 return v, 1 29 } 30 v -= 0x80 31 32 if len(b) <= 1 { 33 return 0, errCodeTruncated 34 } 35 y = uint64(b[1]) 36 v += y << 7 37 if y < 0x80 { 38 return v, 2 39 } 40 v -= 0x80 << 7 41 42 if len(b) <= 2 { 43 return 0, errCodeTruncated 44 } 45 y = uint64(b[2]) 46 v += y << 14 47 if y < 0x80 { 48 return v, 3 49 } 50 v -= 0x80 << 14 51 52 if len(b) <= 3 { 53 return 0, errCodeTruncated 54 } 55 y = uint64(b[3]) 56 v += y << 21 57 if y < 0x80 { 58 return v, 4 59 } 60 v -= 0x80 << 21 61 62 if len(b) <= 4 { 63 return 0, errCodeTruncated 64 } 65 y = uint64(b[4]) 66 v += y << 28 67 if y < 0x80 { 68 return v, 5 69 } 70 v -= 0x80 << 28 71 72 if len(b) <= 5 { 73 return 0, errCodeTruncated 74 } 75 y = uint64(b[5]) 76 v += y << 35 77 if y < 0x80 { 78 return v, 6 79 } 80 v -= 0x80 << 35 81 82 if len(b) <= 6 { 83 return 0, errCodeTruncated 84 } 85 y = uint64(b[6]) 86 v += y << 42 87 if y < 0x80 { 88 return v, 7 89 } 90 v -= 0x80 << 42 91 92 if len(b) <= 7 { 93 return 0, errCodeTruncated 94 } 95 y = uint64(b[7]) 96 v += y << 49 97 if y < 0x80 { 98 return v, 8 99 } 100 v -= 0x80 << 49 101 102 if len(b) <= 8 { 103 return 0, errCodeTruncated 104 } 105 y = uint64(b[8]) 106 v += y << 56 107 if y < 0x80 { 108 return v, 9 109 } 110 v -= 0x80 << 56 111 112 if len(b) <= 9 { 113 return 0, errCodeTruncated 114 } 115 y = uint64(b[9]) 116 v += y << 63 117 if y < 2 { 118 return v, 10 119 } 120 return 0, errCodeOverflow 121 } 122 123 // ConsumeFixed32 parses b as a little-endian uint32, reporting its length. 124 // This returns a negative length upon an error (see ParseError). 125 func ConsumeFixed32(b []byte) (v uint32, n int) { 126 if len(b) < 4 { 127 return 0, errCodeTruncated 128 } 129 v = uint32(b[0])<<0 | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 130 return v, 4 131 } 132 133 // ConsumeFixed64 parses b as a little-endian uint64, reporting its length. 134 // This returns a negative length upon an error (see ParseError). 135 func ConsumeFixed64(b []byte) (v uint64, n int) { 136 if len(b) < 8 { 137 return 0, errCodeTruncated 138 } 139 v = uint64(b[0])<<0 | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 140 return v, 8 141 } 142 143 // ConsumeBytes parses b as a length-prefixed bytes value, reporting its length. 144 // This returns a negative length upon an error (see ParseError). 145 func ConsumeBytes(b []byte) (v []byte, n int, all int) { 146 m, n := ConsumeVarint(b) 147 if n < 0 { 148 return nil, n, n 149 } 150 if m > uint64(len(b[n:])) { 151 return nil, errCodeTruncated, errCodeTruncated 152 } 153 return b[n:][:m], n, n + int(m) // V's bytes, L's bytelen, (L+V)'s bytelen 154 } 155 156 // DecodeZigZag decodes a zig-zag-encoded uint64 as an int64. 157 // 158 // Input: {…, 5, 3, 1, 0, 2, 4, 6, …} 159 // Output: {…, -3, -2, -1, 0, +1, +2, +3, …} 160 func DecodeZigZag(x uint64) int64 { 161 return int64(x>>1) ^ int64(x)<<63>>63 162 } 163 164 func (BinaryDecoder) DecodeBool(b []byte) (bool, int) { 165 v, n := ConsumeVarint(b) 166 return int8(v) == 1, n 167 } 168 169 func (BinaryDecoder) DecodeByte(b []byte) byte { 170 return byte(b[0]) 171 } 172 173 func (BinaryDecoder) DecodeInt32(b []byte) (int32, int) { 174 v, n := ConsumeVarint(b) 175 return int32(v), n 176 } 177 178 func (BinaryDecoder) DecodeSint32(b []byte) (int32, int) { 179 v, n := ConsumeVarint(b) 180 return int32(DecodeZigZag(v & math.MaxUint32)), n 181 } 182 183 func (BinaryDecoder) DecodeUint32(b []byte) (uint32, int) { 184 v, n := ConsumeVarint(b) 185 return uint32(v), n 186 } 187 188 func (BinaryDecoder) DecodeInt64(b []byte) (int64, int) { 189 v, n := ConsumeVarint(b) 190 return int64(v), n 191 } 192 193 func (BinaryDecoder) DecodeSint64(b []byte) (int64, int) { 194 v, n := ConsumeVarint(b) 195 return DecodeZigZag(v), n 196 } 197 198 func (BinaryDecoder) DecodeUint64(b []byte) (uint64, int) { 199 v, n := ConsumeVarint(b) 200 return v, n 201 } 202 203 func (BinaryDecoder) DecodeSfixed32(b []byte) (int32, int) { 204 v, n := ConsumeFixed32(b) 205 return int32(v), n 206 } 207 208 func (BinaryDecoder) DecodeFixed32(b []byte) (uint32, int) { 209 v, n := ConsumeFixed32(b) 210 return v, n 211 } 212 213 func (BinaryDecoder) DecodeFloat32(b []byte) (float32, int) { 214 v, n := ConsumeFixed32(b) 215 return math.Float32frombits(v), n 216 } 217 218 func (BinaryDecoder) DecodeSfixed64(b []byte) (int64, int) { 219 v, n := ConsumeFixed64(b) 220 return int64(v), n 221 } 222 223 func (BinaryDecoder) DecodeFixed64(b []byte) (uint64, int) { 224 v, n := ConsumeFixed64(b) 225 return v, n 226 } 227 228 func (BinaryDecoder) DecodeDouble(b []byte) (float64, int) { 229 v, n := ConsumeFixed64(b) 230 return math.Float64frombits(v), n 231 } 232 233 func (BinaryDecoder) DecodeString(b []byte) (string, int, int) { 234 v, n, all := ConsumeBytes(b) 235 return string(v), n, all 236 } 237 238 func (BinaryDecoder) DecodeBytes(b []byte) ([]byte, int, int) { 239 v, n, all := ConsumeBytes(b) 240 return v, n, all 241 }