TwoByteString.st
changeset 16750 394404a33691
parent 14557 427740fc4329
child 17621 098adea6b2d4
--- a/TwoByteString.st	Thu Jul 10 14:24:42 2014 +0200
+++ b/TwoByteString.st	Thu Jul 10 14:28:32 2014 +0200
@@ -103,6 +103,94 @@
     ^ super basicAt:index.
 ! !
 
+!TwoByteString methodsFor:'filling and replacing'!
+
+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)) {
+        REGISTER int count;
+        int len, index1, index2;
+
+        index1 = __intVal(start);
+        index2 = __intVal(stop);
+        count = index2 - index1 + 1;
+        if (count <= 0) {
+             RETURN (self);
+        }
+        len = __twoByteStringSize(self);
+        if ((index2 <= len) && (index1 > 0)) {
+            int repLen, repIndex;
+
+            repIndex = __intVal(repStart);
+
+            if (__isStringLike(aString)) {
+                repLen = __stringSize(aString);
+                if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) {
+                    REGISTER unsigned char *srcp;
+                    REGISTER unsigned short *dstp;
+
+                    srcp = __stringVal(aString) + repIndex - 1;
+                    dstp = __twoByteStringVal(self) + index1 - 1;
+                    while (count-- > 0) {
+                        *dstp++ = *srcp++;
+                    }
+                    RETURN (self);
+                }
+            } else  if (__isTwoByteString(aString) || __isUnicode16String(aString)) {
+                repLen = __twoByteStringSize(aString);
+                if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) {
+                    REGISTER unsigned short *srcp;
+                    REGISTER unsigned short *dstp;
+
+                    srcp = __twoByteStringVal(aString) + repIndex - 1;
+                    dstp = __twoByteStringVal(self) + index1 - 1;
+                    if (aString == self) {
+                        /* take care of overlapping copy */
+                        if (srcp < dstp) {
+                            /* must do a reverse copy */
+                            srcp += count;
+                            dstp += count;
+                            while (count-- > 0) {
+                                *--dstp = *--srcp;
+                            }
+                            RETURN (self);
+                        }
+                    }
+                    if (count > 5) {
+                        memcpy(dstp, srcp, count*sizeof(short));
+                    } 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' asUnicode16String replaceFrom:1 to:5 with:'123456' startingAt:2
+     'hello world' asUnicode16String replaceFrom:1 to:5 with:'123456' asUnicode16String startingAt:2
+     'hello world' asUnicode16String replaceFrom:1 to:0 with:'123456' startingAt:2
+     'hello' asUnicode16String replaceFrom:1 to:6 with:'123456' startingAt:2
+     'hello world' asUnicode16String replaceFrom:1 to:1 with:'123456' startingAt:2
+    "
+! !
+
 !TwoByteString methodsFor:'queries'!
 
 bitsPerCharacter
@@ -121,7 +209,8 @@
 !TwoByteString class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/TwoByteString.st,v 1.34 2012-12-12 22:56:13 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/TwoByteString.st,v 1.35 2014-07-10 12:28:32 cg Exp $'
 ! !
 
+
 TwoByteString initialize!