--- 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.