use std::io::Read;
use Marker;
use super::{read_marker, read_data_i8, read_data_u8, read_data_u16, read_data_u32, ValueReadError};
pub fn read_fixext1<R: Read>(rd: &mut R) -> Result<(i8, u8), ValueReadError> {
match try!(read_marker(rd)) {
Marker::FixExt1 => {
let ty = try!(read_data_i8(rd));
let data = try!(read_data_u8(rd));
Ok((ty, data))
}
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_fixext2<R: Read>(rd: &mut R) -> Result<(i8, [u8; 2]), ValueReadError> {
match try!(read_marker(rd)) {
Marker::FixExt2 => {
let mut buf = [0; 2];
read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
}
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_fixext4<R: Read>(rd: &mut R) -> Result<(i8, [u8; 4]), ValueReadError> {
match try!(read_marker(rd)) {
Marker::FixExt4 => {
let mut buf = [0; 4];
read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
}
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_fixext8<R: Read>(rd: &mut R) -> Result<(i8, [u8; 8]), ValueReadError> {
match try!(read_marker(rd)) {
Marker::FixExt8 => {
let mut buf = [0; 8];
read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
}
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_fixext16<R: Read>(rd: &mut R) -> Result<(i8, [u8; 16]), ValueReadError> {
match try!(read_marker(rd)) {
Marker::FixExt16 => {
let mut buf = [0; 16];
read_fixext_data(rd, &mut buf).map(|ty| (ty, buf))
}
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
fn read_fixext_data<R: Read>(rd: &mut R, buf: &mut [u8]) -> Result<i8, ValueReadError> {
let id = try!(read_data_i8(rd));
match rd.read_exact(buf) {
Ok(()) => Ok(id),
Err(err) => Err(ValueReadError::InvalidDataRead(From::from(err))),
}
}
#[derive(Debug, PartialEq)]
pub struct ExtMeta {
pub typeid: i8,
pub size: u32,
}
pub fn read_ext_meta<R: Read>(rd: &mut R) -> Result<ExtMeta, ValueReadError> {
let size = match try!(read_marker(rd)) {
Marker::FixExt1 => 1,
Marker::FixExt2 => 2,
Marker::FixExt4 => 4,
Marker::FixExt8 => 8,
Marker::FixExt16 => 16,
Marker::Ext8 => try!(read_data_u8(rd)) as u32,
Marker::Ext16 => try!(read_data_u16(rd)) as u32,
Marker::Ext32 => try!(read_data_u32(rd)),
marker => return Err(ValueReadError::TypeMismatch(marker)),
};
let ty = try!(read_data_i8(rd));
let meta = ExtMeta {
typeid: ty,
size: size,
};
Ok(meta)
}