#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/15439811?v=3&s=200",
html_favicon_url = "https://iorust.github.io/favicon.ico",
html_root_url = "https://iorust.github.io",
html_playground_url = "https://play.rust-lang.org",
issue_tracker_base_url = "https://github.com/iorust/msgp-rust/issues")]
use std::ptr;
use std::io::{Result, Error, ErrorKind};
pub fn encode(val: &[u8]) -> Vec<u8> {
let len: usize = val.len();
assert!(len < 268435456);
if len < 128 {
let mut res: Vec<u8> = Vec::with_capacity(len + 1);
res.push(len as u8);
copy_to_vec(val, &mut res, 1, 0, val.len());
return res;
} else if len < 16384 {
let mut res: Vec<u8> = Vec::with_capacity(len + 2);
let len = len as u16;
res.push(((len >> 7) | 0x80u16) as u8);
res.push((len & 0x7Fu16) as u8);
copy_to_vec(val, &mut res, 2, 0, val.len());
return res;
} else if len < 2097152 {
let mut res: Vec<u8> = Vec::with_capacity(len + 3);
let len = len as u32;
res.push((((len >> 14) & 0x7Fu32) as u8) | 0x80u8);
res.push((((len >> 7) & 0x7Fu32) as u8) | 0x80u8);
res.push((len & 0x7Fu32) as u8);
copy_to_vec(val, &mut res, 3, 0, val.len());
return res;
} else {
let mut res: Vec<u8> = Vec::with_capacity(len + 4);
let len = len as u32;
res.push((((len >> 21) & 0x7Fu32) as u8) | 0x80u8);
res.push((((len >> 14) & 0x7Fu32) as u8) | 0x80u8);
res.push((((len >> 7) & 0x7Fu32) as u8) | 0x80u8);
res.push((len & 0x7Fu32) as u8);
copy_to_vec(val, &mut res, 4, 0, val.len());
return res;
}
}
pub fn decode(val: &[u8]) -> Option<Vec<u8>> {
let src_len = val.len();
if src_len == 0 {
return None;
}
if let Ok(res) = parse_buffer(val, 0) {
if res.1 == 0 || res.1 > src_len {
return None;
}
let len: usize = res.1 - res.0;
let mut buf: Vec<u8> = Vec::with_capacity(len);
copy_to_vec(val, &mut buf, 0, res.0, len);
return Some(buf);
}
return None;
}
#[derive(Debug)]
pub struct Decoder {
pos: usize,
msg_start: usize,
msg_end: usize,
buf: Vec<u8>,
res: Vec<Vec<u8>>,
}
impl Decoder {
pub fn new() -> Self {
Decoder {
pos: 0,
msg_start: 0,
msg_end: 0,
buf: Vec::new(),
res: Vec::with_capacity(8),
}
}
pub fn feed(&mut self, buf: &[u8]) -> Result<usize> {
self.buf.extend_from_slice(buf);
self.parse()
}
pub fn read(&mut self) -> Option<Vec<u8>> {
if self.res.len() == 0 {
return None;
}
Some(self.res.remove(0))
}
pub fn buffer_len(&self) -> usize {
self.buf.len()
}
pub fn result_len(&self) -> usize {
self.res.len()
}
fn parse(&mut self) -> Result<usize> {
let mut count: usize = 0;
while self.msg_end <= self.buf.len() {
if self.msg_start > self.pos {
let len: usize = self.msg_end - self.msg_start;
let mut buf: Vec<u8> = Vec::with_capacity(len);
if len > 0 {
copy_to_vec(&self.buf, &mut buf, 0, self.msg_start, len);
}
count += 1;
self.res.push(buf);
self.pos = self.msg_end;
self.msg_start = self.msg_end;
}
if self.buf.len() == self.pos {
self.pos = 0;
self.msg_start = 0;
self.msg_end = 0;
self.buf.clear();
return Ok(count);
}
match parse_buffer(&self.buf, self.pos) {
Ok((0, 0)) => {}
Ok((start, end)) => {
self.msg_start = start;
self.msg_end = end;
}
Err(err) => {
return Err(err);
}
}
}
Ok(count)
}
}
fn parse_buffer(buf: &[u8], pos: usize) -> Result<(usize, usize)> {
let mut byte: u8 = 0;
let mut total: usize = 0;
let mut pos: usize = pos;
loop {
let len = unsafe { *buf.get_unchecked(pos) as usize };
pos += 1;
if len < 128 {
return Ok((pos, pos + total + len));
}
byte += 1;
if byte >= 4 {
return Err(Error::new(ErrorKind::InvalidData,
"Max buffer length must be small than 268435456"));
}
if pos >= buf.len() {
return Ok((0, 0));
}
total = ((len & 0x7f) + total) * 128;
}
}
fn copy_to_vec(src: &[u8], dst: &mut Vec<u8>, dst_start: usize, src_start: usize, count: usize) {
let len = dst.len();
unsafe {
ptr::copy_nonoverlapping(src.get_unchecked(src_start),
dst.get_unchecked_mut(dst_start),
count);
dst.set_len(len + count);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encode_len_eq_0() {
assert_eq!(encode(&vec![]), vec![0]);
}
#[test]
fn encode_len_lt_128() {
assert_eq!(encode(&vec![0x1u8, 0x2u8]), vec![0x2u8, 0x1u8, 0x2u8]);
let mut res = Vec::with_capacity(127 + 1);
res.extend_from_slice(&[0x7fu8]);
res.append(&mut vec![0xffu8; 127]);
assert_eq!(encode(&vec![0xffu8; 127]), res);
}
#[test]
fn encode_len_eq_128() {
let mut res = Vec::with_capacity(128 + 2);
res.extend_from_slice(&[0x81u8, 0x00u8]);
res.append(&mut vec![0xffu8; 128]);
assert_eq!(encode(&vec![0xffu8; 128]), res);
}
#[test]
fn encode_len_lt_16384() {
let mut res = Vec::with_capacity(129 + 2);
res.extend_from_slice(&[0x81u8, 0x01u8]);
res.append(&mut vec![0xffu8; 129]);
assert_eq!(encode(&vec![0xffu8; 129]), res);
let mut res = Vec::with_capacity(16383 + 2);
res.extend_from_slice(&[0xffu8, 0x7fu8]);
res.append(&mut vec![0xffu8; 16383]);
assert_eq!(encode(&vec![0xffu8; 16383]), res);
}
#[test]
fn encode_len_eq_16384() {
let mut res = Vec::with_capacity(16384 + 3);
res.extend_from_slice(&[0x81u8, 0x80u8, 0x00u8]);
res.append(&mut vec![0xffu8; 16384]);
assert_eq!(encode(&vec![0xffu8; 16384]), res);
}
#[test]
fn encode_len_lt_2097152() {
let mut res = Vec::with_capacity(16385 + 3);
res.extend_from_slice(&[0x81u8, 0x80u8, 0x01u8]);
res.append(&mut vec![0xffu8; 16385]);
assert_eq!(encode(&vec![0xffu8; 16385]), res);
let mut res = Vec::with_capacity(2097151 + 3);
res.extend_from_slice(&[0xffu8, 0xffu8, 0x7fu8]);
res.append(&mut vec![0xffu8; 2097151]);
assert_eq!(encode(&vec![0xffu8; 2097151]), res);
}
#[test]
fn encode_len_eq_2097152() {
let mut res = Vec::with_capacity(2097152 + 4);
res.extend_from_slice(&[0x81u8, 0x80u8, 0x80u8, 0x00u8]);
res.append(&mut vec![0xffu8; 2097152]);
assert_eq!(encode(&vec![0xffu8; 2097152]), res);
}
#[test]
fn encode_len_lt_268435456() {
let mut res = Vec::with_capacity(2097153 + 4);
res.extend_from_slice(&[0x81u8, 0x80u8, 0x80u8, 0x01u8]);
res.append(&mut vec![0xffu8; 2097153]);
assert_eq!(encode(&vec![0xffu8; 2097153]), res);
let mut res = Vec::with_capacity(268435455 + 4);
res.extend_from_slice(&[0xffu8, 0xffu8, 0xffu8, 0x7fu8]);
res.append(&mut vec![0xffu8; 268435455]);
assert_eq!(encode(&vec![0xffu8; 268435455]), res);
}
#[test]
fn decode_zero_buf() {
let res = decode((&vec![]));
assert_eq!(res, None);
}
#[test]
fn decode_half_prefix_buf() {
let res = decode((&vec![0x81u8, 0x80u8]));
assert_eq!(res, None);
}
#[test]
fn decode_half_buf() {
let res = decode((&vec![0x3u8, 0x01u8, 0x02u8]));
assert_eq!(res, None);
}
#[test]
fn decode_sim_buf() {
let res = decode((&vec![0x3u8, 0x01u8, 0x02u8, 0x03u8]));
assert_eq!(res.unwrap(), vec![0x01u8, 0x02u8, 0x03u8]);
}
#[test]
fn decode_buf() {
let res = decode(&encode(&mut vec![0xffu8; 16384]));
assert_eq!(res.unwrap(), vec![0xffu8; 16384]);
}
#[test]
fn decoder_sim() {
let mut decoder = Decoder::new();
decoder.feed(&encode(&vec![0xffu8; 16384])).unwrap();
assert_eq!(decoder.read().unwrap(), vec![0xffu8; 16384]);
}
}