chunk header

This commit is contained in:
Alex Mikhalev 2021-11-18 21:05:46 -08:00
parent 153402755f
commit c6abdac270
5 changed files with 80 additions and 20 deletions

View File

@ -5,7 +5,7 @@ use regex::Regex;
use ros_message::{MessagePath, Msg};
use rsbag::{
index::{BagIndex, ConnInfo},
reader::IoReader,
reader::{BagReader, MmapReader},
};
fn parse_msgdef(message_name: &str, msgdef: &str) -> rsbag::Result<Msg> {
@ -53,28 +53,40 @@ fn main() {
let bag_path = &args[1];
let bag_file = File::open(bag_path).expect("Could not open bag file");
let mut bag_reader = IoReader::new(bag_file);
let mut bag_reader = MmapReader::new(bag_file).unwrap();
match BagIndex::read_all(&mut bag_reader) {
Ok(index) => {
for conn in &index.connections {
match parse_message_definitions(conn) {
Ok(msgs) => {
for msg in &msgs {
info!(
"message definition parsed: {:#?}",
msg.fields()
.iter()
.filter(|field| !field.is_constant())
.map(ToString::to_string)
.collect::<Vec<_>>()
);
}
}
Err(err) => error!("could not parse message definition: {}", err),
let index = match BagIndex::read_all(&mut bag_reader) {
Ok(index) => index,
Err(err) => {
error!("bag parse error: {}", err);
return;
}
};
for conn in &index.connections {
match parse_message_definitions(conn) {
Ok(msgs) => {
for msg in &msgs {
info!(
"message definition parsed: {:#?}",
msg.fields()
.iter()
.filter(|field| !field.is_constant())
.map(ToString::to_string)
.collect::<Vec<_>>()
);
}
}
Err(err) => error!("could not parse message definition: {}", err),
}
Err(err) => error!("bag parse error: {}", err),
}
let mut total_size = 0;
for chunk in &index.chunks {
let chunk_header = bag_reader.read_chunk_header(chunk.pos).unwrap();
total_size += chunk_header.uncompressed_size;
}
info!("total uncompressed size: {}", total_size);
}

38
src/chunk.rs Normal file
View File

@ -0,0 +1,38 @@
use std::str::FromStr;
use crate::{parse::Header, Error, Result};
#[derive(Clone, Copy, Debug)]
pub enum Compression {
None,
Bz2,
Lz4,
}
impl FromStr for Compression {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"none" => Compression::None,
"bz2" => Compression::Bz2,
"lz4" => Compression::Lz4,
_ => return Err(Error::UnsupportedCompression(s.to_string())),
})
}
}
#[derive(Debug)]
pub struct ChunkHeader {
pub compression: Compression,
pub uncompressed_size: u32,
}
impl ChunkHeader {
pub fn from_header(header: Header) -> Result<Self> {
Ok(Self {
compression: header.read_string(b"compression")?.parse()?,
uncompressed_size: header.read_u32(b"size")?,
})
}
}

View File

@ -13,6 +13,8 @@ pub enum Error {
UnsupportedVersion(parse::Version),
#[error("unsupported encryptor: {0}")]
UnsupportedEncryptor(String),
#[error("unsupported compression: {0}")]
UnsupportedCompression(String),
#[error("unexpected EOF")]
Eof,
#[error("invalid header op: {0}")]

View File

@ -2,5 +2,6 @@ mod error;
pub mod index;
pub mod parse;
pub mod reader;
pub mod chunk;
pub use error::{Error, Result};

View File

@ -2,6 +2,7 @@ use std::io::SeekFrom;
use nom::number::streaming::le_u32;
use crate::chunk::ChunkHeader;
use crate::error::{Error, Result};
use crate::index::{ChunkInfo, ConnInfo};
use crate::parse::{self, Header, Op, Version};
@ -59,4 +60,10 @@ pub trait BagReader {
self.skip_data()?;
ChunkInfo::from_header(header)
}
fn read_chunk_header(&mut self, pos: u64) -> Result<ChunkHeader> {
self.seek(SeekFrom::Start(pos))?;
let header = self.read_header_op(Op::Chunk)?;
ChunkHeader::from_header(header)
}
}