use super::super::{
super::{annotate::*, normal::*},
builder::*,
*,
};
use {
borc::{basic::streaming::*, errors::*},
std::io,
tracing::trace,
};
impl Parser {
pub fn parse_cbor<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 reader = Self::base64_reader(reader);
let mut decoder = Decoder::new(reader);
read_next_cbor(&mut decoder, &mut value_builder, None)?;
} else {
let mut decoder = Decoder::new(reader);
read_next_cbor(&mut decoder, &mut value_builder, None)?;
}
Ok(value_builder.finalize())
}
}
fn read_next_cbor<ReadT, AnnotatedT>(
decoder: &mut Decoder<ReadT>,
value_builder: &mut VariantBuilder<AnnotatedT>,
label: Option<Label>,
) -> Result<bool, ParseError>
where
ReadT: io::Read,
AnnotatedT: Annotated + Clone + Default,
{
let event = decoder.next_event()?;
trace!("{:?}", event);
match event {
Event::Break => {
return Ok(false);
}
Event::Tag(tag) => {
return read_next_cbor(decoder, value_builder, Some(Label::Integer(tag as i64)));
}
Event::Null => {
value_builder.add(Null::default().with_label(label), None);
}
Event::Unsigned(unsigned_integer) => {
value_builder.add(UnsignedInteger::from(unsigned_integer).with_label(label), None);
}
Event::Signed(integer) => {
let integer = Event::interpret_signed_checked(integer).ok_or_else(|| DecodeError::Malformed)?;
value_builder.add(Integer::from(integer).with_label(label), None);
}
Event::Float(float) => {
value_builder.add(Float::from(float).with_label(label), None);
}
Event::Bool(boolean) => {
value_builder.add(Boolean::from(boolean).with_label(label), None);
}
Event::TextString(string) => {
value_builder.add(Text::from(string).with_label(label), None);
}
Event::UnknownLengthTextString => {
let string = read_cbor_unknown_length_text_string(decoder)?;
value_builder.add(Text::from(string).with_label(label), None);
}
Event::ByteString(bytes) => {
value_builder.add(Blob::from(bytes).with_label(label), None);
}
Event::UnknownLengthByteString => {
let bytes = read_cbor_unknown_length_bytes(decoder)?;
value_builder.add(Blob::from(bytes).with_label(label), None);
}
Event::Array(length) => {
value_builder.start_list_with_label(label, None);
for _ in 0..length {
read_next_cbor(decoder, value_builder, None)?;
}
value_builder.end_container();
}
Event::UnknownLengthArray => {
value_builder.start_list_with_label(label, None);
loop {
match decoder.next_event()? {
Event::Break => {
break;
}
_ => {
read_next_cbor(decoder, value_builder, None)?;
}
}
}
value_builder.end_container();
}
Event::Map(length) => {
value_builder.start_map_with_label(label, None);
for _ in 0..length {
read_next_cbor(decoder, value_builder, None)?;
read_next_cbor(decoder, value_builder, None)?;
}
value_builder.end_container();
}
Event::UnknownLengthMap => {
value_builder.start_map_with_label(label, None);
loop {
match decoder.next_event()? {
Event::Break => {
break;
}
_ => {
read_next_cbor(decoder, value_builder, None)?;
}
}
}
value_builder.end_container();
}
Event::Undefined => {}
}
Ok(true)
}
fn read_cbor_unknown_length_text_string<ReadT>(decoder: &mut Decoder<ReadT>) -> Result<String, DecodeError>
where
ReadT: io::Read,
{
let mut buffer = String::default();
loop {
match decoder.next_event()? {
Event::TextString(string) => {
buffer.push_str(&string);
}
Event::Break => return Ok(buffer),
_ => return Err(DecodeError::Malformed),
}
}
}
fn read_cbor_unknown_length_bytes<ReadT>(decoder: &mut Decoder<ReadT>) -> Result<Vec<u8>, DecodeError>
where
ReadT: io::Read,
{
let mut buffer = Vec::default();
loop {
match decoder.next_event()? {
Event::ByteString(bytes) => {
buffer.extend_from_slice(&bytes);
}
Event::Break => return Ok(buffer),
_ => return Err(DecodeError::Malformed),
}
}
}