#TUNING by cg
class: FourByteString
added: #replaceFrom:to:with:startingAt:
changed: #from:to:put:
--- 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$'
! !