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  }