Skip to content

Commit

Permalink
Merge pull request #33 from shindan-io/oxidized_preamble_parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
puffyCid authored Nov 23, 2024
2 parents 20579ec + ef252b1 commit 7fd1d1a
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 27 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ simplelog = "0.12.2"
csv = "1.3.0"
chrono = "0.4.38"
criterion = "0.5.1"
anyhow = "1.0.93"

[[bench]]
name = "high_sierra_benchmark"
Expand Down
1 change: 1 addition & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ allow = [
"BSL-1.0",
"Unlicense",
"Unicode-DFS-2016",
"Unicode-3.0",
]
# List of explicitly disallowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
clippy::checked_conversions,
clippy::unnecessary_cast
)]

mod catalog;
mod chunks;
mod chunkset;
Expand Down
58 changes: 31 additions & 27 deletions src/preamble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,68 @@
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.

use std::mem::size_of;

use nom::{
bytes::complete::take,
number::complete::{le_u32, le_u64},
sequence::tuple,
IResult,
};

#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
pub struct LogPreamble {
pub chunk_tag: u32,
pub chunk_sub_tag: u32,
pub chunk_data_size: u64,
}

impl LogPreamble {
/// Get the preamble (first 16 bytes of all Unified Log entries (chunks)) to detect the log (chunk) type. Ex: Firehose, Statedump, Simpledump, Catalog, etc
pub fn detect_preamble(data: &[u8]) -> nom::IResult<&[u8], LogPreamble> {
let mut preamble = LogPreamble {
chunk_tag: 0,
chunk_sub_tag: 0,
chunk_data_size: 0,
};

let (input, tag) = take(size_of::<u32>())(data)?;
let (input, sub_tag) = take(size_of::<u32>())(input)?;
let (input, data_size) = take(size_of::<u64>())(input)?;

let (_, trace_tag) = le_u32(tag)?;
let (_, trace_sub_tag) = le_u32(sub_tag)?;
let (_, trace_data_size) = le_u64(data_size)?;

preamble.chunk_tag = trace_tag;
preamble.chunk_sub_tag = trace_sub_tag;
preamble.chunk_data_size = trace_data_size;
/// Do not consume the input
pub fn detect_preamble(input: &[u8]) -> IResult<&[u8], Self> {
let (_, preamble) = Self::parse(input)?;
Ok((input, preamble))
}

/// Get the preamble (first 16 bytes of all Unified Log entries (chunks)) to detect the log (chunk) type. Ex: Firehose, Statedump, Simpledump, Catalog, etc
/// And consume the input
pub fn parse(input: &[u8]) -> IResult<&[u8], Self> {
let (input, (chunk_tag, chunk_sub_tag, chunk_data_size)) =
tuple((le_u32, le_u32, le_u64))(input)?;
Ok((
input,
LogPreamble {
chunk_tag,
chunk_sub_tag,
chunk_data_size,
},
))
}
}

#[cfg(test)]
mod tests {
use super::LogPreamble;

#[test]
fn test_detect_preamble() {
let test_preamble_header = [
fn test_detect_preamble() -> anyhow::Result<()> {
let test_preamble_header = &[
0, 16, 0, 0, 17, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
];

let (_, preamble_data) = LogPreamble::detect_preamble(&test_preamble_header).unwrap();
let (output, preamble_data) = LogPreamble::detect_preamble(test_preamble_header)?;

assert_eq!(output, test_preamble_header);
assert_eq!(preamble_data.chunk_tag, 0x1000);
assert_eq!(preamble_data.chunk_sub_tag, 0x11);
assert_eq!(preamble_data.chunk_data_size, 0xd0);

let test_catalog_chunk = [11, 96, 0, 0, 17, 0, 0, 0, 176, 31, 0, 0, 0, 0, 0, 0];
let (_, preamble_data) = LogPreamble::detect_preamble(&test_catalog_chunk).unwrap();
let test_catalog_chunk = &[11, 96, 0, 0, 17, 0, 0, 0, 176, 31, 0, 0, 0, 0, 0, 0];
let (output, preamble_data) = LogPreamble::parse(test_catalog_chunk)?;

assert_eq!(output.len(), 0);
assert_eq!(preamble_data.chunk_tag, 0x600b);
assert_eq!(preamble_data.chunk_sub_tag, 0x11);
assert_eq!(preamble_data.chunk_data_size, 0x1fb0);

Ok(())
}
}

0 comments on commit 7fd1d1a

Please sign in to comment.