UninterpretedBytes.st
branchjv
changeset 18285 7aab8c3dab19
parent 18120 e3a375d5f6a8
parent 18284 7887131009f5
child 18366 a6e62e167c32
--- a/UninterpretedBytes.st	Fri Apr 24 06:44:03 2015 +0200
+++ b/UninterpretedBytes.st	Sat Apr 25 06:43:41 2015 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1993 by Claus Gittinger
 	      All Rights Reserved
@@ -11,6 +13,8 @@
 "
 "{ Package: 'stx:libbasic' }"
 
+"{ NameSpace: Smalltalk }"
+
 ArrayedCollection subclass:#UninterpretedBytes
 	instanceVariableNames:''
 	classVariableNames:'IsBigEndian'
@@ -104,6 +108,12 @@
 "
 ! !
 
+!UninterpretedBytes class methodsFor:'initialization'!
+
+initialize
+    IsBigEndian := self isBigEndian.
+! !
+
 !UninterpretedBytes class methodsFor:'instance creation'!
 
 from:aByteArray
@@ -267,6 +277,97 @@
     "Modified: / 18.12.1997 / 17:17:11 / stefan"
 !
 
+uninitializedNew:anInteger
+    "return a new instance of the receiver with uninitialized
+     (i.e. undefined) contents. The indexed elements have any random
+     value. However, any named instance variables are still nilled.
+     For use, when contents will be set anyway shortly after - this
+     is a bit faster than the regular basicNew:, which clears the bytes.
+     Of course, it only makes a difference for very big ByteArrays, such
+     as used for images/bitmaps.
+
+     Notice: if you want to port code using uninitializedNew: to another
+     smalltalk, you have to add an 'uninitializedNew: -> basicNew:'-calling
+     method to the ByteArray class of the other smalltalk."
+
+%{  /* NOCONTEXT */
+    OBJ newobj;
+    INT instsize, nInstVars, nindexedinstvars;
+    REGISTER OBJ *op;
+
+    if (__isSmallInteger(anInteger)) {
+        nindexedinstvars = __intVal(anInteger);
+        if (nindexedinstvars >= 0) {
+            if (self == ByteArray) {
+                /*
+                 * the most common case
+                 */
+                instsize = OHDR_SIZE + nindexedinstvars;
+                if (__CanDoQuickNew(instsize)) {        /* OBJECT ALLOCATION */
+                    __qCheckedNew(newobj, instsize);
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
+                    RETURN (newobj );
+                }
+            } else {
+                /*
+                 * Take care for subclasses like TwoByteString
+                 */
+                switch (__smallIntegerVal(__ClassInstPtr(self)->c_flags) & ARRAYMASK) {
+                case BYTEARRAY:
+                    break;
+
+                case WORDARRAY:
+                case SWORDARRAY:
+                    nindexedinstvars *= 2;
+                    break;
+
+                case LONGARRAY:
+                case SLONGARRAY:
+                    nindexedinstvars *= 4;
+                    break;
+
+                default:
+                    /* don't know about this array type, delegate to super */
+                    goto out;
+                }
+            }
+            nInstVars = __intVal(__ClassInstPtr(self)->c_ninstvars);
+            instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + nindexedinstvars;
+            __PROTECT_CONTEXT__
+            __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
+            __UNPROTECT_CONTEXT__
+            if (newobj != nil) {
+                __InstPtr(newobj)->o_class = self;
+                __qSTORE(newobj, self);
+                if (nInstVars) {
+                    /*
+                     * still have to nil out named instvars ...
+                     */
+#if defined(memset4) && defined(FAST_OBJECT_MEMSET4)
+                    memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
+#else
+# if defined(FAST_MEMSET) && !defined(NEGATIVE_ADDRESSES)
+                    /*
+                     * knowing that nil is 0
+                     */
+                    memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
+# else
+                    op = __InstPtr(newobj)->i_instvars;
+                    while (nInstVars--)
+                        *op++ = nil;
+# endif
+#endif
+                }
+                RETURN ( newobj );
+            }
+        }
+    }
+out:;
+%}.
+    ^ self basicNew:anInteger
+!
+
 with:aByteArray from:start to:stop
     "return new instance with a copy of aByteArray
      beginning at index start up to and including index stop"
@@ -607,13 +708,13 @@
 
     |newFloat|
 
-    msb == UninterpretedBytes isBigEndian ifTrue:[
-	^ self doubleAt:index.
+    msb == IsBigEndian ifTrue:[
+        ^ self doubleAt:index.
     ].
 
     newFloat := Float basicNew.
     1 to:8 do:[:destIndex|
-	newFloat basicAt:(9-destIndex) put:(self at:index - 1 + destIndex)
+        newFloat basicAt:(9-destIndex) put:(self at:index - 1 + destIndex)
     ].
     ^ newFloat.
 
@@ -685,13 +786,13 @@
 
     |flt|
 
-    msb == UninterpretedBytes isBigEndian ifTrue:[
-	^ self doubleAt:index put:aFloat.
+    msb == IsBigEndian ifTrue:[
+        ^ self doubleAt:index put:aFloat.
     ].
 
     flt := aFloat asFloat.
     1 to:8 do:[:srcIndex|
-	self at:index - 1 + srcIndex put:(flt basicAt:(9-srcIndex))
+        self at:index - 1 + srcIndex put:(flt basicAt:(9-srcIndex))
     ].
     ^ aFloat
 
@@ -759,13 +860,13 @@
 
     |newFloat|
 
-    msb == UninterpretedBytes isBigEndian ifTrue:[
-	^ self floatAt:index
+    msb == IsBigEndian ifTrue:[
+        ^ self floatAt:index
     ].
 
     newFloat := ShortFloat basicNew.
     1 to:4 do:[:destIndex|
-	newFloat basicAt:(5-destIndex) put:(self at:index - 1 + destIndex)
+        newFloat basicAt:(5-destIndex) put:(self at:index - 1 + destIndex)
     ].
     ^ newFloat.
 
@@ -838,7 +939,7 @@
 
     |sflt|
 
-    msb == UninterpretedBytes isBigEndian ifTrue:[
+    msb == IsBigEndian ifTrue:[
         self floatAt:index put:aFloat.
         ^ self.
     ].
@@ -942,9 +1043,9 @@
 
     |w|
 
-    w := self unsignedLongLongAt:index bigEndian:(UninterpretedBytes isBigEndian).
+    w := self unsignedLongLongAt:index bigEndian:IsBigEndian.
     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
-	^ w - (16r10000000000000000)
+        ^ w - (16r10000000000000000)
     ].
     ^ w
 
@@ -1124,7 +1225,7 @@
      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
      The value is stored in natural byte order."
 
-    ^ self unsignedLongLongAt:index put:anInteger bigEndian:(UninterpretedBytes isBigEndian)
+    ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian
 
     "Created: / 5.3.1998 / 14:44:00 / stefan"
     "Modified: / 5.3.1998 / 15:02:32 / stefan"
@@ -1173,7 +1274,7 @@
      The index is a smalltalk index (i.e. 1-based).
      The value is retrieved in the machines natural byte order."
 
-    ^ self doubleWordAt:index MSB:(UninterpretedBytes isBigEndian)
+    ^ self doubleWordAt:index MSB:IsBigEndian
 
     "
      |b|
@@ -1301,7 +1402,7 @@
      (for negative values, the stored value is not defined).
      The value is stored in the machines natural byte order."
 
-    ^ self doubleWordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
+    ^ self doubleWordAt:index put:value MSB:IsBigEndian
 
     "
      |b|
@@ -1358,7 +1459,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index MSB:(UninterpretedBytes isBigEndian)
+    ^ self doubleWordAtDoubleWordIndex:index MSB:IsBigEndian
 
     "Created: / 21.1.1998 / 17:43:53 / cg"
     "Modified: / 5.3.1998 / 14:58:06 / stefan"
@@ -1383,7 +1484,7 @@
      accessing the memory as an array of doubleWord entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
+    ^ self doubleWordAtDoubleWordIndex:index put:value MSB:IsBigEndian
 
     "Created: / 21.1.1998 / 17:44:13 / cg"
     "Modified: / 5.3.1998 / 14:58:19 / stefan"
@@ -1702,7 +1803,7 @@
      The value is retrieved in the machines natural byte order.
      This may be worth a primitive."
 
-    ^ self signedDoubleWordAt:index MSB:(UninterpretedBytes isBigEndian)
+    ^ self signedDoubleWordAt:index MSB:IsBigEndian
 
     "
      |b|
@@ -2026,11 +2127,11 @@
     |v|
 
     value >= 0 ifTrue:[
-	v := value
+        v := value
     ] ifFalse:[
-	v := 16r10000 + value
+        v := 16r10000 + value
     ].
-    self unsignedShortAt:index put:v bigEndian:(UninterpretedBytes isBigEndian).
+    self unsignedShortAt:index put:v bigEndian:IsBigEndian.
     ^ value
 
     "
@@ -2183,7 +2284,7 @@
      This is the ST80 equivalent of #wordAt:"
 
 
-    ^ self unsignedShortAt:index bigEndian:(UninterpretedBytes isBigEndian)
+    ^ self unsignedShortAt:index bigEndian:IsBigEndian
 
     "Created: / 5.3.1998 / 11:38:25 / stefan"
     "Modified: / 5.3.1998 / 14:59:25 / stefan"
@@ -2215,7 +2316,7 @@
      The stored value must be in the range 0 .. 16rFFFF.
      The value is stored in the machines natural byteorder."
 
-    ^ self unsignedShortAt:index put:value bigEndian:(UninterpretedBytes isBigEndian)
+    ^ self unsignedShortAt:index put:value bigEndian:IsBigEndian
 
     "
      |b|
@@ -2274,7 +2375,7 @@
      The value is retrieved in the machines natural byte order
      Subclasses may redefine this for better performance."
 
-    ^ self wordAt:index MSB:(UninterpretedBytes isBigEndian)
+    ^ self wordAt:index MSB:IsBigEndian
 
     "Modified: / 5.3.1998 / 14:59:51 / stefan"
 !
@@ -2306,7 +2407,7 @@
      The value is stored in the machines natural byteorder.
      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
 
-    ^ self wordAt:index put:value MSB:(UninterpretedBytes isBigEndian)
+    ^ self wordAt:index put:value MSB:IsBigEndian
 
     "
      |b|
@@ -2364,7 +2465,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index MSB:(UninterpretedBytes isBigEndian)
+    ^ self wordAtWordIndex:index MSB:IsBigEndian
 
     "Created: / 21.1.1998 / 17:48:26 / cg"
     "Modified: / 5.3.1998 / 15:00:16 / stefan"
@@ -2389,7 +2490,7 @@
      accessing the memory as an array of word entries.
      (i.e. indices are 1, 2, ...)"
 
-    ^ self wordAtWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian)
+    ^ self wordAtWordIndex:index put:value MSB:IsBigEndian
 
     "Created: / 21.1.1998 / 17:48:34 / cg"
     "Modified: / 5.3.1998 / 15:00:27 / stefan"
@@ -3073,10 +3174,12 @@
 !UninterpretedBytes class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.100 2014-11-26 08:38:03 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.101 2015-04-24 12:17:11 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.100 2014-11-26 08:38:03 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.101 2015-04-24 12:17:11 stefan Exp $'
 ! !
 
+
+UninterpretedBytes initialize!