extern crate encoding_rs;
use crate::input::ByteCounter;
use crate::mission::Mission;
use crate::options::Radix;
use crate::options::ARGS;
use crate::options::ASCII_ENC_LABEL;
use std::io::Write;
use std::str;
#[cfg(not(test))]
pub const OUTPUT_BUF_LEN: usize = 0x9192;
#[cfg(test)]
pub const OUTPUT_BUF_LEN: usize = 0x40;
pub const OUTPUT_LINE_METADATA_LEN: usize = 40;
#[derive(Debug, Eq, PartialEq)]
pub enum Precision {
Before,
Exact,
After,
}
#[derive(Debug)]
pub struct Finding<'a> {
pub input_file_id: Option<u8>,
pub mission: &'static Mission,
pub position: ByteCounter,
pub position_precision: Precision,
pub s: &'a str,
pub s_completes_previous_s: bool,
}
impl Eq for Finding<'_> {}
impl PartialEq for Finding<'_> {
fn eq(&self, other: &Self) -> bool {
(self.position == other.position)
&& (self.position_precision == other.position_precision)
&& (self.mission.encoding.name() == other.mission.encoding.name())
&& (self.mission.filter == other.mission.filter)
&& (self.s == other.s)
}
}
impl PartialOrd for Finding<'_> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if self.position != other.position {
self.position.partial_cmp(&other.position)
} else if self.mission.mission_id != other.mission.mission_id {
self.mission
.mission_id
.partial_cmp(&other.mission.mission_id)
} else if self.mission.filter.ubf != other.mission.filter.ubf {
self.mission
.filter
.ubf
.partial_cmp(&other.mission.filter.ubf)
} else {
self.mission.filter.af.partial_cmp(&other.mission.filter.af)
}
}
}
impl<'a> Finding<'a> {
pub fn print(&self, out: &mut dyn Write) -> Result<(), Box<std::io::Error>> {
out.write_all(b"\n")?;
if !ARGS.no_metadata {
if ARGS.inputs.len() > 1 {
if let Some(i) = self.input_file_id {
out.write_all(&[i + 64_u8, b' '])?;
}
};
if ARGS.radix.is_some() {
match &self.position_precision {
Precision::After => out.write_all(b">")?,
Precision::Exact => out.write_all(b" ")?,
Precision::Before => out.write_all(b"<")?,
};
match ARGS.radix {
Some(Radix::X) => out.write_fmt(format_args!("{:0x}", self.position,))?,
Some(Radix::D) => out.write_fmt(format_args!("{:0}", self.position,))?,
Some(Radix::O) => out.write_fmt(format_args!("{:0o}", self.position,))?,
None => {}
};
if self.s_completes_previous_s {
out.write_all(b"+\t")?
} else {
out.write_all(b" \t")?
};
}
if ARGS.encoding.len() > 1 {
out.write_all(&[b'(', self.mission.mission_id + 97_u8, b' '])?;
out.write_all(if self.mission.print_encoding_as_ascii {
ASCII_ENC_LABEL.as_bytes()
} else {
self.mission.encoding.name().as_bytes()
})?;
out.write_all(b")\t")?;
};
};
out.write_all(self.s.as_bytes())?;
Ok(())
}
}