mod dec;
mod ext;
mod sint;
mod str;
mod uint;
pub use self::sint::{read_nfix, read_i8, read_i16, read_i32, read_i64};
pub use self::uint::{read_pfix, read_u8, read_u16, read_u32, read_u64};
pub use self::dec::{read_f32, read_f64};
pub use self::str::{read_str_len, read_str, read_str_from_slice, read_str_ref, DecodeStringError};
pub use self::ext::{read_fixext1, read_fixext2, read_fixext4, read_fixext8, read_fixext16, read_ext_meta, ExtMeta};
use std::error;
use std::fmt::{self, Display, Formatter};
use std::io::Read;
use byteorder::{self, ReadBytesExt};
use num_traits::cast::FromPrimitive;
use crate::Marker;
pub type Error = ::std::io::Error;
#[derive(Debug)]
pub struct MarkerReadError(pub Error);
#[derive(Debug)]
pub enum ValueReadError {
InvalidMarkerRead(Error),
InvalidDataRead(Error),
TypeMismatch(Marker),
}
impl error::Error for ValueReadError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
ValueReadError::InvalidMarkerRead(ref err) |
ValueReadError::InvalidDataRead(ref err) => Some(err),
ValueReadError::TypeMismatch(..) => None,
}
}
}
impl Display for ValueReadError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(match *self {
ValueReadError::InvalidMarkerRead(..) => "failed to read MessagePack marker",
ValueReadError::InvalidDataRead(..) => "failed to read MessagePack data",
ValueReadError::TypeMismatch(..) => {
"the type decoded isn't match with the expected one"
}
})
}
}
impl From<MarkerReadError> for ValueReadError {
fn from(err: MarkerReadError) -> ValueReadError {
match err {
MarkerReadError(err) => ValueReadError::InvalidMarkerRead(err),
}
}
}
impl From<Error> for MarkerReadError {
fn from(err: Error) -> MarkerReadError {
MarkerReadError(err)
}
}
pub fn read_marker<R: Read>(rd: &mut R) -> Result<Marker, MarkerReadError> {
Ok(Marker::from_u8(rd.read_u8()?))
}
pub fn read_nil<R: Read>(rd: &mut R) -> Result<(), ValueReadError> {
match read_marker(rd)? {
Marker::Null => Ok(()),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_bool<R: Read>(rd: &mut R) -> Result<bool, ValueReadError> {
match read_marker(rd)? {
Marker::True => Ok(true),
Marker::False => Ok(false),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
#[derive(Debug)]
pub enum NumValueReadError {
InvalidMarkerRead(Error),
InvalidDataRead(Error),
TypeMismatch(Marker),
OutOfRange,
}
impl error::Error for NumValueReadError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
NumValueReadError::InvalidMarkerRead(ref err) |
NumValueReadError::InvalidDataRead(ref err) => Some(err),
NumValueReadError::TypeMismatch(..) |
NumValueReadError::OutOfRange => None,
}
}
}
impl Display for NumValueReadError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(match *self {
NumValueReadError::InvalidMarkerRead(..) => "failed to read MessagePack marker",
NumValueReadError::InvalidDataRead(..) => "failed to read MessagePack data",
NumValueReadError::TypeMismatch(..) => {
"the type decoded isn't match with the expected one"
}
NumValueReadError::OutOfRange => "out of range integral type conversion attempted",
})
}
}
impl From<MarkerReadError> for NumValueReadError {
fn from(err: MarkerReadError) -> NumValueReadError {
match err {
MarkerReadError(err) => NumValueReadError::InvalidMarkerRead(err),
}
}
}
impl From<ValueReadError> for NumValueReadError {
fn from(err: ValueReadError) -> NumValueReadError {
match err {
ValueReadError::InvalidMarkerRead(err) => NumValueReadError::InvalidMarkerRead(err),
ValueReadError::InvalidDataRead(err) => NumValueReadError::InvalidDataRead(err),
ValueReadError::TypeMismatch(err) => NumValueReadError::TypeMismatch(err),
}
}
}
#[doc(hidden)]
pub fn read_data_u8<R: Read>(rd: &mut R) -> Result<u8, ValueReadError> {
rd.read_u8().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_u16<R: Read>(rd: &mut R) -> Result<u16, ValueReadError> {
rd.read_u16::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_u32<R: Read>(rd: &mut R) -> Result<u32, ValueReadError> {
rd.read_u32::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_u64<R: Read>(rd: &mut R) -> Result<u64, ValueReadError> {
rd.read_u64::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_i8<R: Read>(rd: &mut R) -> Result<i8, ValueReadError> {
rd.read_i8().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_i16<R: Read>(rd: &mut R) -> Result<i16, ValueReadError> {
rd.read_i16::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_i32<R: Read>(rd: &mut R) -> Result<i32, ValueReadError> {
rd.read_i32::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_i64<R: Read>(rd: &mut R) -> Result<i64, ValueReadError> {
rd.read_i64::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_f32<R: Read>(rd: &mut R) -> Result<f32, ValueReadError> {
rd.read_f32::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
#[doc(hidden)]
pub fn read_data_f64<R: Read>(rd: &mut R) -> Result<f64, ValueReadError> {
rd.read_f64::<byteorder::BigEndian>().map_err(ValueReadError::InvalidDataRead)
}
pub fn read_int<T: FromPrimitive, R: Read>(rd: &mut R) -> Result<T, NumValueReadError> {
let val = match read_marker(rd)? {
Marker::FixPos(val) => T::from_u8(val),
Marker::FixNeg(val) => T::from_i8(val),
Marker::U8 => T::from_u8(read_data_u8(rd)?),
Marker::U16 => T::from_u16(read_data_u16(rd)?),
Marker::U32 => T::from_u32(read_data_u32(rd)?),
Marker::U64 => T::from_u64(read_data_u64(rd)?),
Marker::I8 => T::from_i8(read_data_i8(rd)?),
Marker::I16 => T::from_i16(read_data_i16(rd)?),
Marker::I32 => T::from_i32(read_data_i32(rd)?),
Marker::I64 => T::from_i64(read_data_i64(rd)?),
marker => return Err(NumValueReadError::TypeMismatch(marker)),
};
val.ok_or(NumValueReadError::OutOfRange)
}
pub fn read_array_len<R>(rd: &mut R) -> Result<u32, ValueReadError>
where
R: Read,
{
match read_marker(rd)? {
Marker::FixArray(size) => Ok(size as u32),
Marker::Array16 => Ok(read_data_u16(rd)? as u32),
Marker::Array32 => Ok(read_data_u32(rd)?),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_map_len<R: Read>(rd: &mut R) -> Result<u32, ValueReadError> {
let marker = read_marker(rd)?;
marker_to_len(rd, marker)
}
pub fn marker_to_len<R: Read>(rd: &mut R, marker: Marker) -> Result<u32, ValueReadError> {
match marker {
Marker::FixMap(size) => Ok(size as u32),
Marker::Map16 => Ok(read_data_u16(rd)? as u32),
Marker::Map32 => Ok(read_data_u32(rd)?),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_bin_len<R: Read>(rd: &mut R) -> Result<u32, ValueReadError> {
match read_marker(rd)? {
Marker::Bin8 => Ok(read_data_u8(rd)? as u32),
Marker::Bin16 => Ok(read_data_u16(rd)? as u32),
Marker::Bin32 => Ok(read_data_u32(rd)?),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}