#TUNING by cg
authorClaus Gittinger <cg@exept.de>
Tue, 26 Mar 2019 12:12:05 +0100
changeset 4922 ff7afd151379
parent 4921 e5f2b1b5a28d
child 4923 6e6fea06fff6
#TUNING by cg class: FourByteString added: #replaceFrom:to:with:startingAt: changed: #from:to:put:
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$'
 ! !