Character.st
changeset 16074 c45e7c47def3
parent 15984 4f74a20b24f7
child 16108 9147e2468e80
--- a/Character.st	Wed Feb 19 14:18:45 2014 +0100
+++ b/Character.st	Wed Feb 19 15:12:30 2014 +0100
@@ -182,98 +182,98 @@
     c1 := aStream next.
     codePoint := c1 codePoint.
     codePoint <= 16r7F ifTrue:[
-        "/ 0xxxxxxx - 7 bits
-        ^ c1.
+	"/ 0xxxxxxx - 7 bits
+	^ c1.
     ].
 
     (codePoint bitAnd:2r11000000) == 2r10000000 ifTrue:[
-        "/ out of sync (got an intermediate character)
-        InvalidEncodingError raiseRequestWith:codePoint errorString:' - out of sync'.
-        ^ c1.
+	"/ out of sync (got an intermediate character)
+	InvalidEncodingError raiseRequestWith:codePoint errorString:' - out of sync'.
+	^ c1.
     ].
 
     fetchNext := [  |ch|
-                    ch := aStream next.
-                    (ch codePoint bitAnd:2r11000000) == 2r10000000 ifFalse:[
-                        "/ followup chars must have 2r10 in high bits
-                        InvalidEncodingError raiseRequestWith:ch codePoint.
-                        ^ c1.
-                    ].
-                    ch
-                 ].
+		    ch := aStream next.
+		    (ch codePoint bitAnd:2r11000000) == 2r10000000 ifFalse:[
+			"/ followup chars must have 2r10 in high bits
+			InvalidEncodingError raiseRequestWith:ch codePoint.
+			^ c1.
+		    ].
+		    ch
+		 ].
 
     (codePoint bitAnd:2r11100000) == 2r11000000 ifTrue:[
-        "/ 110xxxxx 10xxxxxx - 11 bits
-        c2 := fetchNext value.
-        codePoint := c1 codePoint bitAnd:16r1F.
-        codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
-        codePoint <= 16r7F ifTrue:[
-            InvalidEncodingError raiseRequestWith:codePoint.
-        ].
-        ^ Character codePoint:codePoint
+	"/ 110xxxxx 10xxxxxx - 11 bits
+	c2 := fetchNext value.
+	codePoint := c1 codePoint bitAnd:16r1F.
+	codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
+	codePoint <= 16r7F ifTrue:[
+	    InvalidEncodingError raiseRequestWith:codePoint.
+	].
+	^ Character codePoint:codePoint
     ].
     (codePoint bitAnd:2r11110000) == 2r11100000 ifTrue:[
-        "/ 1110xxxx 10xxxxxx 10xxxxxx - 16 bits
-        c2 := fetchNext value.
-        c3 := fetchNext value.
-        codePoint := c1 codePoint bitAnd:16r0F.
-        codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
-        codePoint <= 16r7FF ifTrue:[
-            InvalidEncodingError raiseRequestWith:codePoint.
-        ].
-        ^ Character codePoint:codePoint
+	"/ 1110xxxx 10xxxxxx 10xxxxxx - 16 bits
+	c2 := fetchNext value.
+	c3 := fetchNext value.
+	codePoint := c1 codePoint bitAnd:16r0F.
+	codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
+	codePoint <= 16r7FF ifTrue:[
+	    InvalidEncodingError raiseRequestWith:codePoint.
+	].
+	^ Character codePoint:codePoint
     ].
 
     "/ notice: currently, characters can only have 16bit encoding;
     "/ therefore the following will raise a runtime exception,
 
     (codePoint bitAnd:2r11111000) == 2r11110000 ifTrue:[
-        "/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 21 bits
-        c2 := fetchNext value.
-        c3 := fetchNext value.
-        c4 := fetchNext value.
-        codePoint := c1 codePoint bitAnd:16r07.
-        codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c4 codePoint bitAnd:16r3F).
-        codePoint <= 16rFFFF ifTrue:[
-            InvalidEncodingError raiseRequestWith:codePoint.
-        ].
-        ^ Character codePoint:codePoint
+	"/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 21 bits
+	c2 := fetchNext value.
+	c3 := fetchNext value.
+	c4 := fetchNext value.
+	codePoint := c1 codePoint bitAnd:16r07.
+	codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c4 codePoint bitAnd:16r3F).
+	codePoint <= 16rFFFF ifTrue:[
+	    InvalidEncodingError raiseRequestWith:codePoint.
+	].
+	^ Character codePoint:codePoint
     ].
 
     (codePoint bitAnd:2r11111100) == 2r11111000 ifTrue:[
-        "/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - 26 bits
-        c2 := fetchNext value.
-        c3 := fetchNext value.
-        c4 := fetchNext value.
-        c5 := fetchNext value.
-        codePoint := c1 codePoint bitAnd:16r03.
-        codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c4 codePoint bitAnd:16r3F).
-        codePoint := (codePoint bitShift:6) bitOr:(c5 codePoint bitAnd:16r3F).
-        codePoint <= 16r1FFFFF ifTrue:[
-            InvalidEncodingError raiseRequestWith:codePoint.
-        ].
-        ^ Character codePoint:codePoint
+	"/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - 26 bits
+	c2 := fetchNext value.
+	c3 := fetchNext value.
+	c4 := fetchNext value.
+	c5 := fetchNext value.
+	codePoint := c1 codePoint bitAnd:16r03.
+	codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c3 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c4 codePoint bitAnd:16r3F).
+	codePoint := (codePoint bitShift:6) bitOr:(c5 codePoint bitAnd:16r3F).
+	codePoint <= 16r1FFFFF ifTrue:[
+	    InvalidEncodingError raiseRequestWith:codePoint.
+	].
+	^ Character codePoint:codePoint
     ].
 
     (codePoint bitAnd:2r11111110) == 2r11111100 ifTrue:[
-        "/ 1111110x ... 10xxxxxx - any number of bits
-        codePoint := c1 codePoint bitAnd:16r01.
-
-        c2 := aStream peek.
-        [c2 notNil and:[(c2 codePoint bitAnd:2r11000000) == 2r10000000]] whileTrue:[
-            codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
-            aStream next.
-            c2 := aStream peek.
-        ].
-        codePoint <= 16r3FFFFFF ifTrue:[
-            InvalidEncodingError raiseRequestWith:codePoint.
-        ].
-        ^ Character codePoint:codePoint
+	"/ 1111110x ... 10xxxxxx - any number of bits
+	codePoint := c1 codePoint bitAnd:16r01.
+
+	c2 := aStream peek.
+	[c2 notNil and:[(c2 codePoint bitAnd:2r11000000) == 2r10000000]] whileTrue:[
+	    codePoint := (codePoint bitShift:6) bitOr:(c2 codePoint bitAnd:16r3F).
+	    aStream next.
+	    c2 := aStream peek.
+	].
+	codePoint <= 16r3FFFFFF ifTrue:[
+	    InvalidEncodingError raiseRequestWith:codePoint.
+	].
+	^ Character codePoint:codePoint
     ].
 
     InvalidEncodingError raiseRequestWith:codePoint.
@@ -289,12 +289,12 @@
       |utf8Encoding original readBack|
 
       1 to:16rFFFF do:[:codePoint |
-        original := Character value:codePoint.
-        utf8Encoding := original asString utf8Encoded.
-        readBack := Character utf8DecodeFrom:(utf8Encoding readStream).
-        readBack codePoint = codePoint ifFalse:[
-            self halt
-        ]
+	original := Character value:codePoint.
+	utf8Encoding := original asString utf8Encoded.
+	readBack := Character utf8DecodeFrom:(utf8Encoding readStream).
+	readBack codePoint = codePoint ifFalse:[
+	    self halt
+	]
       ]
     "
 !
@@ -1418,11 +1418,50 @@
      and the argument, a string or character.
      Added for symetry, as we allow string,char also char,string should be allowed"
 
+%{
+    OBJ s;
+    unsigned INT val;
+
+    // fast code for common cases
+    val = __intVal(__characterVal(self));
+    if (val <= 0xFF) {
+	if (__isCharacter(aStringOrCharacter)) {
+	    unsigned INT val2 = __intVal(__characterVal(aStringOrCharacter));
+
+	    if (val2 <= 0xFF) {
+		char buffer[2];
+
+		buffer[0] = val;
+		buffer[1] = val2;
+		s = __MKSTRING_L(buffer, 2);
+		if (s != nil) {
+		    RETURN (s);
+		}
+	    }
+	} else {
+	    if (__isString(aStringOrCharacter)) {
+		int sz = __stringSize(aStringOrCharacter);
+
+		s = __MKEMPTYSTRING(sz);
+		if (s != nil) {
+		    __StringInstPtr(s)->s_element[0] = val;
+		    memcpy(__StringInstPtr(s)->s_element+1, __stringVal(aStringOrCharacter), sz+1); // copies 0-byte too
+		    RETURN (s);
+		}
+	    }
+	}
+    }
+%}.
     ^ self asString , aStringOrCharacter
 
     "
      $. , $:
      $. , 'abc' , $.
+
+      Time millisecondsToRun:[ 10000000 timesRepeat:[ $a , $b ]]
+      Time millisecondsToRun:[ 10000000 timesRepeat:[ $a , 'b' ]]
+      Time millisecondsToRun:[ 10000000 timesRepeat:[ 'a' , 'b' ]]
+      Time millisecondsToRun:[ 10000000 timesRepeat:[ 'a' , $b ]]
     "
 !
 
@@ -2842,10 +2881,9 @@
 !Character class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Character.st,v 1.149 2014-02-11 21:32:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Character.st,v 1.150 2014-02-19 14:12:30 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Character.st,v 1.149 2014-02-11 21:32:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Character.st,v 1.150 2014-02-19 14:12:30 cg Exp $'
 ! !
-