# HG changeset patch # User Claus Gittinger # Date 1553598725 -3600 # Node ID ff7afd15137915134ab6a27f3faa27809e436888 # Parent e5f2b1b5a28dcb9b1e24fcf557fd544783ec6de7 #TUNING by cg class: FourByteString added: #replaceFrom:to:with:startingAt: changed: #from:to:put: diff -r e5f2b1b5a28d -r ff7afd151379 FourByteString.st --- a/FourByteString.st Tue Mar 26 11:54:02 2019 +0100 +++ b/FourByteString.st Tue Mar 26 12:12:05 2019 +0100 @@ -140,58 +140,55 @@ charValue = __intVal(__characterVal(aCharacter)); if (((unsigned)charValue <= 0x0FFFFFFF) && (index1 <= index2) - && (index1 > 0)) { - if (index2 <= len) { - count = index2 - index1 + 1; + && (index1 > 0) + && (index2 <= len)) { + count = index2 - index1 + 1; #if (__POINTER_SIZE__ == 8) - { - INT v2; - - v2 = (charValue << 32) | charValue; + { + INT v2; - /* fill unaligned part */ - while ((count > 0) && (((unsigned INT)dstp & 7) != 0)) { - *dstp++ = charValue; - count--; - } + v2 = (charValue << 32) | charValue; - /* fill aligned part */ - while (count >= 8) { - ((unsigned INT *)dstp)[0] = v2; - ((unsigned INT *)dstp)[1] = v2; - ((unsigned INT *)dstp)[2] = v2; - ((unsigned INT *)dstp)[3] = v2; - dstp += 8; - count -= 8; - } - /* fill aligned part */ - while (count >= 2) { - ((unsigned INT *)dstp)[0] = v2; - dstp += 2; - count -= 2; - } + /* fill unaligned part */ + while ((count > 0) && (((unsigned INT)dstp & 7) != 0)) { + *dstp++ = charValue; + count--; + } - /* fill rest */ - while (count > 0) { - *dstp++ = charValue; - count--; - } - RETURN (self); - } -#endif /* 64bit */ - + /* fill aligned part */ while (count >= 8) { - dstp[0] = dstp[1] = dstp[2] = dstp[3] = - dstp[4] = dstp[5] = dstp[6] = dstp[7] = charValue; + ((unsigned INT *)dstp)[0] = v2; + ((unsigned INT *)dstp)[1] = v2; + ((unsigned INT *)dstp)[2] = v2; + ((unsigned INT *)dstp)[3] = v2; dstp += 8; count -= 8; } - while (count--) { + while (count >= 2) { + ((unsigned INT *)dstp)[0] = v2; + dstp += 2; + count -= 2; + } + + /* fill rest */ + while (count > 0) { *dstp++ = charValue; + count--; } - RETURN (self); } +#else // not 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; + } +#endif /* 64bit */ + RETURN (self); } } %}. @@ -213,6 +210,92 @@ " "Created: / 26-03-2019 / 11:30:51 / 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. + Return the receiver. + + - reimplemented here for speed" + +%{ /* NOCONTEXT */ + +#ifndef NO_PRIM_STRING + if (__bothSmallInteger(start, stop)) { + int len; + int index1 = __intVal(start); + int index2 = __intVal(stop); + int count = index2 - index1 + 1; + + if (count <= 0) { + RETURN (self); + } + len = __unicode32StringSize(self); + if ((index2 <= len) && (index1 > 0)) { + int repIndex = __intVal(repStart); + + if (__isStringLike(aString)) { + int repLen = __stringSize(aString); + if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) { + REGISTER unsigned char *srcp = __stringVal(aString) + repIndex - 1; + REGISTER unsigned int *dstp = __unicode32StringVal(self) + index1 - 1; + + while (count-- > 0) { + *dstp++ = *srcp++; + } + RETURN (self); + } + } else if (__isTwoByteString(aString) || __isUnicode16String(aString)) { + int repLen = __twoByteStringSize(aString); + if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) { + REGISTER unsigned short *srcp = __twoByteStringVal(aString) + repIndex - 1; + REGISTER unsigned int *dstp = __unicode32StringVal(self) + index1 - 1; + + while (count-- > 0) { + *dstp++ = *srcp++; + } + RETURN (self); + } + } else if (__isUnicode32String(aString)) { + int repLen = __unicode32StringSize(aString); + if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) { + REGISTER unsigned int *srcp = __unicode32StringVal(aString) + repIndex - 1; + REGISTER unsigned int *dstp = __unicode32StringVal(self) + index1 - 1; + + if (aString == self) { + /* take care of overlapping copy */ + memmove(dstp, srcp, count*sizeof(int)); + RETURN (self); + } + if (count > 5) { + memcpy(dstp, srcp, count*sizeof(int)); + } else { + while (count-- > 0) { + *dstp++ = *srcp++; + } + } + RETURN (self); + } + } + } + } +#endif +%}. + "/ arrive here if any index arg is out o range, or the source is neither a string, + "/ nor a two-byte string. + ^ super replaceFrom:start to:stop with:aString startingAt:repStart + + " + 'hello world' asUnicode32String replaceFrom:1 to:5 with:'123456' startingAt:2 + 'hello world' asUnicode32String replaceFrom:1 to:5 with:'123456' asUnicode16String startingAt:2 + 'hello world' asUnicode32String replaceFrom:1 to:5 with:'123456' asUnicode32String startingAt:2 + 'hello world' asUnicode32String replaceFrom:1 to:0 with:'123456' startingAt:2 + 'hello' asUnicode32String replaceFrom:1 to:6 with:'123456' startingAt:2 + 'hello world' asUnicode32String replaceFrom:1 to:1 with:'123456' startingAt:2 + " + + "Created: / 26-03-2019 / 12:10:26 / Claus Gittinger" ! ! !FourByteString methodsFor:'queries'! @@ -255,6 +338,10 @@ version ^ '$Header$' +! + +version_CVS + ^ '$Header$' ! !