| ... | @@ -1107,7 +1107,9 @@ pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?us | ... | @@ -1107,7 +1107,9 @@ pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?us |
| 1107 | | 1107 | |
| 1108 | var i: usize = haystack_bytes.len - needle_bytes.len; | 1108 | var i: usize = haystack_bytes.len - needle_bytes.len; |
| 1109 | while (true) { | 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 | const skip = skip_table[haystack_bytes[i]]; | 1113 | const skip = skip_table[haystack_bytes[i]]; |
| 1112 | if (skip > i) break; | 1114 | if (skip > i) break; |
| 1113 | i -= skip; | 1115 | i -= skip; |
| ... | @@ -1132,7 +1134,9 @@ pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, nee | ... | @@ -1132,7 +1134,9 @@ pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, nee |
| 1132 | | 1134 | |
| 1133 | var i: usize = start_index * @sizeOf(T); | 1135 | var i: usize = start_index * @sizeOf(T); |
| 1134 | while (i <= haystack_bytes.len - needle_bytes.len) { | 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 | i += skip_table[haystack_bytes[i + needle_bytes.len - 1]]; | 1140 | i += skip_table[haystack_bytes[i + needle_bytes.len - 1]]; |
| 1137 | } | 1141 | } |
| 1138 | | 1142 | |
| ... | @@ -1164,6 +1168,34 @@ test "mem.indexOf" { | ... | @@ -1164,6 +1168,34 @@ test "mem.indexOf" { |
| 1164 | try testing.expect(lastIndexOfScalar(u8, "boo", 'o').? == 2); | 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 | /// Returns the number of needles inside the haystack | 1199 | /// Returns the number of needles inside the haystack |
| 1168 | /// needle.len must be > 0 | 1200 | /// needle.len must be > 0 |
| 1169 | /// does not count overlapping needles | 1201 | /// does not count overlapping needles |