Add String#lastIndexOf and improve tests (#163)

This commit is contained in:
Max Graey
2018-07-10 04:31:51 +03:00
committed by Daniel Wirtz
parent c4199673ef
commit 365884ff73
11 changed files with 2112 additions and 1172 deletions

View File

@ -2,6 +2,7 @@ import {
HEADER_SIZE,
MAX_LENGTH,
EMPTY,
clamp,
allocate,
isWhiteSpaceOrLineTerminator,
CharCode,
@ -97,7 +98,7 @@ export class String {
endsWith(searchString: String, endPosition: i32 = MAX_LENGTH): bool {
assert(this !== null);
if (searchString === null) return false;
var end: isize = <isize>min(max(endPosition, 0), this.length);
var end = clamp<isize>(endPosition, 0, this.length);
var searchLength: isize = searchString.length;
var start: isize = end - searchLength;
if (start < 0) return false;
@ -206,21 +207,44 @@ export class String {
return this.indexOf(searchString, position) != -1;
}
indexOf(searchString: String, position: i32 = 0): i32 {
indexOf(searchString: String, fromIndex: i32 = 0): i32 {
assert(this !== null);
if (searchString === null) searchString = changetype<String>("null");
var pos: isize = position;
var searchLen: isize = searchString.length;
if (!searchLen) return 0;
var len: isize = this.length;
var start: isize = min<isize>(max<isize>(pos, 0), len);
var searchLen: isize = <isize>searchString.length;
// TODO: two-way, multiple char codes
for (let k: usize = start; <isize>k + searchLen <= len; ++k) {
if (!len) return -1;
var start = clamp<isize>(fromIndex, 0, len);
len -= searchLen;
// TODO: multiple char codes
for (let k: isize = start; k <= len; ++k) {
if (!compare_memory(
changetype<usize>(this) + HEADER_SIZE + (k << 1),
changetype<usize>(searchString) + HEADER_SIZE,
searchLen << 1)
) {
searchLen << 1
)) {
return <i32>k;
}
}
return -1;
}
lastIndexOf(searchString: String, fromIndex: i32 = 0): i32 {
assert(this !== null);
if (searchString === null) searchString = changetype<String>("null");
var len: isize = this.length;
var searchLen: isize = searchString.length;
if (!searchLen) return len;
if (!len) return -1;
var start = clamp<isize>(fromIndex - searchLen, 0, len);
// TODO: multiple char codes
for (let k: isize = len - 1; k >= start; --k) {
if (!compare_memory(
changetype<usize>(this) + HEADER_SIZE + (k << 1),
changetype<usize>(searchString) + HEADER_SIZE,
searchLen << 1
)) {
return <i32>k;
}
}
@ -233,8 +257,8 @@ export class String {
var pos: isize = position;
var len: isize = this.length;
var start: isize = min<isize>(max<isize>(pos, 0), len);
var searchLength: isize = <isize>searchString.length;
var start = clamp<isize>(pos, 0, len);
var searchLength: isize = searchString.length;
if (searchLength + start > len) {
return false;
}
@ -253,7 +277,7 @@ export class String {
if (intStart < 0) {
intStart = max<isize>(size + intStart, 0);
}
var resultLength: isize = min<isize>(max<isize>(end, 0), size - intStart);
var resultLength = clamp<isize>(end, 0, size - intStart);
if (resultLength <= 0) {
return EMPTY;
}
@ -269,8 +293,8 @@ export class String {
substring(start: i32, end: i32 = i32.MAX_VALUE): String {
assert(this !== null);
var len = this.length;
var finalStart = min<i32>(max<i32>(start, 0), len);
var finalEnd = min<i32>(max<i32>(end, 0), len);
var finalStart = clamp<isize>(start, 0, len);
var finalEnd = clamp<isize>(end, 0, len);
var from = min<i32>(finalStart, finalEnd);
var to = max<i32>(finalStart, finalEnd);
len = to - from;