use ppatch::prelude::*; use ppatch::PatternSearchType; use std::io::Write; use std::str::FromStr; // Returns index of first mismatch or len of smaller slice fn slice_equality(one: &[u8], other: &[u8]) -> usize { let mut index = 0; for pair in one.iter().zip(other.iter()) { if pair.0 != pair.1 { return index; } index += 1; } index } const INPUT: [u8; 168] = [ 0x50, 0xF0, 0x01, 0x00, 0xDF, 0xF8, 0x1C, 0x1C, 0x08, 0x70, 0x66, 0x48, 0x00, 0x78, 0x40, 0x1C, 0x64, 0x49, 0x08, 0x70, 0x47, 0x48, 0x00, 0x68, 0xDF, 0xF8, 0x0C, 0x1C, 0x08, 0x42, 0x17, 0xD1, 0x45, 0x48, 0x00, 0x78, 0x00, 0x28, 0x04, 0xD1, 0x00, 0x21, 0x08, 0x20, 0x00, 0xF0, 0xA6, 0xFF, 0x0E, 0xE0, 0x41, 0x48, 0x00, 0x78, 0x01, 0x28, 0x0A, 0xD1, 0x00, 0x21, 0x14, 0x20, 0x00, 0xF0, 0x9D, 0xFF, 0xDF, 0xF8, 0xE8, 0x0B, 0x00, 0x88, 0x40, 0x1C, 0xDF, 0xF8, 0xE0, 0x1B, 0x08, 0x80, 0xDF, 0xF8, 0xDC, 0x0B, 0x00, 0x88, 0x40, 0x1C, 0xDF, 0xF8, 0xD4, 0x1B, 0x08, 0x80, 0x45, 0xE0, 0xDF, 0xF8, 0xB8, 0x0B, 0x00, 0x88, 0xB0, 0xF5, 0x50, 0x4F, 0x05, 0xD0, 0xDF, 0xF8, 0xAC, 0x0B, 0x00, 0x88, 0xB0, 0xF5, 0x30, 0x5F, 0x39, 0xD1, 0xDF, 0xF8, 0xA4, 0x0B, 0x00, 0x78, 0x00, 0x28, 0x34, 0xD1, 0x47, 0x48, 0xFF, 0x21, 0x01, 0x70, 0xDF, 0xF8, 0x98, 0x0B, 0x00, 0x78, 0x50, 0xF0, 0x01, 0x00, 0xDF, 0xF8, 0x90, 0x1B, 0x08, 0x70, 0x42, 0x48, 0x00, 0x78, 0x40, 0x1E, 0x41, 0x49, 0x08, 0x70, 0x24, 0x48, 0x00, 0x68, 0xDF, 0xF8, ]; const RESULT: [u8; 168] = [ 0x50, 0xF0, 0x01, 0x00, 0xDF, 0xF8, 0x1C, 0x1C, 0x08, 0x70, 0x66, 0x48, 0x00, 0x78, 0x80, 0x1C, 0x64, 0x49, 0x08, 0x70, 0x47, 0x48, 0x00, 0x68, 0xDF, 0xF8, 0x0C, 0x1C, 0x08, 0x42, 0x17, 0xD1, 0x45, 0x48, 0x00, 0x78, 0x00, 0x28, 0x04, 0xD1, 0x00, 0x21, 0x08, 0x20, 0x00, 0xF0, 0xA6, 0xFF, 0x0E, 0xE0, 0x41, 0x48, 0x00, 0x78, 0x01, 0x28, 0x0A, 0xD1, 0x00, 0x21, 0x14, 0x20, 0x00, 0xF0, 0x9D, 0xFF, 0xDF, 0xF8, 0xE8, 0x0B, 0x00, 0x88, 0x40, 0x1C, 0xDF, 0xF8, 0xE0, 0x1B, 0x08, 0x80, 0xDF, 0xF8, 0xDC, 0x0B, 0x00, 0x88, 0x40, 0x1C, 0xDF, 0xF8, 0xD4, 0x1B, 0x08, 0x80, 0x45, 0xE0, 0xDF, 0xF8, 0xB8, 0x0B, 0x00, 0x88, 0xB0, 0xF5, 0x50, 0x4F, 0x05, 0xD0, 0xDF, 0xF8, 0xAC, 0x0B, 0x00, 0x88, 0xB0, 0xF5, 0x30, 0x5F, 0x39, 0xD1, 0xDF, 0xF8, 0xA4, 0x0B, 0x00, 0x78, 0x00, 0x28, 0x34, 0xD1, 0x47, 0x48, 0xFF, 0x21, 0x01, 0x70, 0xDF, 0xF8, 0x98, 0x0B, 0x00, 0x78, 0x50, 0xF0, 0x01, 0x00, 0xDF, 0xF8, 0x90, 0x1B, 0x08, 0x70, 0x42, 0x48, 0x00, 0x78, 0x80, 0x1E, 0x41, 0x49, 0x08, 0x70, 0x24, 0x48, 0x00, 0x68, 0xDF, 0xF8, ]; const SEARCH_STRING: &str = "0x08 0x70 0x?? 0x48 0x00 0x78 0x40 0x?? 0x?? 0x49 0x08 0x70 0x?? 0x48 0x00 0x68"; const REPLACE_STRING: &str = "0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x80"; #[test] fn test_multi() { let search = ppatch::Pattern::from_str(SEARCH_STRING).unwrap(); let replace = ppatch::Pattern::from_str(REPLACE_STRING).unwrap(); let mut writer = Vec::new(); for item in INPUT .into_iter() .search_pattern(&search) // pattern_search_ref_iterator .inspect(|result| match result { PatternSearchType::Match { ref data, index } => { let input_slice = &INPUT[*index..(index + search.len())]; assert_eq!(data.len(), input_slice.len()); assert_eq!(slice_equality(&data, input_slice), data.len()); } PatternSearchType::NonMatch(_) => {} }) .replace_pattern(&replace) // pattern_replace_iterator .inspect(|result| match result { Ok(_) => {} Err(error) => assert!(false, "{}", error), }) .search_pattern(&search) // pattern_search_result_iterator .inspect(|result| match result { Ok(search_type) => { if let PatternSearchType::Match { data, index } = search_type { assert!( false, "There should be no match on second round: {:#X} {:X?}", index, data ); } } Err(error) => assert!(false, "{}", error), }) .replace_pattern(&replace) // pattern_replace_result_iterator { match item { Err(error) => { assert!(false, "{}", error); } Ok(value) => { let _ = writer.write_all(&[value]); } } } assert_eq!(writer.len(), RESULT.len()); assert_eq!(slice_equality(&writer, &RESULT), RESULT.len()); }