use super::super::{
super::{
annotate::*,
normal::{Blob, *},
},
builder::*,
*,
};
use {
rmp::{decode::*, *},
std::io,
tracing::trace,
};
impl Parser {
pub fn parse_message_pack<ReadT, AnnotatedT>(&self, reader: &mut ReadT) -> Result<Variant<AnnotatedT>, ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
let mut value_builder = VariantBuilder::new(self.source.clone());
if self.base64 {
let mut reader = Self::base64_reader(reader);
read_next_message_pack(&mut reader, &mut value_builder)?;
} else {
read_next_message_pack(reader, &mut value_builder)?;
}
Ok(value_builder.finalize())
}
}
fn read_next_message_pack<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
let marker = read_marker(reader)?;
trace!("{:?}", marker);
match marker {
Marker::Reserved => {}
Marker::Null => value_builder.add(Null::default(), None),
Marker::True => value_builder.add(Boolean::from(true), None),
Marker::False => value_builder.add(Boolean::from(false), None),
Marker::FixNeg(integer) => value_builder.add(Integer::from(integer as i64), None),
Marker::I8 => value_builder.add(Integer::from(read_i8(reader)? as i64), None),
Marker::I16 => value_builder.add(Integer::from(read_i16(reader)? as i64), None),
Marker::I32 => value_builder.add(Integer::from(read_i32(reader)? as i64), None),
Marker::I64 => value_builder.add(Integer::from(read_i64(reader)?), None),
Marker::FixPos(integer) => value_builder.add(UnsignedInteger::from(integer as u64), None),
Marker::U8 => value_builder.add(UnsignedInteger::from(read_u8(reader)? as u64), None),
Marker::U16 => value_builder.add(UnsignedInteger::from(read_u16(reader)? as u64), None),
Marker::U32 => value_builder.add(UnsignedInteger::from(read_u32(reader)? as u64), None),
Marker::U64 => value_builder.add(UnsignedInteger::from(read_u64(reader)?), None),
Marker::F32 => value_builder.add(Float::from(read_f32(reader)?), None),
Marker::F64 => value_builder.add(Float::from(read_f64(reader)?), None),
Marker::Bin8 => {
let length = read_u8(reader)? as usize;
read_message_pack_bytes(reader, value_builder, length)?;
}
Marker::Bin16 => {
let length = read_u16(reader)? as usize;
read_message_pack_bytes(reader, value_builder, length)?;
}
Marker::Bin32 => {
let length = read_u32(reader)? as usize;
read_message_pack_bytes(reader, value_builder, length)?;
}
Marker::FixStr(length) => read_message_pack_string(reader, value_builder, length as usize)?,
Marker::Str8 => {
let length = read_u8(reader)? as usize;
read_message_pack_string(reader, value_builder, length)?;
}
Marker::Str16 => {
let length = read_u16(reader)? as usize;
read_message_pack_string(reader, value_builder, length)?;
}
Marker::Str32 => {
let length = read_u32(reader)? as usize;
read_message_pack_string(reader, value_builder, length)?;
}
Marker::FixExt1 => {
let label = read_i8(reader)? as i64;
read_message_pack_ext(reader, value_builder, 1, label)?;
}
Marker::FixExt2 => {
let label = read_i8(reader)? as i64;
read_message_pack_ext(reader, value_builder, 2, label)?;
}
Marker::FixExt4 => {
let label = read_i8(reader)? as i64;
read_message_pack_ext(reader, value_builder, 4, label)?;
}
Marker::FixExt8 => {
let label = read_i8(reader)? as i64;
read_message_pack_ext(reader, value_builder, 8, label)?;
}
Marker::FixExt16 => {
let label = read_i8(reader)? as i64;
read_message_pack_ext(reader, value_builder, 16, label)?;
}
Marker::Ext8 => {
let label = read_i8(reader)? as i64;
let length = read_u8(reader)? as usize;
read_message_pack_ext(reader, value_builder, length, label)?;
}
Marker::Ext16 => {
let label = read_i8(reader)? as i64;
let length = read_u16(reader)? as usize;
read_message_pack_ext(reader, value_builder, length, label)?;
}
Marker::Ext32 => {
let label = read_i8(reader)? as i64;
let length = read_u32(reader)? as usize;
read_message_pack_ext(reader, value_builder, length, label)?;
}
Marker::FixArray(length) => read_message_pack_array(reader, value_builder, length as usize)?,
Marker::Array16 => {
let length = read_u16(reader)? as usize;
read_message_pack_array(reader, value_builder, length)?;
}
Marker::Array32 => {
let length = read_u32(reader)? as usize;
read_message_pack_array(reader, value_builder, length)?;
}
Marker::FixMap(length) => read_message_pack_map(reader, value_builder, length as usize)?,
Marker::Map16 => {
let length = read_u16(reader)? as usize;
read_message_pack_map(reader, value_builder, length)?;
}
Marker::Map32 => {
let length = read_u32(reader)? as usize;
read_message_pack_map(reader, value_builder, length)?;
}
}
Ok(())
}
fn read_message_pack_string<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
length: usize,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
trace!("string length: {}", length);
let mut buffer = vec![0; length];
reader.read_exact_buf(&mut buffer)?;
let string = String::from_utf8(buffer)?;
Ok(value_builder.add(Text::from(string), None))
}
fn read_message_pack_bytes<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
length: usize,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
trace!("bytes length: {}", length);
let mut buffer = vec![0; length];
reader.read_exact_buf(&mut buffer)?;
Ok(value_builder.add(Blob::from(buffer), None))
}
fn read_message_pack_ext<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
length: usize,
label: i64,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
trace!("ext type: {}", label);
let mut buffer = vec![0; length];
reader.read_exact_buf(&mut buffer)?;
Ok(value_builder.add(Blob::from(buffer).with_label(Some(Label::Integer(label))), None))
}
fn read_message_pack_array<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
length: usize,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
trace!("array length: {}", length);
value_builder.start_list(None);
for _ in 0..length {
read_next_message_pack(reader, value_builder)?;
}
value_builder.end_container();
Ok(())
}
fn read_message_pack_map<ReadT, AnnotatedT>(
reader: &mut ReadT,
value_builder: &mut VariantBuilder<AnnotatedT>,
length: usize,
) -> Result<(), ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
trace!("map length: {}", length);
value_builder.start_map(None);
for _ in 0..length {
read_next_message_pack(reader, value_builder)?;
read_next_message_pack(reader, value_builder)?;
}
value_builder.end_container();
Ok(())
}
impl From<MarkerReadError> for ParseError {
fn from(marker_read_error: MarkerReadError) -> Self {
marker_read_error.0.into()
}
}