use crate::types::FileType;
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum RelativePosition {
Start,
End,
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Step {
Small,
Large,
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum TestResult {
Matched,
Maybe,
NotMatched,
}
impl TestResult {
fn or_else<F>(self, other: F) -> TestResult
where
F: FnOnce() -> TestResult,
{
if self == TestResult::Matched {
TestResult::Matched
} else {
let other = other();
self | other
}
}
fn and<F>(self, other: F) -> TestResult
where
F: FnOnce() -> TestResult,
{
if self == TestResult::Matched || self == TestResult::Maybe {
let other = other();
self & other
} else {
TestResult::NotMatched
}
}
}
impl std::ops::BitOr for TestResult {
type Output = TestResult;
fn bitor(self, rhs: Self) -> Self::Output {
if (self == TestResult::Matched || rhs == TestResult::Matched)
|| (self == TestResult::Maybe && rhs == TestResult::Maybe)
{
TestResult::Matched
} else {
TestResult::NotMatched
}
}
}
impl std::ops::BitAnd for TestResult {
type Output = TestResult;
fn bitand(self, rhs: Self) -> Self::Output {
if self == TestResult::Matched && rhs == TestResult::Matched {
TestResult::Matched
} else if self == TestResult::Maybe && rhs == TestResult::Maybe {
TestResult::Maybe
} else if (self == TestResult::Matched && rhs == TestResult::Maybe)
|| (self == TestResult::Maybe && rhs == TestResult::Matched)
{
TestResult::Matched
} else {
TestResult::NotMatched
}
}
}
pub trait FileTypeMatcher {
fn test(&self, relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult;
}
impl FileTypeMatcher for FileType {
fn test(&self, relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
match self {
FileType::Zip => zip_test(relative_position, step, bytes),
FileType::Rar5 => rar5_test(relative_position, bytes),
FileType::Rar => rar_test(relative_position, bytes),
FileType::Tar => tar_test(relative_position, step, bytes),
FileType::Lzma => lzma_test(relative_position, step, bytes),
FileType::Xz => xz_test(relative_position, step, bytes),
FileType::Zst => zst_test(relative_position, step, bytes),
FileType::Png => png_test(relative_position, step, bytes),
FileType::Jpg => jpg_test(relative_position, step, bytes),
FileType::_7z => _7z_test(relative_position, step, bytes),
FileType::Opus => opus_test(relative_position, step, bytes),
FileType::Vorbis => vorbis_test(relative_position, step, bytes),
FileType::Mp3 => mp3_test(relative_position, step, bytes),
FileType::Webp => webp_test(relative_position, step, bytes),
FileType::Flac => flac_test(relative_position, step, bytes),
FileType::Matroska => matroska_test(relative_position, step, bytes),
FileType::Wasm => wasm_test(relative_position, step, bytes),
FileType::Class => class_test(relative_position, step, bytes),
FileType::Tasty => tasty_test(relative_position, step, bytes),
FileType::Mach => mach_test(relative_position, step, bytes),
FileType::Elf => elf_test(relative_position, step, bytes),
FileType::Wav => wav_test(relative_position, step, bytes),
FileType::Avi => avi_test(relative_position, step, bytes),
FileType::Aiff => aiff_test(relative_position, step, bytes),
FileType::Tiff => tiff_test(relative_position, step, bytes),
FileType::Sqlite3 => sqlite3_test(relative_position, step, bytes),
FileType::Ico => ico_test(relative_position, step, bytes),
FileType::Dalvik => dalvik_test(relative_position, step, bytes),
FileType::Pdf => pdf_test(relative_position, step, bytes),
FileType::DosMzExecutable => dos_mz_test(relative_position, step, bytes),
FileType::DosZmExecutable => dos_zm_test(relative_position, step, bytes),
FileType::Xcf => xcf_test(relative_position, step, bytes),
FileType::Gif => gif_test(relative_position, step, bytes),
FileType::Bmp => bmp_test(relative_position, step, bytes),
FileType::Iso => iso_test(relative_position, step, bytes),
FileType::Gpg => gpg_test(relative_position, step, bytes),
FileType::ArmoredGpg => armored_gpg_test(relative_position, step, bytes),
FileType::Swf => swf_test(relative_position, step, bytes),
FileType::Swc => swc_test(relative_position, step, bytes),
}
}
}
const LFHS: [u8; 4] = [0x50, 0x4b, 0x03, 0x04];
const ECDS: [u8; 4] = [0x50, 0x4b, 0x05, 0x06];
fn zip_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
match *relative_position {
RelativePosition::Start => {
if bytes.len() < 4 || *step != Step::Small {
TestResult::NotMatched
} else {
let header = &bytes[..4];
if header == LFHS {
TestResult::Maybe
} else {
TestResult::NotMatched
}
}
}
RelativePosition::End => {
if bytes.len() < 4 {
TestResult::NotMatched
} else {
let signature = &bytes[..4];
if signature == ECDS {
TestResult::Matched
} else {
TestResult::Maybe
}
}
}
}
}
const RAR_4_MARKER: [u8; 7] = [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00];
fn rar_test(relative_position: &RelativePosition, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start {
return windowing_test(bytes, &RAR_4_MARKER);
}
TestResult::NotMatched
}
const RAR_5_MARKER: [u8; 8] = [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00];
fn rar5_test(relative_position: &RelativePosition, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start {
return windowing_test(bytes, &RAR_5_MARKER);
}
TestResult::NotMatched
}
fn windowing_test(bytes: &[u8], matching: &[u8]) -> TestResult {
if bytes.len() < matching.len() {
return TestResult::NotMatched;
}
let mut i = 0;
loop {
if i < (bytes.len() - matching.len()) {
let size = i + matching.len();
let slice = &bytes[i..size];
if slice == matching {
return TestResult::Matched;
} else {
let mut any = false;
for i in slice {
if *i == matching[0] {
any = true;
}
}
if !any {
i += matching.len() - 1;
}
}
i += 1
} else {
break;
}
}
TestResult::NotMatched
}
const TAR_MARKER: [u8; 8] = [0x75, 0x73, 0x74, 0x61, 0x72, 0x00, 0x30, 0x30];
fn tar_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start
&& *step == Step::Small
&& bytes.len() >= 257 + 8
{
let slice = &bytes[257..257 + 8];
if slice == TAR_MARKER {
return TestResult::Matched;
}
}
TestResult::NotMatched
}
const LZMA_MARKER: [u8; 1] = [0x5d];
const LZMA_LV0_MARKER: &[u8] = &[0x04, 0x00];
const LZMA_LV1_MARKER: &[u8] = &[0x10, 0x00];
const LZMA_LV2_MARKER: &[u8] = &[0x20, 0x00];
const LZMA_LV3_MARKER: &[u8] = &[0x40, 0x00];
const LZMA_LV5_MARKER: &[u8] = &[0x80, 0x00];
const LZMA_LV7_MARKER: &[u8] = &[0x00, 0x01];
const LZMA_LV8_MARKER: &[u8] = &[0x00, 0x02];
const LZMA_LV9_MARKER: &[u8] = &[0x00, 0x04];
fn lzma_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start {
if *step == Step::Small {
if !bytes.is_empty() {
let slice = &bytes[0..1];
if slice == LZMA_MARKER {
return TestResult::Matched;
}
}
} else if bytes.len() >= 5 {
let slice = &bytes[0..5];
if slice[0..1] == LZMA_MARKER {
match &slice[3..5] {
LZMA_LV0_MARKER | LZMA_LV1_MARKER | LZMA_LV2_MARKER | LZMA_LV3_MARKER
| LZMA_LV5_MARKER | LZMA_LV7_MARKER | LZMA_LV8_MARKER | LZMA_LV9_MARKER => {
return TestResult::Matched
}
_ => {}
}
}
}
}
TestResult::NotMatched
}
const XZ_MARKER: [u8; 5] = [0xfd, 0x37, 0x7a, 0x58, 0x5a];
fn xz_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 5 {
let slice = &bytes[0..5];
if slice == XZ_MARKER {
return TestResult::Matched;
}
}
TestResult::NotMatched
}
const ZST_MARKER: [u8; 4] = [0x28, 0xb5, 0x2f, 0xfd];
fn zst_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 4 {
let slice = &bytes[0..4];
if slice == ZST_MARKER {
return TestResult::Matched;
}
}
TestResult::NotMatched
}
const PNG_SIGNATURE: [u8; 8] = [0x89, 0x50, 0x4e, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
fn png_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &PNG_SIGNATURE);
}
TestResult::NotMatched
}
const JPG_SIGNATURE: [u8; 2] = [0xFF, 0xD8];
fn jpg_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &JPG_SIGNATURE);
}
TestResult::NotMatched
}
const _7Z_SIGNATURE: [u8; 6] = [0x37, 0x7a, 0xBC, 0xAF, 0x27, 0x1C];
fn _7z_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &_7Z_SIGNATURE);
}
TestResult::NotMatched
}
const OPUS_START_SIGNATURE: [u8; 4] = [0x4f, 0x67, 0x67, 0x53];
const OPUS_INTERVAL: usize = 24;
const OPUS_HEAD_SIGNATURE: [u8; 8] = [0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64];
fn opus_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 36 {
if let TestResult::Matched = slice_test(bytes, &OPUS_START_SIGNATURE) {
let start = OPUS_START_SIGNATURE.len() + OPUS_INTERVAL;
return slice_test(&bytes[start..], &OPUS_HEAD_SIGNATURE);
}
}
TestResult::NotMatched
}
const VORBIS_INTERVAL: usize = 25;
const VORBIS_HEAD_SIGNATURE: [u8; 6] = [0x76, 0x6f, 0x72, 0x62, 0x69, 0x73];
fn vorbis_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 35 {
if let TestResult::Matched = slice_test(bytes, &OPUS_START_SIGNATURE) {
let start = OPUS_START_SIGNATURE.len() + VORBIS_INTERVAL;
return slice_test(&bytes[start..], &VORBIS_HEAD_SIGNATURE);
}
}
TestResult::NotMatched
}
const MP3_SIGNATURE_1: [u8; 2] = [0xFF, 0xFB];
const MP3_SIGNATURE_2: [u8; 2] = [0xFF, 0xF3];
const MP3_SIGNATURE_3: [u8; 2] = [0xFF, 0xF2];
const MP3_SIGNATURE_4: [u8; 3] = [0x49, 0x44, 0x43];
fn mp3_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &MP3_SIGNATURE_1)
.or_else(|| slice_test(bytes, &MP3_SIGNATURE_2))
.or_else(|| slice_test(bytes, &MP3_SIGNATURE_3))
.or_else(|| slice_test(bytes, &MP3_SIGNATURE_4));
}
TestResult::NotMatched
}
const WEBP_SIGNATURE_1: [u8; 4] = [0x52, 0x49, 0x46, 0x46];
const WEBP_SIGNATURE_2: [u8; 4] = [0x57, 0x45, 0x42, 0x50];
fn webp_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 12 {
return slice_test(bytes, &WEBP_SIGNATURE_1)
.and(|| slice_test(&bytes[8..], &WEBP_SIGNATURE_2));
}
TestResult::NotMatched
}
const FLAC_SIGNATURE: [u8; 4] = [0x66, 0x4C, 0x61, 0x43];
fn flac_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &FLAC_SIGNATURE);
}
TestResult::NotMatched
}
const MATROSKA_SIGNATURE: [u8; 4] = [0x1A, 0x45, 0xDF, 0xA3];
fn matroska_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &MATROSKA_SIGNATURE);
}
TestResult::NotMatched
}
const WASM_SIGNATURE: [u8; 4] = [0x00, 0x61, 0x73, 0x6D];
fn wasm_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &WASM_SIGNATURE);
}
TestResult::NotMatched
}
const CLASS_SIGNATURE: [u8; 4] = [0xCA, 0xFE, 0xBA, 0xBE];
fn class_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &CLASS_SIGNATURE);
}
TestResult::NotMatched
}
const TASTY_SIGNATURE: [u8; 4] = [0x5C, 0xA1, 0xAB, 0x1F];
fn tasty_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &TASTY_SIGNATURE);
}
TestResult::NotMatched
}
const MACH_SIGNATURE: [u8; 4] = [0xCF, 0xFA, 0xED, 0xFE];
fn mach_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &MACH_SIGNATURE);
}
TestResult::NotMatched
}
const ELF_SIGNATURE: [u8; 4] = [0x7F, 0x45, 0x4C, 0x46];
fn elf_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &ELF_SIGNATURE);
}
TestResult::NotMatched
}
const WAV_SIGNATURE_1: [u8; 4] = [0x52, 0x49, 0x46, 0x46];
const WAV_SIGNATURE_2: [u8; 4] = [0x57, 0x41, 0x56, 0x45];
fn wav_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 12 {
return slice_test(bytes, &WAV_SIGNATURE_1)
.and(|| slice_test(&bytes[8..], &WAV_SIGNATURE_2));
}
TestResult::NotMatched
}
const AVI_SIGNATURE_1: [u8; 4] = [0x52, 0x49, 0x46, 0x46];
const AVI_SIGNATURE_2: [u8; 4] = [0x41, 0x56, 0x49, 0x20];
fn avi_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 12 {
return slice_test(bytes, &AVI_SIGNATURE_1)
.and(|| slice_test(&bytes[8..], &AVI_SIGNATURE_2));
}
TestResult::NotMatched
}
const AIFF_SIGNATURE_1: [u8; 4] = [0x46, 0x4F, 0x52, 0x4D];
const AIFF_SIGNATURE_2: [u8; 4] = [0x41, 0x49, 0x46, 0x46];
fn aiff_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 12 {
return slice_test(bytes, &AIFF_SIGNATURE_1)
.and(|| slice_test(&bytes[8..], &AIFF_SIGNATURE_2));
}
TestResult::NotMatched
}
const TIFF_SIGNATURE_1: [u8; 4] = [0x49, 0x49, 0x2A, 0x00];
const TIFF_SIGNATURE_2: [u8; 4] = [0x4D, 0x4D, 0x00, 0x2A];
fn tiff_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &TIFF_SIGNATURE_1)
.or_else(|| slice_test(bytes, &TIFF_SIGNATURE_2));
}
TestResult::NotMatched
}
const SQLITE3_SIGNATURE_1: [u8; 16] = [
0x53, 0x51, 0x4C, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x20, 0x33, 0x00,
];
fn sqlite3_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &SQLITE3_SIGNATURE_1);
}
TestResult::NotMatched
}
const ICO_SIGNATURE_1: [u8; 4] = [0x00, 0x00, 0x01, 0x00];
fn ico_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &ICO_SIGNATURE_1);
}
TestResult::NotMatched
}
const DALVIK_SIGNATURE_1: [u8; 8] = [0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00];
fn dalvik_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &DALVIK_SIGNATURE_1);
}
TestResult::NotMatched
}
const PDF_SIGNATURE_1: [u8; 5] = [0x25, 0x50, 0x44, 0x46, 0x2D];
fn pdf_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &PDF_SIGNATURE_1);
}
TestResult::NotMatched
}
const DOS_MZ_SIGNATURE_1: [u8; 2] = [0x4D, 0x5A];
fn dos_mz_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &DOS_MZ_SIGNATURE_1);
}
TestResult::NotMatched
}
const DOS_ZM_SIGNATURE_1: [u8; 2] = [0x5A, 0x4D];
fn dos_zm_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &DOS_ZM_SIGNATURE_1);
}
TestResult::NotMatched
}
const XCF_SIGNATURE_1: [u8; 10] = [0x67, 0x69, 0x6D, 0x70, 0x20, 0x78, 0x63, 0x66, 0x20, 0x76];
fn xcf_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &XCF_SIGNATURE_1);
}
TestResult::NotMatched
}
const GIF_SIGNATURE_1: [u8; 4] = [0x47, 0x49, 0x46, 0x38];
fn gif_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &GIF_SIGNATURE_1);
}
TestResult::NotMatched
}
const BMP_SIGNATURE_1: [u8; 2] = [0x42, 0x4d];
fn bmp_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test_maybe(bytes, &BMP_SIGNATURE_1);
}
TestResult::NotMatched
}
const ISO_SIGNATURE_1: [u8; 5] = [0x43, 0x44, 0x30, 0x30, 0x31];
fn iso_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Large && bytes.len() >= 32769
{
return slice_test(&bytes[32769..], &ISO_SIGNATURE_1);
}
TestResult::NotMatched
}
const ARMORED_GPG_SIGNATURE_1: [u8; 27] = [
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, 0x47, 0x50, 0x20, 0x4d,
0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
];
fn armored_gpg_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small && bytes.len() >= 27 {
return slice_test(bytes, &ARMORED_GPG_SIGNATURE_1);
}
TestResult::NotMatched
}
const GPG_SIGNATURE_1: [u8; 2] = [0x85, 0x03];
fn gpg_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start
&& *step == Step::Small
&& bytes.len() >= 4
&& bytes[0] == GPG_SIGNATURE_1[0]
&& bytes[3] == GPG_SIGNATURE_1[1]
{
return TestResult::Matched;
}
TestResult::NotMatched
}
const SWF_SIGNATURE_1: [u8; 3] = [0x46, 0x57, 0x53];
fn swf_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &SWF_SIGNATURE_1);
}
TestResult::NotMatched
}
const SWC_SIGNATURE_1: [u8; 3] = [0x43, 0x57, 0x53];
fn swc_test(relative_position: &RelativePosition, step: &Step, bytes: &[u8]) -> TestResult {
if *relative_position == RelativePosition::Start && *step == Step::Small {
return slice_test(bytes, &SWC_SIGNATURE_1);
}
TestResult::NotMatched
}
fn slice_test(bytes: &[u8], matching: &[u8]) -> TestResult {
if bytes.len() >= matching.len() && &bytes[..matching.len()] == matching {
return TestResult::Matched;
}
TestResult::NotMatched
}
fn slice_test_maybe(bytes: &[u8], matching: &[u8]) -> TestResult {
if bytes.len() >= matching.len() && &bytes[..matching.len()] == matching {
return TestResult::Maybe;
}
TestResult::NotMatched
}