Macro safe_arch::string_search_for_index
source · macro_rules! string_search_for_index { ([$needle:expr, $needle_len:expr], [$haystack:expr, $haystack_len:expr], $char_type:tt, $search_op:tt, $index_end:tt) => { ... }; ($needle:expr, $haystack:expr, $char_type:tt, $search_op:tt, $index_end:tt) => { ... }; (@_char_type u8) => { ... }; (@_char_type u16) => { ... }; (@_char_type i8) => { ... }; (@_char_type i16) => { ... }; (@_char_type $unknown:tt) => { ... }; (@_search_op EqAny) => { ... }; (@_search_op CmpRanges) => { ... }; (@_search_op CmpEqEach) => { ... }; (@_search_op CmpEqOrdered) => { ... }; (@_search_op $unknown:tt) => { ... }; (@_index_end FirstMatch) => { ... }; (@_index_end LastMatch) => { ... }; (@_index_end $unknown:tt) => { ... }; (@_raw_explicit_len $needle:expr, $needle_len:expr, $haystack:expr, $haystack_len:expr, $imm:expr) => { ... }; (@_raw_implicit_len $needle:expr, $haystack:expr, $imm:expr) => { ... }; }
Expand description
Looks for $needle
in $haystack
and gives the index of the either the
first or last match.
This is a fairly flexible operation, and so I apologize in advance.
- The “needle” is the string you’re looking for.
- The “haystack” is the string you’re looking inside of.
- The lengths of each string can be “explicit” or “implicit”.
- “explicit” is specified with
[str, len]
pairs. - “implicit” just ends at the first
\0
. - Either way a string doesn’t go past the end of the register.
- “explicit” is specified with
- You need to pick a “char type”, which can be any of
u8
,i8
,u16
,i16
. These operations always operate onm128i
registers, but the interpretation of the data is configurable. - You need to pick the search operation, which determines how the
needle
is compared to thehaystack
:EqAny
: Matches when any haystack character equals any needle character, regardless of position.CmpRanges
: Interprets consecutive pairs of characters in the needle as(low..=high)
ranges to compare each haystack character to.CmpEqEach
: Matches when a character position in the needle is equal to the character at the same position in the haystack.CmpEqOrdered
: Matches when the complete needle string is a substring somewhere in the haystack.
- Finally, you need to specify if you’re looking for the
FirstMatch
orLastMatch
.- If no match is found the output will be the length of the haystack.
It’s a lot to take in. Hopefully the examples below can help clarify how
things work. They all use u8
since Rust string literals are UTF-8, but
it’s the same with the other character types.
EqAny
let hay: m128i = m128i::from(*b"some test words.");
// explicit needle length
let needle: m128i = m128i::from(*b"e_______________");
let i: ::core::primitive::i32 =
string_search_for_index!([needle, 1], [hay, 16], u8, EqAny, FirstMatch);
assert_eq!(i, 3);
let i: ::core::primitive::i32 =
string_search_for_index!([needle, 1], [hay, 16], u8, EqAny, LastMatch);
assert_eq!(i, 6);
// implicit needle length
let needle: m128i = m128i::from(*b"e\0______________");
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, EqAny, FirstMatch);
assert_eq!(i, 3);
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, EqAny, LastMatch);
assert_eq!(i, 6);
// more than one needle character will match any of them, though we
// don't get info about _which_ needle character matched.
let needle: m128i = m128i::from(*b"et\0_____________");
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, EqAny, FirstMatch);
assert_eq!(i, 3);
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, EqAny, LastMatch);
assert_eq!(i, 8);
CmpRanges
let hay: m128i = m128i::from(*b"some test words.");
let needle: m128i = m128i::from(*b"vz\0_____________");
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, CmpRanges, FirstMatch);
assert_eq!(i, 10); // matches the 'w'
CmpEqEach
let hay: m128i = m128i::from(*b"some test words.");
let needle: m128i = m128i::from(*b"_____test_______");
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, CmpEqEach, FirstMatch);
assert_eq!(i, 5); // start of "test"
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, CmpEqEach, LastMatch);
assert_eq!(i, 8); // end of "test"
CmpEqOrdered
let hay: m128i = m128i::from(*b"some test words.");
let needle: m128i = m128i::from(*b"words\0__________");
let i: ::core::primitive::i32 =
string_search_for_index!(needle, hay, u8, CmpEqOrdered, FirstMatch);
assert_eq!(i, 10); // This is where the "words" substring begins