github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/protowire/encode.go (about) 1 package protowire 2 3 import ( 4 "math" 5 "math/bits" 6 ) 7 8 type BinaryEncoder struct{} 9 10 // VarintEncode encodes a uint64 value as a varint-encoded byte slice. 11 // AppendVarint appends v to b as a varint-encoded uint64. 12 func AppendVarint(b []byte, v uint64) []byte { 13 switch { 14 case v < 1<<7: 15 b = append(b, byte(v)) 16 case v < 1<<14: 17 b = append(b, 18 byte((v>>0)&0x7f|0x80), 19 byte(v>>7)) 20 case v < 1<<21: 21 b = append(b, 22 byte((v>>0)&0x7f|0x80), 23 byte((v>>7)&0x7f|0x80), 24 byte(v>>14)) 25 case v < 1<<28: 26 b = append(b, 27 byte((v>>0)&0x7f|0x80), 28 byte((v>>7)&0x7f|0x80), 29 byte((v>>14)&0x7f|0x80), 30 byte(v>>21)) 31 case v < 1<<35: 32 b = append(b, 33 byte((v>>0)&0x7f|0x80), 34 byte((v>>7)&0x7f|0x80), 35 byte((v>>14)&0x7f|0x80), 36 byte((v>>21)&0x7f|0x80), 37 byte(v>>28)) 38 case v < 1<<42: 39 b = append(b, 40 byte((v>>0)&0x7f|0x80), 41 byte((v>>7)&0x7f|0x80), 42 byte((v>>14)&0x7f|0x80), 43 byte((v>>21)&0x7f|0x80), 44 byte((v>>28)&0x7f|0x80), 45 byte(v>>35)) 46 case v < 1<<49: 47 b = append(b, 48 byte((v>>0)&0x7f|0x80), 49 byte((v>>7)&0x7f|0x80), 50 byte((v>>14)&0x7f|0x80), 51 byte((v>>21)&0x7f|0x80), 52 byte((v>>28)&0x7f|0x80), 53 byte((v>>35)&0x7f|0x80), 54 byte(v>>42)) 55 case v < 1<<56: 56 b = append(b, 57 byte((v>>0)&0x7f|0x80), 58 byte((v>>7)&0x7f|0x80), 59 byte((v>>14)&0x7f|0x80), 60 byte((v>>21)&0x7f|0x80), 61 byte((v>>28)&0x7f|0x80), 62 byte((v>>35)&0x7f|0x80), 63 byte((v>>42)&0x7f|0x80), 64 byte(v>>49)) 65 case v < 1<<63: 66 b = append(b, 67 byte((v>>0)&0x7f|0x80), 68 byte((v>>7)&0x7f|0x80), 69 byte((v>>14)&0x7f|0x80), 70 byte((v>>21)&0x7f|0x80), 71 byte((v>>28)&0x7f|0x80), 72 byte((v>>35)&0x7f|0x80), 73 byte((v>>42)&0x7f|0x80), 74 byte((v>>49)&0x7f|0x80), 75 byte(v>>56)) 76 default: 77 b = append(b, 78 byte((v>>0)&0x7f|0x80), 79 byte((v>>7)&0x7f|0x80), 80 byte((v>>14)&0x7f|0x80), 81 byte((v>>21)&0x7f|0x80), 82 byte((v>>28)&0x7f|0x80), 83 byte((v>>35)&0x7f|0x80), 84 byte((v>>42)&0x7f|0x80), 85 byte((v>>49)&0x7f|0x80), 86 byte((v>>56)&0x7f|0x80), 87 1) 88 } 89 return b 90 } 91 92 // AppendFixed32 appends v to b as a little-endian uint32. 93 func AppendFixed32(b []byte, v uint32) []byte { 94 return append(b, 95 byte(v>>0), 96 byte(v>>8), 97 byte(v>>16), 98 byte(v>>24)) 99 } 100 101 // AppendFixed64 appends v to b as a little-endian uint64. 102 func AppendFixed64(b []byte, v uint64) []byte { 103 return append(b, 104 byte(v>>0), 105 byte(v>>8), 106 byte(v>>16), 107 byte(v>>24), 108 byte(v>>32), 109 byte(v>>40), 110 byte(v>>48), 111 byte(v>>56)) 112 } 113 114 // EncodeZigZag encodes an int64 as a zig-zag-encoded uint64. 115 // 116 // Input: {…, -3, -2, -1, 0, +1, +2, +3, …} 117 // Output: {…, 5, 3, 1, 0, 2, 4, 6, …} 118 func EncodeZigZag(v int64) uint64 { 119 return uint64(v<<1) ^ uint64(v>>63) 120 } 121 122 // SizeVarint returns the encoded size of a varint. 123 // The size is guaranteed to be within 1 and 10, inclusive. 124 func SizeVarint(v uint64) int { 125 // This computes 1 + (bits.Len64(v)-1)/7. 126 // 9/64 is a good enough approximation of 1/7 127 return int(9*uint32(bits.Len64(v))+64) / 64 128 } 129 130 // SizeFixed32 returns the encoded size of a fixed32; which is always 4. 131 func SizeFixed32() int { 132 return 4 133 } 134 135 // SizeFixed64 returns the encoded size of a fixed64; which is always 8. 136 func SizeFixed64() int { 137 return 8 138 } 139 140 // encode each proto kind into bytes 141 func (BinaryEncoder) EncodeBool(b []byte, v bool) []byte { 142 if v { 143 return append(b, 1) 144 } 145 return append(b, 0) 146 } 147 148 func (BinaryEncoder) EncodeByte(b []byte, v byte) []byte { 149 return append(b, v) 150 } 151 152 func (BinaryEncoder) EncodeEnum(b []byte, v int32) []byte { 153 return AppendVarint(b, uint64(v)) 154 } 155 156 func (BinaryEncoder) EncodeInt32(b []byte, v int32) []byte { 157 return AppendVarint(b, uint64(v)) 158 } 159 160 func (BinaryEncoder) EncodeSint32(b []byte, v int32) []byte { 161 return AppendVarint(b, EncodeZigZag(int64(v))) 162 } 163 164 func (BinaryEncoder) EncodeUint32(b []byte, v uint32) []byte { 165 return AppendVarint(b, uint64(v)) 166 } 167 168 func (BinaryEncoder) EncodeInt64(b []byte, v int64) []byte { 169 return AppendVarint(b, uint64(v)) 170 } 171 172 func (BinaryEncoder) EncodeSint64(b []byte, v int64) []byte { 173 return AppendVarint(b, EncodeZigZag(v)) 174 } 175 176 func (BinaryEncoder) EncodeUint64(b []byte, v uint64) []byte { 177 return AppendVarint(b, v) 178 } 179 180 func (BinaryEncoder) EncodeSfixed32(b []byte, v int32) []byte { 181 return AppendFixed32(b, uint32(v)) 182 } 183 184 func (BinaryEncoder) EncodeFixed32(b []byte, v uint32) []byte { 185 return AppendFixed32(b, v) 186 } 187 188 func (BinaryEncoder) EncodeFloat32(b []byte, v float32) []byte { 189 return AppendFixed32(b, math.Float32bits(v)) 190 } 191 192 func (BinaryEncoder) EncodeSfixed64(b []byte, v int64) []byte { 193 return AppendFixed64(b, uint64(v)) 194 } 195 196 func (BinaryEncoder) EncodeFixed64(b []byte, v uint64) []byte { 197 return AppendFixed64(b, v) 198 } 199 200 func (BinaryEncoder) EncodeDouble(b []byte, v float64) []byte { 201 return AppendFixed64(b, math.Float64bits(v)) 202 } 203 204 func (BinaryEncoder) EncodeString(b []byte, v string) []byte { 205 return append(AppendVarint(b, uint64(len(v))), v...) 206 } 207 208 func (BinaryEncoder) EncodeBytes(b []byte, v []byte) []byte { 209 return append(AppendVarint(b, uint64(len(v))), v...) 210 }