@@ -17,7 +17,7 @@ export const EMPTY = changetype<String>(""); // TODO: is this a bad idea with '=
1717
1818@inline
1919export function clamp < T > ( val : T , lo : T , hi : T ) : T {
20- return max < T > ( min < T > ( val , hi ) , lo ) ;
20+ return min < T > ( max < T > ( val , lo ) , hi ) ;
2121}
2222
2323/** Allocates a raw String with uninitialized contents. */
@@ -28,6 +28,15 @@ export function allocate(length: i32): String {
2828 return changetype < String > ( buffer ) ;
2929}
3030
31+ @inline
32+ export function copyUnsafe ( dest : String , destOffset : usize , src : String , srcOffset : usize , len : usize ) : void {
33+ memory . copy (
34+ changetype < usize > ( dest ) + ( destOffset << 1 ) + HEADER_SIZE ,
35+ changetype < usize > ( src ) + ( srcOffset << 1 ) + HEADER_SIZE ,
36+ len << 1
37+ ) ;
38+ }
39+
3140export function isWhiteSpaceOrLineTerminator ( c : u16 ) : bool {
3241 switch ( c ) {
3342 case 10 : // <LF>
@@ -76,24 +85,19 @@ export const enum CharCode {
7685
7786export function parse < T > ( str : String , radix : i32 = 0 ) : T {
7887 var len : i32 = str . length ;
79- if ( ! len ) {
80- return < T > NaN ;
81- }
88+ if ( ! len ) return < T > NaN ;
89+
8290 var ptr = changetype < usize > ( str ) /* + HEAD -> offset */ ;
8391 var code = < i32 > load < u16 > ( ptr , HEADER_SIZE ) ;
8492
8593 // determine sign
8694 var sign : T ;
8795 if ( code == CharCode . MINUS ) {
88- if ( ! -- len ) {
89- return < T > NaN ;
90- }
96+ if ( ! -- len ) return < T > NaN ;
9197 code = < i32 > load < u16 > ( ptr += 2 , HEADER_SIZE ) ;
9298 sign = - 1 ;
9399 } else if ( code == CharCode . PLUS ) {
94- if ( ! -- len ) {
95- return < T > NaN ;
96- }
100+ if ( ! -- len ) return < T > NaN ;
97101 code = < i32 > load < u16 > ( ptr += 2 , HEADER_SIZE ) ;
98102 sign = 1 ;
99103 } else {
@@ -122,9 +126,7 @@ export function parse<T>(str: String, radix: i32 = 0): T {
122126 radix = 16 ;
123127 break ;
124128 }
125- default : {
126- radix = 10 ;
127- }
129+ default : radix = 10 ;
128130 }
129131 } else radix = 10 ;
130132 } else if ( radix < 2 || radix > 36 ) {
@@ -141,22 +143,79 @@ export function parse<T>(str: String, radix: i32 = 0): T {
141143 code -= CharCode . A - 10 ;
142144 } else if ( code >= CharCode . a && code <= CharCode . z ) {
143145 code -= CharCode . a - 10 ;
144- } else {
145- break ;
146- }
147- if ( code >= radix ) {
148- break ;
149- }
146+ } else break ;
147+ if ( code >= radix ) break ;
150148 num = ( num * radix ) + code ;
151149 ptr += 2 ;
152150 }
153151 return sign * num ;
154152}
155153
156- export function compareUTF16 ( ptr1 : usize , ptr2 : usize , len : usize ) : i32 {
154+ export function compareUnsafe ( str1 : String , offset1 : usize , str2 : String , offset2 : usize , len : usize ) : i32 {
157155 var cmp : i32 = 0 ;
156+ var ptr1 = changetype < usize > ( str1 ) + ( offset1 << 1 ) ;
157+ var ptr2 = changetype < usize > ( str2 ) + ( offset2 << 1 ) ;
158158 while ( len && ! ( cmp = < i32 > load < u16 > ( ptr1 , HEADER_SIZE ) - < i32 > load < u16 > ( ptr2 , HEADER_SIZE ) ) ) {
159159 -- len , ++ ptr1 , ++ ptr2 ;
160160 }
161161 return cmp ;
162162}
163+
164+ export function repeatUnsafe ( dest : String , destOffset : usize , src : String , count : i32 ) : void {
165+ var length = src . length ;
166+ if ( ASC_SHRINK_LEVEL > 1 ) {
167+ let strLen = length << 1 ;
168+ let to = changetype < usize > ( dest ) + HEADER_SIZE + ( destOffset << 1 ) ;
169+ let from = changetype < usize > ( src ) + HEADER_SIZE ;
170+ for ( let i = 0 , len = strLen * count ; i < len ; i += strLen ) {
171+ memory . copy ( to + i , from , strLen ) ;
172+ }
173+ } else {
174+ switch ( length ) {
175+ case 0 : break ;
176+ case 1 : {
177+ let cc = load < u16 > ( changetype < usize > ( src ) , HEADER_SIZE ) ;
178+ let out = changetype < usize > ( dest ) + ( destOffset << 1 ) ;
179+ for ( let i = 0 ; i < count ; ++ i ) {
180+ store < u16 > ( out + ( i << 1 ) , cc , HEADER_SIZE ) ;
181+ }
182+ break ;
183+ }
184+ case 2 : {
185+ let cc = load < u32 > ( changetype < usize > ( src ) , HEADER_SIZE ) ;
186+ let out = changetype < usize > ( dest ) + ( destOffset << 1 ) ;
187+ for ( let i = 0 ; i < count ; ++ i ) {
188+ store < u32 > ( out + ( i << 2 ) , cc , HEADER_SIZE ) ;
189+ }
190+ break ;
191+ }
192+ case 3 : {
193+ let cc1 = load < u32 > ( changetype < usize > ( src ) , HEADER_SIZE + 0 ) ;
194+ let cc2 = load < u16 > ( changetype < usize > ( src ) , HEADER_SIZE + 4 ) ;
195+ let out = changetype < usize > ( dest ) + ( destOffset << 1 ) ;
196+ for ( let i = 0 ; i < count ; ++ i ) {
197+ store < u32 > ( out + ( i << 2 ) , cc1 , HEADER_SIZE + 0 ) ;
198+ store < u16 > ( out + ( i << 1 ) , cc2 , HEADER_SIZE + 4 ) ;
199+ }
200+ break ;
201+ }
202+ case 4 : {
203+ let cc = load < u64 > ( changetype < usize > ( src ) , HEADER_SIZE ) ;
204+ let out = changetype < usize > ( dest ) + ( destOffset << 1 ) ;
205+ for ( let i = 0 ; i < count ; ++ i ) {
206+ store < u64 > ( out + ( i << 3 ) , cc , HEADER_SIZE ) ;
207+ }
208+ break ;
209+ }
210+ default : {
211+ let strLen = length << 1 ;
212+ let to = changetype < usize > ( dest ) + HEADER_SIZE + ( destOffset << 1 ) ;
213+ let from = changetype < usize > ( src ) + HEADER_SIZE ;
214+ for ( let i = 0 , len = strLen * count ; i < len ; i += strLen ) {
215+ memory . copy ( to + i , from , strLen ) ;
216+ }
217+ break ;
218+ }
219+ }
220+ }
221+ }
0 commit comments