# HG changeset patch # User Claus Gittinger # Date 1553596574 -3600 # Node ID 2601c14688d856ce0763fd5257c0d42069d5c572 # Parent 868df53eb2f52497030d4fbecd031811a2fb87d7 #TUNING by cg class: TwoByteString added: #from:to:put: diff -r 868df53eb2f5 -r 2601c14688d8 TwoByteString.st --- a/TwoByteString.st Mon Mar 25 16:43:41 2019 +0100 +++ b/TwoByteString.st Tue Mar 26 11:36:14 2019 +0100 @@ -118,6 +118,103 @@ !TwoByteString methodsFor:'filling and replacing'! +from:start to:stop put:aCharacter + "fill part of the receiver with aCharacter. + - reimplemented here for speed" + +%{ /* NOCONTEXT */ + + REGISTER unsigned short *dstp; + REGISTER int count, charValue; + int len, index1, index2; + OBJ cls; + + // fprintf(stderr, "fill16...\n"); + if (__isCharacter(aCharacter) + && __bothSmallInteger(start, stop)) { + len = __twoByteStringSize(self); + index1 = __intVal(start); + index2 = __intVal(stop); + + dstp = __twoByteStringVal(self) + index1 - 1; + if ((cls = __qClass(self)) != @global(Unicode16String)) { + int nInst; + + nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); + dstp += nInst; + len -= nInst; + } + + charValue = __intVal(__characterVal(aCharacter)); + if (((unsigned)charValue <= 0xFFFF) + && (index1 <= index2) + && (index1 > 0)) { + if (index2 <= len) { + count = index2 - index1 + 1; + +#if (__POINTER_SIZE__ == 8) + { + INT v4; + + v4 = (charValue << 16) | charValue; + v4 = (v4 << 32) | v4; + + /* fill unaligned part */ + while ((count > 0) && (((unsigned INT)dstp & 7) != 0)) { + *dstp++ = charValue; + count--; + } + + /* fill aligned part */ + while (count >= 4) { + ((unsigned INT *)dstp)[0] = v4; + dstp += 4; + count -= 4; + } + + /* fill rest */ + while (count > 0) { + *dstp++ = charValue; + count--; + } + RETURN (self); + } +#endif /* 64bit */ + + while (count >= 8) { + dstp[0] = dstp[1] = dstp[2] = dstp[3] = + dstp[4] = dstp[5] = dstp[6] = dstp[7] = charValue; + dstp += 8; + count -= 8; + } + while (count--) { + *dstp++ = charValue; + } + RETURN (self); + } + } + } +%}. + " + fall back in case of non-integer index or out-of-bound index/value; + will eventually lead to an out-of-bound signal raise + " + ^ super from:start to:stop put:aCharacter + + " + (Unicode16String new:10) from:1 to:10 put:$a + (Unicode16String new:20) from:10 to:20 put:$b + (Unicode16String new:20) from:1 to:10 put:$c + (Unicode16String new:20) from:1 to:10 put:$c + (Unicode16String new:100) from:2 to:99 put:$c + + (Unicode16String new:10) from:0 to:9 put:$a + (Unicode16String new:10) from:1 to:11 put:$a + " + + "Created: / 26-03-2019 / 11:20:14 / Claus Gittinger" +! + replaceFrom:start to:stop with:aString startingAt:repStart "replace the characters starting at index start, anInteger and ending at stop, anInteger with characters from aString starting at repStart.