| 892 | } |
| 893 | |
| 894 | fn search_info_literal<const LITERAL: bool, S: StrDrive>( |
| 895 | req: &mut Request<'_, S>, |
| 896 | state: &mut State, |
| 897 | mut ctx: MatchContext, |
| 898 | ) -> bool { |
| 899 | /* pattern starts with a known prefix */ |
| 900 | /* <length> <skip> <prefix data> <overlap data> */ |
| 901 | let len = ctx.peek_code(req, 5) as usize; |
| 902 | let skip = ctx.peek_code(req, 6) as usize; |
| 903 | let prefix = &ctx.pattern(req)[7..7 + len]; |
| 904 | let overlap = &ctx.pattern(req)[7 + len - 1..7 + len * 2]; |
| 905 | |
| 906 | // code_position ready for tail match |
| 907 | ctx.skip_code_from(req, 1); |
| 908 | ctx.skip_code(2 * skip); |
| 909 | |
| 910 | req.must_advance = false; |
| 911 | |
| 912 | if len == 1 { |
| 913 | // pattern starts with a literal character |
| 914 | let c = prefix[0]; |
| 915 | |
| 916 | while !ctx.at_end(req) { |
| 917 | // find the next matched literal |
| 918 | while ctx.peek_char::<S>() != c { |
| 919 | ctx.advance_char::<S>(); |
| 920 | if ctx.at_end(req) { |
| 921 | return false; |
| 922 | } |
| 923 | } |
| 924 | |
| 925 | req.start = ctx.cursor.position; |
| 926 | state.start = req.start; |
| 927 | state.cursor = ctx.cursor; |
| 928 | S::skip(&mut state.cursor, skip); |
| 929 | |
| 930 | // literal only |
| 931 | if LITERAL { |
| 932 | return true; |
| 933 | } |
| 934 | |
| 935 | let mut next_ctx = ctx; |
| 936 | next_ctx.skip_char::<S>(skip); |
| 937 | |
| 938 | if _match(req, state, next_ctx) { |
| 939 | return true; |
| 940 | } |
| 941 | |
| 942 | ctx.advance_char::<S>(); |
| 943 | state.marks.clear(); |
| 944 | } |
| 945 | } else { |
| 946 | while !ctx.at_end(req) { |
| 947 | let c = prefix[0]; |
| 948 | while ctx.peek_char::<S>() != c { |
| 949 | ctx.advance_char::<S>(); |
| 950 | if ctx.at_end(req) { |
| 951 | return false; |