22 HEADER_SIZE ,
33 MAX_LENGTH ,
44 EMPTY ,
5+ clamp ,
56 allocate ,
67 isWhiteSpaceOrLineTerminator ,
78 CharCode ,
@@ -97,7 +98,7 @@ export class String {
9798 endsWith ( searchString : String , endPosition : i32 = MAX_LENGTH ) : bool {
9899 assert ( this !== null ) ;
99100 if ( searchString === null ) return false ;
100- var end : isize = < isize > min ( max ( endPosition , 0 ) , this . length ) ;
101+ var end = clamp < isize > ( endPosition , 0 , this . length ) ;
101102 var searchLength : isize = searchString . length ;
102103 var start : isize = end - searchLength ;
103104 if ( start < 0 ) return false ;
@@ -206,21 +207,44 @@ export class String {
206207 return this . indexOf ( searchString , position ) != - 1 ;
207208 }
208209
209- indexOf ( searchString : String , position : i32 = 0 ) : i32 {
210+ indexOf ( searchString : String , fromIndex : i32 = 0 ) : i32 {
211+ assert ( this !== null ) ;
212+ if ( searchString === null ) searchString = changetype < String > ( "null" ) ;
213+ var searchLen : isize = searchString . length ;
214+ if ( ! searchLen ) return 0 ;
215+ var len : isize = this . length ;
216+ if ( ! len ) return - 1 ;
217+ var start = clamp < isize > ( fromIndex , 0 , len ) ;
218+ len -= searchLen ;
219+ // TODO: multiple char codes
220+ for ( let k : isize = start ; k <= len ; ++ k ) {
221+ if ( ! compare_memory (
222+ changetype < usize > ( this ) + HEADER_SIZE + ( k << 1 ) ,
223+ changetype < usize > ( searchString ) + HEADER_SIZE ,
224+ searchLen << 1
225+ ) ) {
226+ return < i32 > k ;
227+ }
228+ }
229+ return - 1 ;
230+ }
231+
232+ lastIndexOf ( searchString : String , fromIndex : i32 = 0 ) : i32 {
210233 assert ( this !== null ) ;
211234 if ( searchString === null ) searchString = changetype < String > ( "null" ) ;
212- var pos : isize = position ;
213235 var len : isize = this . length ;
214- var start : isize = min < isize > ( max < isize > ( pos , 0 ) , len ) ;
215- var searchLen : isize = < isize > searchString . length ;
236+ var searchLen : isize = searchString . length ;
237+ if ( ! searchLen ) return len ;
238+ if ( ! len ) return - 1 ;
239+ var start = clamp < isize > ( fromIndex - searchLen , 0 , len ) ;
216240
217- // TODO: two-way, multiple char codes
218- for ( let k : usize = start ; < isize > k + searchLen <= len ; ++ k ) {
241+ // TODO: multiple char codes
242+ for ( let k : isize = len - 1 ; k >= start ; -- k ) {
219243 if ( ! compare_memory (
220244 changetype < usize > ( this ) + HEADER_SIZE + ( k << 1 ) ,
221245 changetype < usize > ( searchString ) + HEADER_SIZE ,
222- searchLen << 1 )
223- ) {
246+ searchLen << 1
247+ ) ) {
224248 return < i32 > k ;
225249 }
226250 }
@@ -233,8 +257,8 @@ export class String {
233257
234258 var pos : isize = position ;
235259 var len : isize = this . length ;
236- var start : isize = min < isize > ( max < isize > ( pos , 0 ) , len ) ;
237- var searchLength : isize = < isize > searchString . length ;
260+ var start = clamp < isize > ( pos , 0 , len ) ;
261+ var searchLength : isize = searchString . length ;
238262 if ( searchLength + start > len ) {
239263 return false ;
240264 }
@@ -253,7 +277,7 @@ export class String {
253277 if ( intStart < 0 ) {
254278 intStart = max < isize > ( size + intStart , 0 ) ;
255279 }
256- var resultLength : isize = min < isize > ( max < isize > ( end , 0 ) , size - intStart ) ;
280+ var resultLength = clamp < isize > ( end , 0 , size - intStart ) ;
257281 if ( resultLength <= 0 ) {
258282 return EMPTY ;
259283 }
@@ -269,8 +293,8 @@ export class String {
269293 substring ( start : i32 , end : i32 = i32 . MAX_VALUE ) : String {
270294 assert ( this !== null ) ;
271295 var len = this . length ;
272- var finalStart = min < i32 > ( max < i32 > ( start , 0 ) , len ) ;
273- var finalEnd = min < i32 > ( max < i32 > ( end , 0 ) , len ) ;
296+ var finalStart = clamp < isize > ( start , 0 , len ) ;
297+ var finalEnd = clamp < isize > ( end , 0 , len ) ;
274298 var from = min < i32 > ( finalStart , finalEnd ) ;
275299 var to = max < i32 > ( finalStart , finalEnd ) ;
276300 len = to - from ;
0 commit comments