mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 14:34:19 +00:00
No side effect deserialization -> side effects
This commit is contained in:
parent
17c86ed3ec
commit
92ff441d42
2 changed files with 109 additions and 84 deletions
|
@ -2,76 +2,120 @@ use byteorder::{ByteOrder, LittleEndian};
|
|||
use bytes::Bytes;
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_lenenc(buf: &Vec<u8>, index: &usize) -> (Option<usize>, usize) {
|
||||
pub fn deserialize_int_lenenc(buf: &Vec<u8>, index: &mut usize) -> Option<usize> {
|
||||
match buf[*index] {
|
||||
0xFB => (None, *index + 1),
|
||||
0xFC => (Some(LittleEndian::read_u16(&buf[*index + 1..]) as usize), *index + 2),
|
||||
0xFD => (Some((buf[*index + 1] + buf[*index + 2] << 8 + buf[*index + 3] << 16) as usize), *index + 3),
|
||||
0xFE => (Some(LittleEndian::read_u64(&buf[*index..]) as usize), *index + 8),
|
||||
0xFB => {
|
||||
*index += 1;
|
||||
None
|
||||
}
|
||||
0xFC => {
|
||||
let value = Some(LittleEndian::read_u16(&buf[*index + 1..]) as usize);
|
||||
*index += 3;
|
||||
value
|
||||
}
|
||||
0xFD => {
|
||||
let value =
|
||||
Some((buf[*index + 1] + buf[*index + 2] << 8 + buf[*index + 3] << 16) as usize);
|
||||
*index += 4;
|
||||
value
|
||||
}
|
||||
0xFE => {
|
||||
let value = Some(LittleEndian::read_u64(&buf[*index..]) as usize);
|
||||
*index += 9;
|
||||
value
|
||||
}
|
||||
0xFF => panic!("int<lenenc> unprocessable first byte 0xFF"),
|
||||
_ => (Some(buf[*index] as usize), *index + 1),
|
||||
_ => {
|
||||
let value = Some(buf[*index] as usize);
|
||||
*index += 2;
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_8(buf: &Vec<u8>, index: &usize) -> (u64, usize) {
|
||||
(LittleEndian::read_u64(&buf[*index..]), index + 8)
|
||||
pub fn deserialize_int_8(buf: &Vec<u8>, index: &mut usize) -> u64 {
|
||||
let value = LittleEndian::read_u64(&buf[*index..]);
|
||||
*index += 8;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_4(buf: &Vec<u8>, index: &usize) -> (u32, usize) {
|
||||
(LittleEndian::read_u32(&buf[*index..]), index + 4)
|
||||
pub fn deserialize_int_4(buf: &Vec<u8>, index: &mut usize) -> u32 {
|
||||
let value = LittleEndian::read_u32(&buf[*index..]);
|
||||
*index += 4;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_3(buf: &Vec<u8>, index: &usize) -> (u32, usize) {
|
||||
(LittleEndian::read_u24(&buf[*index..]), index + 3)
|
||||
pub fn deserialize_int_3(buf: &Vec<u8>, index: &mut usize) -> u32 {
|
||||
let value = LittleEndian::read_u24(&buf[*index..]);
|
||||
*index += 3;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_2(buf: &Vec<u8>, index: &usize) -> (u16, usize) {
|
||||
(LittleEndian::read_u16(&buf[*index..]), index + 2)
|
||||
pub fn deserialize_int_2(buf: &Vec<u8>, index: &mut usize) -> u16 {
|
||||
let value = LittleEndian::read_u16(&buf[*index..]);
|
||||
*index += 2;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_int_1(buf: &Vec<u8>, index: &usize) -> (u8, usize) {
|
||||
(buf[*index], index + 1)
|
||||
pub fn deserialize_int_1(buf: &Vec<u8>, index: &mut usize) -> u8 {
|
||||
let value = buf[*index];
|
||||
*index += 1;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_string_lenenc(buf: &Vec<u8>, index: &usize) -> (Bytes, usize) {
|
||||
let (length, index) = deserialize_int_3(&buf, &index);
|
||||
(Bytes::from(&buf[index..index + length as usize]), index + length as usize)
|
||||
pub fn deserialize_string_lenenc(buf: &Vec<u8>, index: &mut usize) -> Bytes {
|
||||
let length = deserialize_int_3(&buf, &mut *index);
|
||||
let value = Bytes::from(&buf[*index..*index + length as usize]);
|
||||
*index = *index + length as usize;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_string_fix(buf: &Vec<u8>, index: &usize, length: usize) -> (Bytes, usize) {
|
||||
(Bytes::from(&buf[*index..index + length as usize]), index + length as usize)
|
||||
pub fn deserialize_string_fix(buf: &Vec<u8>, index: &mut usize, length: usize) -> Bytes {
|
||||
let value = Bytes::from(&buf[*index..*index + length as usize]);
|
||||
*index = *index + length as usize;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_string_eof(buf: &Vec<u8>, index: &usize) -> (Bytes, usize) {
|
||||
(Bytes::from(&buf[*index..]), buf.len())
|
||||
pub fn deserialize_string_eof(buf: &Vec<u8>, index: &mut usize) -> Bytes {
|
||||
let value = Bytes::from(&buf[*index..]);
|
||||
*index = buf.len();
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_string_null(buf: &Vec<u8>, index: &usize) -> (Bytes, usize) {
|
||||
pub fn deserialize_string_null(buf: &Vec<u8>, index: &mut usize) -> Bytes {
|
||||
let null_index = memchr::memchr(b'\0', &buf[*index..]).unwrap();
|
||||
(Bytes::from(&buf[*index..null_index]), null_index + 1)
|
||||
let value = Bytes::from(&buf[*index..null_index]);
|
||||
*index = null_index + 1;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_byte_fix(buf: &Vec<u8>, index: &usize, length: usize) -> (Bytes, usize) {
|
||||
(Bytes::from(&buf[*index..index + length as usize]), index + length as usize)
|
||||
pub fn deserialize_byte_fix(buf: &Vec<u8>, index: &mut usize, length: usize) -> Bytes {
|
||||
let value = Bytes::from(&buf[*index..*index + length as usize]);
|
||||
*index = *index + length as usize;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_byte_lenenc(buf: &Vec<u8>, index: &usize) -> (Bytes, usize) {
|
||||
let (length, index) = deserialize_int_3(&buf, &index);
|
||||
(Bytes::from(&buf[index..index + length as usize]), index + length as usize)
|
||||
pub fn deserialize_byte_lenenc(buf: &Vec<u8>, index: &mut usize) -> Bytes {
|
||||
let length = deserialize_int_3(&buf, &mut *index);
|
||||
let value = Bytes::from(&buf[*index..*index + length as usize]);
|
||||
*index = *index + length as usize;
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn deserialize_byte_eof(buf: &Vec<u8>, index: &usize) -> (Bytes, usize) {
|
||||
(Bytes::from(&buf[*index..]), buf.len())
|
||||
pub fn deserialize_byte_eof(buf: &Vec<u8>, index: &mut usize) -> Bytes {
|
||||
let value = Bytes::from(&buf[*index..]);
|
||||
*index = buf.len();
|
||||
value
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Reference: https://mariadb.com/kb/en/library/connection
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use failure::{Error, err_msg};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use crate::protocol::deserialize::*;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use failure::{err_msg, Error};
|
||||
|
||||
pub trait Deserialize: Sized {
|
||||
fn deserialize(buf: &mut Vec<u8>) -> Result<Self, Error>;
|
||||
|
@ -129,42 +129,38 @@ impl Deserialize for InitialHandshakePacket {
|
|||
fn deserialize(buf: &mut Vec<u8>) -> Result<Self, Error> {
|
||||
let mut index = 0;
|
||||
|
||||
let (length, index) = deserialize_int_3(&buf, &index);
|
||||
let length = deserialize_int_3(&buf, &mut index);
|
||||
|
||||
if buf.len() != length as usize {
|
||||
return Err(err_msg("Lengths to do not match"));
|
||||
}
|
||||
|
||||
let mut sequence_number = 0;
|
||||
(sequence_number, index) = deserialize_int_1(&buf, &index);
|
||||
let sequence_number = deserialize_int_1(&buf, &mut index);
|
||||
|
||||
if sequence_number != 0 {
|
||||
return Err(err_msg("Squence Number of Initial Handshake Packet is not 0"));
|
||||
}
|
||||
|
||||
let (protocol_version, index) = deserialize_int_1(&buf, &index);
|
||||
let (server_version, index) = deserialize_string_null(&buf, &index);
|
||||
let (connection_id, index) = deserialize_int_4(&buf, &index);
|
||||
let (auth_seed, index) = deserialize_string_fix(&buf, &index, 8);
|
||||
let protocol_version = deserialize_int_1(&buf, &mut index);
|
||||
let server_version = deserialize_string_null(&buf, &mut index);
|
||||
let connection_id = deserialize_int_4(&buf, &mut index);
|
||||
let auth_seed = deserialize_string_fix(&buf, &mut index, 8);
|
||||
|
||||
// Skip reserved byte
|
||||
index += 1;
|
||||
|
||||
let (cap, index) = deserialize_int_2(&buf, &index);
|
||||
let mut capabilities = Capabilities::from_bits(cap.into()).unwrap();
|
||||
let mut capabilities =
|
||||
Capabilities::from_bits(deserialize_int_2(&buf, &mut index).into()).unwrap();
|
||||
|
||||
let (collation, index) = deserialize_int_1(&buf, &index);
|
||||
let collation = deserialize_int_1(&buf, &mut index);
|
||||
let status = deserialize_int_2(&buf, &mut index);
|
||||
|
||||
let (status, index) = deserialize_int_2(&buf, &index);
|
||||
|
||||
let (cap, index) = deserialize_int_2(&buf, &index);
|
||||
capabilities |= Capabilities::from_bits(cap.into()).unwrap();
|
||||
capabilities |=
|
||||
Capabilities::from_bits(deserialize_int_2(&buf, &mut index).into()).unwrap();
|
||||
|
||||
let mut plugin_data_length = 0;
|
||||
if !(capabilities & Capabilities::PLUGIN_AUTH).is_empty() {
|
||||
let (plugin, i) = deserialize_int_1(&buf, &index);
|
||||
plugin_data_length = plugin;
|
||||
index = i;
|
||||
plugin_data_length = deserialize_int_1(&buf, &mut index);
|
||||
} else {
|
||||
// Skip reserve byte
|
||||
index += 1;
|
||||
|
@ -174,9 +170,8 @@ impl Deserialize for InitialHandshakePacket {
|
|||
index += 6;
|
||||
|
||||
if (capabilities & Capabilities::CLIENT_MYSQL).is_empty() {
|
||||
let (cap, i) = deserialize_int_4(&buf, &index);
|
||||
capabilities |= Capabilities::from_bits(cap.into()).unwrap();
|
||||
index = i;
|
||||
capabilities |=
|
||||
Capabilities::from_bits(deserialize_int_4(&buf, &mut index).into()).unwrap();
|
||||
} else {
|
||||
// Skip filler
|
||||
index += 4;
|
||||
|
@ -186,13 +181,9 @@ impl Deserialize for InitialHandshakePacket {
|
|||
let mut auth_plugin_name: Option<Bytes> = None;
|
||||
if !(capabilities & Capabilities::SECURE_CONNECTION).is_empty() {
|
||||
let len = std::cmp::max(12, plugin_data_length as usize - 9);
|
||||
let (scram, i) = deserialize_string_fix(&buf, &index, len);
|
||||
scramble = Some(scram);
|
||||
index = i;
|
||||
scramble = Some(deserialize_string_fix(&buf, &mut index, len));
|
||||
} else {
|
||||
let (plugin, i) = deserialize_string_null(&buf, &index);
|
||||
let auth_plugin_name = Some(plugin);
|
||||
index = i;
|
||||
auth_plugin_name = Some(deserialize_string_null(&buf, &mut index));
|
||||
}
|
||||
|
||||
Ok(InitialHandshakePacket {
|
||||
|
@ -215,10 +206,10 @@ impl Deserialize for InitialHandshakePacket {
|
|||
impl Deserialize for OkPacket {
|
||||
fn deserialize(buf: &mut Vec<u8>) -> Result<Self, Error> {
|
||||
let mut index = 1;
|
||||
let (affected_rows, index) = deserialize_int_lenenc(&buf, &index);
|
||||
let (last_insert_id, index) = deserialize_int_lenenc(&buf, &index);
|
||||
let (server_status, index) = deserialize_int_2(&buf, &index);
|
||||
let (warning_count, index) = deserialize_int_2(&buf, &index);
|
||||
let affected_rows = deserialize_int_lenenc(&buf, &mut index);
|
||||
let last_insert_id = deserialize_int_lenenc(&buf, &mut index);
|
||||
let server_status = deserialize_int_2(&buf, &mut index);
|
||||
let warning_count = deserialize_int_2(&buf, &mut index);
|
||||
|
||||
// Assuming CLIENT_SESSION_TRACK is unsupported
|
||||
let session_state_info = None;
|
||||
|
@ -241,7 +232,7 @@ impl Deserialize for OkPacket {
|
|||
impl Deserialize for ErrPacket {
|
||||
fn deserialize(buf: &mut Vec<u8>) -> Result<Self, Error> {
|
||||
let mut index = 1;
|
||||
let (error_code, index) = deserialize_int_2(&buf, &index);
|
||||
let error_code = deserialize_int_2(&buf, &mut index);
|
||||
|
||||
let mut stage = None;
|
||||
let mut max_stage = None;
|
||||
|
@ -254,27 +245,17 @@ impl Deserialize for ErrPacket {
|
|||
|
||||
// Progress Reporting
|
||||
if error_code == 0xFFFF {
|
||||
let (d_stage, index) = deserialize_int_1(&buf, &index);
|
||||
let (d_max_stage, index) = deserialize_int_1(&buf, &index);
|
||||
let (d_progress, index) = deserialize_int_3(&buf, &index);
|
||||
let (d_progress_info, index) = deserialize_string_lenenc(&buf, &index);
|
||||
stage = Some(d_stage);
|
||||
max_stage = Some(d_max_stage);
|
||||
progress = Some(d_progress);
|
||||
progress_info = Some(d_progress_info);
|
||||
|
||||
|
||||
stage = Some(deserialize_int_1(&buf, &mut index));
|
||||
max_stage = Some(deserialize_int_1(&buf, &mut index));
|
||||
progress = Some(deserialize_int_3(&buf, &mut index));
|
||||
progress_info = Some(deserialize_string_lenenc(&buf, &mut index));
|
||||
} else {
|
||||
if buf[index] == b'#' {
|
||||
let (d_sql_state_marker, index) = deserialize_string_fix(&buf, &index, 1);
|
||||
let (d_sql_state, index) = deserialize_string_fix(&buf, &index, 5);
|
||||
let (d_error_message, index) = deserialize_string_eof(&buf, &index);
|
||||
sql_state_marker = Some(d_sql_state_marker);
|
||||
sql_state = Some(d_sql_state);
|
||||
error_message = Some(d_error_message);
|
||||
sql_state_marker = Some(deserialize_string_fix(&buf, &mut index, 1));
|
||||
sql_state = Some(deserialize_string_fix(&buf, &mut index, 5));
|
||||
error_message = Some(deserialize_string_eof(&buf, &mut index));
|
||||
} else {
|
||||
let (d_error_message, index) = deserialize_string_eof(&buf, &index);
|
||||
error_message = Some(d_error_message);
|
||||
error_message = Some(deserialize_string_eof(&buf, &mut index));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue