| ... | ... | @@ -1107,7 +1107,9 @@ pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?us |
| 1107 | 1107 | |
| 1108 | 1108 | var i: usize = haystack_bytes.len - needle_bytes.len; |
| 1109 | 1109 | while (true) { |
| 1110 | | if (mem.eql(u8, haystack_bytes[i .. i + needle_bytes.len], needle_bytes)) return i; |
| 1110 | if (i % @sizeOf(T) == 0 and mem.eql(u8, haystack_bytes[i .. i + needle_bytes.len], needle_bytes)) { |
| 1111 | return @divExact(i, @sizeOf(T)); |
| 1112 | } |
| 1111 | 1113 | const skip = skip_table[haystack_bytes[i]]; |
| 1112 | 1114 | if (skip > i) break; |
| 1113 | 1115 | i -= skip; |
| ... | ... | @@ -1132,7 +1134,9 @@ pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, nee |
| 1132 | 1134 | |
| 1133 | 1135 | var i: usize = start_index * @sizeOf(T); |
| 1134 | 1136 | while (i <= haystack_bytes.len - needle_bytes.len) { |
| 1135 | | if (mem.eql(u8, haystack_bytes[i .. i + needle_bytes.len], needle_bytes)) return i; |
| 1137 | if (i % @sizeOf(T) == 0 and mem.eql(u8, haystack_bytes[i .. i + needle_bytes.len], needle_bytes)) { |
| 1138 | return @divExact(i, @sizeOf(T)); |
| 1139 | } |
| 1136 | 1140 | i += skip_table[haystack_bytes[i + needle_bytes.len - 1]]; |
| 1137 | 1141 | } |
| 1138 | 1142 | |
| ... | ... | @@ -1164,6 +1168,34 @@ test "mem.indexOf" { |
| 1164 | 1168 | try testing.expect(lastIndexOfScalar(u8, "boo", 'o').? == 2); |
| 1165 | 1169 | } |
| 1166 | 1170 | |
| 1171 | test "mem.indexOf multibyte" { |
| 1172 | { |
| 1173 | // make haystack and needle long enough to trigger boyer-moore-horspool algorithm |
| 1174 | const haystack = [1]u16{0} ** 100 ++ [_]u16 { 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff }; |
| 1175 | const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; |
| 1176 | try testing.expectEqual(indexOfPos(u16, &haystack, 0, &needle), 100); |
| 1177 | |
| 1178 | // check for misaligned false positives (little and big endian) |
| 1179 | const needleLE = [_]u16{ 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff }; |
| 1180 | try testing.expectEqual(indexOfPos(u16, &haystack, 0, &needleLE), null); |
| 1181 | const needleBE = [_]u16{ 0xaacc, 0xbbdd, 0xccee, 0xddff, 0xee00 }; |
| 1182 | try testing.expectEqual(indexOfPos(u16, &haystack, 0, &needleBE), null); |
| 1183 | } |
| 1184 | |
| 1185 | { |
| 1186 | // make haystack and needle long enough to trigger boyer-moore-horspool algorithm |
| 1187 | const haystack = [_]u16 { 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff } ++ [1]u16{0} ** 100; |
| 1188 | const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; |
| 1189 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needle), 0); |
| 1190 | |
| 1191 | // check for misaligned false positives (little and big endian) |
| 1192 | const needleLE = [_]u16{ 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff }; |
| 1193 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needleLE), null); |
| 1194 | const needleBE = [_]u16{ 0xaacc, 0xbbdd, 0xccee, 0xddff, 0xee00 }; |
| 1195 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needleBE), null); |
| 1196 | } |
| 1197 | } |
| 1198 | |
| 1167 | 1199 | /// Returns the number of needles inside the haystack |
| 1168 | 1200 | /// needle.len must be > 0 |
| 1169 | 1201 | /// does not count overlapping needles |