1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::io::Cursor;
use std::io::Result;
use rowevents::value_type::*;
use byteorder::{LittleEndian, BigEndian, ReadBytesExt};
use rowevents::descriptor_datetime::*;
use rowevents::descriptor_decimal::*;
fn parse_string(metadata1: u8, metadata2: u8, data: &[u8]) -> Result<(ValueType, usize)> {
let max_len = metadata1 + metadata2 * 256;
let strlen = data[0] as usize;
let v = Vec::from(&data[1 .. strlen + 1]);
Ok((ValueType::String(v), strlen + 1))
}
fn parse_varchar(metadata1: u8, metadata2: u8, data: &[u8]) -> Result<(ValueType, usize)> {
let max_len: u32 = metadata1 as u32 + metadata2 as u32 * 256;
let mut cursor = Cursor::new(&data);
let (from, strlen) = if max_len < 256 {
(1, cursor.read_u8()? as usize)
} else {
(2, cursor.read_i16::<LittleEndian>()? as usize)
};
let v = Vec::from(&data[from .. strlen + from]);
Ok((ValueType::String(v), strlen + from))
}
fn parse_blob(metadata1: u8, metadata2: u8, data: &[u8]) -> Result<(ValueType, usize)> {
let max_len = metadata1 + metadata2 * 256;
let mut cursor = Cursor::new(&data);
let strlen = cursor.read_i16::<LittleEndian>()? as usize;
let v = Vec::from(&data[2 .. strlen + 2]);
Ok((ValueType::String(v), strlen + 2))
}
pub fn parse_field(field_type: u8, nullable: bool, metadata1: u8, metadata2: u8, data: &[u8]) -> Result<(ValueType, usize)> {
let (value, offset) = if field_type == FieldType::Tiny as u8 {
let mut cursor = Cursor::new(&data);
let v:i8 = cursor.read_i8()?;
(ValueType::Tinyint(v), 1)
} else if field_type == FieldType::Short as u8 {
let mut cursor = Cursor::new(&data);
let v:i16 = cursor.read_i16::<LittleEndian>()?;
(ValueType::Shortint(v), 2)
} else if field_type == FieldType::Long as u8 {
let mut cursor = Cursor::new(&data);
let v:i32 = cursor.read_i32::<LittleEndian>()?;
(ValueType::Int(v), 4)
} else if field_type == FieldType::Longlong as u8 {
let mut cursor = Cursor::new(&data);
let v:i64 = cursor.read_i64::<LittleEndian>()?;
(ValueType::Longlong(v), 8)
} else if field_type == FieldType::Float as u8 {
let mut cursor = Cursor::new(&data);
let v:f32 = cursor.read_f32::<LittleEndian>()?;
(ValueType::Float(v), 4)
} else if field_type == FieldType::Double as u8 {
let mut cursor = Cursor::new(&data);
let v:f64 = cursor.read_f64::<LittleEndian>()?;
(ValueType::Double(v), 8)
} else if field_type == FieldType::Datetime2 as u8 {
let (dt, offset) = parse_datetime2(metadata1, metadata2, data)?;
(dt, offset)
} else if field_type == FieldType::NewDecimal as u8 {
let (dcm, offset) = parse_new_decimal(metadata1, metadata2, data)?;
(dcm, offset)
} else if field_type == FieldType::Varchar as u8 {
let (strval, offset) = parse_varchar(metadata1, metadata2, data)?;
(strval, offset)
} else if field_type == FieldType::String as u8 {
let (strval, offset) = parse_string(metadata1, metadata2, data)?;
(strval, offset)
} else if field_type == FieldType::Blob as u8 {
let (strval, offset) = parse_blob(metadata1, metadata2, data)?;
(strval, offset)
} else if field_type == FieldType::Timestamp as u8 {
let mut cursor = Cursor::new(&data);
let v:u32 = cursor.read_u32::<BigEndian>()?;
(ValueType::Timestamp(v), 4)
} else if field_type == FieldType::Timestamp2 as u8 {
let mut cursor = Cursor::new(&data);
let v:u32 = cursor.read_u32::<BigEndian>()?;
(ValueType::Timestamp(v), 4)
} else {
(ValueType::Unknown, 0)
};
Ok((value, offset))
}