vitess.io/vitess@v0.16.2/go/mysql/encoding.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mysql 18 19 import ( 20 "bytes" 21 "encoding/binary" 22 ) 23 24 // This file contains the data encoding and decoding functions. 25 26 // 27 // Encoding methods. 28 // 29 // The same assumptions are made for all the encoding functions: 30 // - there is enough space to write the data in the buffer. If not, we 31 // will panic with out of bounds. 32 // - all functions start writing at 'pos' in the buffer, and return the next position. 33 34 // lenEncIntSize returns the number of bytes required to encode a 35 // variable-length integer. 36 func lenEncIntSize(i uint64) int { 37 switch { 38 case i < 251: 39 return 1 40 case i < 1<<16: 41 return 3 42 case i < 1<<24: 43 return 4 44 default: 45 return 9 46 } 47 } 48 49 func writeLenEncInt(data []byte, pos int, i uint64) int { 50 switch { 51 case i < 251: 52 data[pos] = byte(i) 53 return pos + 1 54 case i < 1<<16: 55 data[pos] = 0xfc 56 data[pos+1] = byte(i) 57 data[pos+2] = byte(i >> 8) 58 return pos + 3 59 case i < 1<<24: 60 data[pos] = 0xfd 61 data[pos+1] = byte(i) 62 data[pos+2] = byte(i >> 8) 63 data[pos+3] = byte(i >> 16) 64 return pos + 4 65 default: 66 data[pos] = 0xfe 67 data[pos+1] = byte(i) 68 data[pos+2] = byte(i >> 8) 69 data[pos+3] = byte(i >> 16) 70 data[pos+4] = byte(i >> 24) 71 data[pos+5] = byte(i >> 32) 72 data[pos+6] = byte(i >> 40) 73 data[pos+7] = byte(i >> 48) 74 data[pos+8] = byte(i >> 56) 75 return pos + 9 76 } 77 } 78 79 func lenNullString(value string) int { 80 return len(value) + 1 81 } 82 83 func lenEOFString(value string) int { 84 return len(value) 85 } 86 87 func writeNullString(data []byte, pos int, value string) int { 88 pos += copy(data[pos:], value) 89 data[pos] = 0 90 return pos + 1 91 } 92 93 func writeEOFString(data []byte, pos int, value string) int { 94 pos += copy(data[pos:], value) 95 return pos 96 } 97 98 func writeByte(data []byte, pos int, value byte) int { 99 data[pos] = value 100 return pos + 1 101 } 102 103 func writeUint16(data []byte, pos int, value uint16) int { 104 data[pos] = byte(value) 105 data[pos+1] = byte(value >> 8) 106 return pos + 2 107 } 108 109 func writeUint32(data []byte, pos int, value uint32) int { 110 data[pos] = byte(value) 111 data[pos+1] = byte(value >> 8) 112 data[pos+2] = byte(value >> 16) 113 data[pos+3] = byte(value >> 24) 114 return pos + 4 115 } 116 117 func writeUint64(data []byte, pos int, value uint64) int { 118 data[pos] = byte(value) 119 data[pos+1] = byte(value >> 8) 120 data[pos+2] = byte(value >> 16) 121 data[pos+3] = byte(value >> 24) 122 data[pos+4] = byte(value >> 32) 123 data[pos+5] = byte(value >> 40) 124 data[pos+6] = byte(value >> 48) 125 data[pos+7] = byte(value >> 56) 126 return pos + 8 127 } 128 129 func lenEncStringSize(value string) int { 130 l := len(value) 131 return lenEncIntSize(uint64(l)) + l 132 } 133 134 func writeLenEncString(data []byte, pos int, value string) int { 135 pos = writeLenEncInt(data, pos, uint64(len(value))) 136 return writeEOFString(data, pos, value) 137 } 138 139 func writeZeroes(data []byte, pos int, len int) int { 140 for i := 0; i < len; i++ { 141 data[pos+i] = 0 142 } 143 return pos + len 144 } 145 146 // 147 // Decoding methods. 148 // 149 // The same assumptions are made for all the decoding functions: 150 // - they return the decode data, the new position to read from, and ak 'ok' flag. 151 // - all functions start reading at 'pos' in the buffer, and return the next position. 152 // 153 154 func readByte(data []byte, pos int) (byte, int, bool) { 155 if pos >= len(data) { 156 return 0, 0, false 157 } 158 return data[pos], pos + 1, true 159 } 160 161 func readBytes(data []byte, pos int, size int) ([]byte, int, bool) { 162 if pos+size-1 >= len(data) { 163 return nil, 0, false 164 } 165 return data[pos : pos+size], pos + size, true 166 } 167 168 // readBytesCopy returns a copy of the bytes in the packet. 169 // Useful to remember contents of ephemeral packets. 170 func readBytesCopy(data []byte, pos int, size int) ([]byte, int, bool) { 171 if pos+size-1 >= len(data) { 172 return nil, 0, false 173 } 174 result := make([]byte, size) 175 copy(result, data[pos:pos+size]) 176 return result, pos + size, true 177 } 178 179 func readNullString(data []byte, pos int) (string, int, bool) { 180 end := bytes.IndexByte(data[pos:], 0) 181 if end == -1 { 182 return "", 0, false 183 } 184 return string(data[pos : pos+end]), pos + end + 1, true 185 } 186 187 func readEOFString(data []byte, pos int) (string, int, bool) { 188 return string(data[pos:]), len(data) - pos, true 189 } 190 191 func readUint8(data []byte, pos int) (uint8, int, bool) { 192 b, pos, ok := readByte(data, pos) 193 return uint8(b), pos, ok 194 } 195 196 func readUint16(data []byte, pos int) (uint16, int, bool) { 197 if pos+1 >= len(data) { 198 return 0, 0, false 199 } 200 return binary.LittleEndian.Uint16(data[pos : pos+2]), pos + 2, true 201 } 202 203 func readUint32(data []byte, pos int) (uint32, int, bool) { 204 if pos+3 >= len(data) { 205 return 0, 0, false 206 } 207 return binary.LittleEndian.Uint32(data[pos : pos+4]), pos + 4, true 208 } 209 210 func readUint64(data []byte, pos int) (uint64, int, bool) { 211 if pos+7 >= len(data) { 212 return 0, 0, false 213 } 214 return binary.LittleEndian.Uint64(data[pos : pos+8]), pos + 8, true 215 } 216 217 func readLenEncInt(data []byte, pos int) (uint64, int, bool) { 218 if pos >= len(data) { 219 return 0, 0, false 220 } 221 switch data[pos] { 222 case 0xfc: 223 // Encoded in the next 2 bytes. 224 if pos+2 >= len(data) { 225 return 0, 0, false 226 } 227 return uint64(data[pos+1]) | 228 uint64(data[pos+2])<<8, pos + 3, true 229 case 0xfd: 230 // Encoded in the next 3 bytes. 231 if pos+3 >= len(data) { 232 return 0, 0, false 233 } 234 return uint64(data[pos+1]) | 235 uint64(data[pos+2])<<8 | 236 uint64(data[pos+3])<<16, pos + 4, true 237 case 0xfe: 238 // Encoded in the next 8 bytes. 239 if pos+8 >= len(data) { 240 return 0, 0, false 241 } 242 return uint64(data[pos+1]) | 243 uint64(data[pos+2])<<8 | 244 uint64(data[pos+3])<<16 | 245 uint64(data[pos+4])<<24 | 246 uint64(data[pos+5])<<32 | 247 uint64(data[pos+6])<<40 | 248 uint64(data[pos+7])<<48 | 249 uint64(data[pos+8])<<56, pos + 9, true 250 } 251 return uint64(data[pos]), pos + 1, true 252 } 253 254 func readLenEncString(data []byte, pos int) (string, int, bool) { 255 size, pos, ok := readLenEncInt(data, pos) 256 if !ok { 257 return "", 0, false 258 } 259 s := int(size) 260 if pos+s-1 >= len(data) { 261 return "", 0, false 262 } 263 return string(data[pos : pos+s]), pos + s, true 264 } 265 266 func skipLenEncString(data []byte, pos int) (int, bool) { 267 size, pos, ok := readLenEncInt(data, pos) 268 if !ok { 269 return 0, false 270 } 271 s := int(size) 272 if pos+s-1 >= len(data) { 273 return 0, false 274 } 275 return pos + s, true 276 } 277 278 func readLenEncStringAsBytes(data []byte, pos int) ([]byte, int, bool) { 279 size, pos, ok := readLenEncInt(data, pos) 280 if !ok { 281 return nil, 0, false 282 } 283 s := int(size) 284 if pos+s-1 >= len(data) { 285 return nil, 0, false 286 } 287 return data[pos : pos+s], pos + s, true 288 } 289 290 func readLenEncStringAsBytesCopy(data []byte, pos int) ([]byte, int, bool) { 291 size, pos, ok := readLenEncInt(data, pos) 292 if !ok { 293 return nil, 0, false 294 } 295 s := int(size) 296 if pos+s-1 >= len(data) { 297 return nil, 0, false 298 } 299 result := make([]byte, size) 300 copy(result, data[pos:pos+s]) 301 return result, pos + s, true 302 } 303 304 type coder struct { 305 data []byte 306 pos int 307 } 308 309 func (d *coder) readLenEncInt() (uint64, bool) { 310 res, newPos, ok := readLenEncInt(d.data, d.pos) 311 d.pos = newPos 312 return res, ok 313 } 314 315 func (d *coder) readUint16() (uint16, bool) { 316 res, newPos, ok := readUint16(d.data, d.pos) 317 d.pos = newPos 318 return res, ok 319 } 320 321 func (d *coder) readByte() (byte, bool) { 322 res, newPos, ok := readByte(d.data, d.pos) 323 d.pos = newPos 324 return res, ok 325 } 326 327 func (d *coder) readLenEncString() (string, bool) { 328 res, newPos, ok := readLenEncString(d.data, d.pos) 329 d.pos = newPos 330 return res, ok 331 } 332 333 func (d *coder) readLenEncInfo() (string, bool) { 334 res, newPos, ok := readLenEncString(d.data, d.pos) 335 if ok { 336 d.pos = newPos 337 } 338 return res, ok 339 } 340 341 func (d *coder) writeByte(value byte) { 342 newPos := writeByte(d.data, d.pos, value) 343 d.pos = newPos 344 } 345 346 func (d *coder) writeLenEncInt(i uint64) { 347 newPos := writeLenEncInt(d.data, d.pos, i) 348 d.pos = newPos 349 } 350 351 func (d *coder) writeUint16(value uint16) { 352 newPos := writeUint16(d.data, d.pos, value) 353 d.pos = newPos 354 } 355 356 func (d *coder) writeUint32(value uint32) { 357 newPos := writeUint32(d.data, d.pos, value) 358 d.pos = newPos 359 } 360 361 func (d *coder) writeLenEncString(value string) { 362 newPos := writeLenEncString(d.data, d.pos, value) 363 d.pos = newPos 364 } 365 366 func (d *coder) writeEOFString(value string) { 367 d.pos += copy(d.data[d.pos:], value) 368 }