--- a/UninterpretedBytes.st Fri May 08 15:24:35 1998 +0200
+++ b/UninterpretedBytes.st Fri May 08 15:26:50 1998 +0200
@@ -17,6 +17,43 @@
category:'Collections-Abstract'
!
+!UninterpretedBytes primitiveDefinitions!
+%{
+/*
+ * Notice: I am abstract, and my subclasses may be anything.
+ * Therefore, the code must always handle the fallback case
+ * where the receiver is neither an ExternalBytes nor a ByteArray.
+ * (which are, however, the most common)
+ *
+ * macro to fetch my byte address and size-in-bytes;
+ * convenient for inline-C code.
+ * (yes, C is bad ...)
+ */
+#define __fetchBytePointerAndSize__(o, pPtr, pSize) \
+ {\
+ if (__isNonNilObject(o)) { \
+ if (__qClass(o) == ByteArray) { \
+ *(pPtr) = (char *)__ByteArrayInstPtr(o)->ba_element; \
+ *(pSize) = __byteArraySize(o); \
+ } else if (__qClass(o) == ExternalBytes) { \
+ OBJ __sz__ = __externalBytesSize(o); \
+ if (__isSmallInteger(__sz__)) { \
+ *(pSize) = __intVal(__sz__); \
+ *(pPtr) = (char *)(__externalBytesAddress(o)); \
+ } else { \
+ *(pPtr) = (char *)0; \
+ } \
+ } else { \
+ *(pPtr) = (char *)0; \
+ } \
+ } else { \
+ *(pPtr) = (char *)0; \
+ } \
+ }
+
+%}
+! !
+
!UninterpretedBytes class methodsFor:'documentation'!
copyright
@@ -44,14 +81,21 @@
UninterpretedBytes itself is abstract, so no instances of it can be created.
- [author:]
- Claus Gittinger
-
[See also:]
ByteArray String ExternalBytes
[author:]
Claus Gittinger
+
+ [Notice:]
+ Notice the confusion due to multiple methods with the same
+ functionality (i.e. 'xxxx:MSB:' vs. 'xxxx:bigEndian:').
+ The reason is that at the time this class was written,
+ ST80 sid not offer protocol to specify the byteOrder, and
+ ST/X provided methods ending in 'MSB:' for this.
+ In the meanwhile, VW added protocol ending in 'bigEndian:',
+ which has been added here for compatibility.
+ (certainly a point, where an ansi-standard will help)
"
! !
@@ -108,7 +152,13 @@
/*
* I dont like ifdefs - you always forget some ...
- * therefore we look into a structure at run-time
+ * therefore we look into a structure at run-time.
+ * (also, there are CPUs around [mips], where the byteorder
+ * is programmable, and which come in different flavours)
+ *
+ * NOTICE:
+ * both the JIT and stc may inline this to a
+ * constant for systems where this is known.
*/
union {
unsigned int u_l;
@@ -119,7 +169,9 @@
if (u.u_c[0] == 0x21) RETURN (false);
RETURN (true);
%}
- "UninterpretedBytes isBigEndian"
+ "
+ UninterpretedBytes isBigEndian
+ "
!
isBuiltInClass
@@ -153,6 +205,7 @@
doubleAt:index
"return the 8-bytes starting at index as a Float.
+ The index is a smalltalk index (i.e. 1-based).
Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
Notice also, that the bytes are expected to be in this machines
float representation - if the bytearray originated from another
@@ -160,16 +213,52 @@
|newFloat|
+%{
+ /*
+ * handle the most common cases fast ...
+ */
+ if (__isSmallInteger(index)) {
+ char *cp;
+ int sz;
+
+ __fetchBytePointerAndSize__(self, &cp, &sz);
+ if (cp) {
+ unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+
+ if ((idx+7) < sz) {
+ cp += idx;
+ /*
+ * aligned
+ */
+ if (((INT)cp & 7) == 0) {
+ double dVal = ((double *)cp)[0];
+ RETURN (__MKFLOAT(dVal));
+ }
+ }
+ }
+ }
+%}.
+
newFloat := Float basicNew.
1 to:8 do:[:destIndex|
newFloat basicAt:destIndex put:(self at:index - 1 + destIndex)
].
^ newFloat.
+
+ "
+ |b|
+
+ b := ByteArray new:20.
+ b doubleAt:1 put:(Float pi).
+ Transcript showCR:b.
+ Transcript showCR:(b doubleAt:1)
+ "
!
doubleAt:index put:aFloat
"store the value of the argument, aFloat into the receiver
starting at index.
+ The index is a smalltalk index (i.e. 1-based).
Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
Notice also, that the bytes are expected to be in this machines
float representation - if the bytearray originated from another
@@ -178,6 +267,32 @@
|flt|
flt := aFloat asFloat.
+%{
+ /*
+ * handle the most common cases fast ...
+ */
+ if (__isSmallInteger(index) && __isFloat(flt)) {
+ char *cp;
+ int sz;
+
+ __fetchBytePointerAndSize__(self, &cp, &sz);
+ if (cp) {
+ unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+
+ if ((idx+7) < sz) {
+ cp += idx;
+ /*
+ * aligned
+ */
+ if (((INT)cp & 7) == 0) {
+ ((double *)cp)[0] = __floatVal(flt);
+ RETURN (aFloat);
+ }
+ }
+ }
+ }
+%}.
+
1 to:8 do:[:srcIndex|
self at:index - 1 + srcIndex put:(flt basicAt:srcIndex)
].
@@ -186,6 +301,7 @@
doubleWordAt:index
"return the 4-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
Subclasses may redefine this for better performance."
@@ -203,12 +319,13 @@
doubleWordAt:index MSB:msb
"return the 4-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB-first, if the msb-arg is true;
LSB-first otherwise.
Subclasses may redefine this for better performance."
|val
- ival "{ Class: SmallInteger }"
+ ival "{ XXClass: SmallInteger }"
i "{ Class: SmallInteger }"
b1 "{ Class: SmallInteger }"
b2 "{ Class: SmallInteger }"
@@ -225,12 +342,12 @@
ival := b1.
ival := (ival bitShift:8) + b2.
ival := (ival bitShift:8) + b3.
- val := (ival * 256) + b4.
+ val := (ival bitShift:8) + b4.
] ifFalse:[
ival := b4.
ival := (ival bitShift:8) + b3.
ival := (ival bitShift:8) + b2.
- val := (ival * 256) + b1.
+ val := (ival bitShift:8) + b1.
].
^ val
@@ -247,6 +364,7 @@
doubleWordAt:index put:value
"set the 4-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value should be in the range 0 to 16rFFFFFFFF
(for negative values, the stored value is not defined).
The value is stored in the machines natural byte order.
@@ -266,6 +384,7 @@
doubleWordAt:index put:aNumber MSB:msb
"set the 4-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value must be in the range 0 to 16rFFFFFFFF.
The value is stored MSB-first if msb is true; LSB-first otherwise.
Subclasses may redefine this for better performance."
@@ -354,6 +473,7 @@
floatAt:index
"return the 4-bytes starting at index as a Float.
+ The index is a smalltalk index (i.e. 1-based).
Notice, that (currently) ST/X Floats are what Doubles are in ST-80;
therefore this method reads a 4-byte float from the byteArray and returns
a float object which keeps an 8-byte double internally.
@@ -373,6 +493,7 @@
floatAt:index put:aFloat
"store the 4 bytes of value of the argument, aFloat into the receiver
starting at index.
+ The index is a smalltalk index (i.e. 1-based).
Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
Notice also, that the bytes are expected to be in this machines
float representation - if the bytearray originated from another
@@ -389,6 +510,7 @@
ieeeDoubleAt:index
"retrieve the 8 bytes starting at index as a float.
+ The index is a smalltalk index (i.e. 1-based).
The 8 bytes are assumed to be in IEEE floating point single precision
number format."
@@ -399,6 +521,8 @@
To date, all supported systems use IEEE float numbers, so there should be
no problem.
"
+ self isIEEEFormat ifFalse:[self error:'unsupported operation'].
+
^ self doubleAt:index
"Created: / 5.3.1998 / 10:50:03 / stefan"
@@ -406,6 +530,7 @@
ieeeDoubleAt:index put:aFloat
"store the value of the argument, aFloat into the receiver
+ The index is a smalltalk index (i.e. 1-based).
starting at index. Storage is in IEEE floating point double precision format.
(i.e. 8 bytes are stored)."
@@ -416,6 +541,8 @@
To date, all supported systems use IEEE float numbers, so there should be
no problem.
"
+ self isIEEEFormat ifFalse:[self error:'unsupported operation'].
+
^ self doubleAt:index put:aFloat
"Created: / 5.3.1998 / 10:50:26 / stefan"
@@ -423,6 +550,7 @@
ieeeFloatAt:index
"retrieve the 4 bytes starting at index as a float.
+ The index is a smalltalk index (i.e. 1-based).
The 4 bytes are assumed to be in IEEE floating point single precision
number format."
@@ -433,6 +561,8 @@
To date, all supported systems use IEEE float numbers, so there should be
no problem.
"
+ self isIEEEFormat ifFalse:[self error:'unsupported operation'].
+
^ self floatAt:index
"Created: / 5.3.1998 / 10:50:45 / stefan"
@@ -440,7 +570,8 @@
ieeeFloatAt:index put:aFloat
"store the value of the argument, aFloat into the receiver
- starting at index. Storage is in IEEE floating point single precision format.
+ starting at index, which is a smalltalk index (i.e. 1-based).
+ Storage is in IEEE floating point single precision format.
(i.e. 4 bytes are stored). Since ST/X floats are really doubles, the low-
order 4 bytes of the precision is lost."
@@ -451,6 +582,8 @@
To date, all supported systems use IEEE float numbers, so there should be
no problem.
"
+ self isIEEEFormat ifFalse:[self error:'unsupported operation'].
+
^ self floatAt:index put:aFloat
"Created: / 5.3.1998 / 10:51:11 / stefan"
@@ -458,6 +591,7 @@
longAt:index
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive."
@@ -482,6 +616,7 @@
longAt:index bigEndian:msb
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
Depending on msb, the value is retrieved MSB-first or LSB-first.
This may be worth a primitive."
@@ -506,6 +641,7 @@
longAt:index put:value
"set the 4-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value is stored in the machines natural byte order.
This may be worth a primitive.
@@ -534,6 +670,7 @@
longLongAt:index
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive."
@@ -559,6 +696,7 @@
longLongAt:index bigEndian:msb
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive."
@@ -584,6 +722,7 @@
longLongAt:byteIndex put:anInteger
"store a signed longLong (64bit) integer.
+ The index is a smalltalk index (i.e. 1-based).
Same as #signedQuadWordAt:put: - for ST80 compatibility."
^ self signedQuadWordAt:byteIndex put:anInteger
@@ -594,6 +733,7 @@
quadWordAt:index MSB:msb
"return the 8-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
Depending on msb, the value is retrieved MSB or LSB-first."
|l
@@ -626,6 +766,7 @@
quadWordAt:index put:anInteger MSB:msb
"set the 8-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
Depending on msb, the value is stored MSB-first or LSB-first."
@@ -659,6 +800,7 @@
shortAt:index
"return the 2-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive.
This is the ST80 equivalent of #signedWordAt:"
@@ -679,6 +821,7 @@
shortAt:index bigEndian:msb
"return the 2-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB-first, if the msb-arg is true;
LSB-first otherwise.
This is the ST80 equivalent of #signedWordAt:"
@@ -698,6 +841,7 @@
shortAt:index put:value
"set the 2-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range -32768 .. +32676.
The value is stored in the machines natural byteorder.
This may be worth a primitive.
@@ -729,6 +873,7 @@
signedByteAt:index
"return the byte at index as a signed 8 bit value.
+ The index is a smalltalk index (i.e. 1-based).
This may be worth a primitive."
^ (self at:index) signExtendedByteValue
@@ -746,6 +891,7 @@
signedByteAt:index put:aSignedByteValue
"return the byte at index as a signed 8 bit value.
+ The index is a smalltalk index (i.e. 1-based).
Return the signedByteValue argument.
This may be worth a primitive."
@@ -771,6 +917,7 @@
signedDoubleWordAt:index
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive."
@@ -794,6 +941,7 @@
signedDoubleWordAt:index MSB:msb
"return the 4-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
Depending on msb, the value is retrieved MSB-first or LSB-first.
This may be worth a primitive."
@@ -817,6 +965,7 @@
signedDoubleWordAt:index put:value
"set the 4-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value is stored in the machines natural byte order.
This may be worth a primitive."
@@ -842,6 +991,7 @@
signedDoubleWordAt:index put:value MSB:msb
"set the 4-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
Depending on msb, the value is stored MSB-first or LSB-first.
This may be worth a primitive."
@@ -867,6 +1017,7 @@
signedWordAt:index
"return the 2-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
This may be worth a primitive."
@@ -884,6 +1035,7 @@
signedWordAt:index MSB:msb
"return the 2-bytes starting at index as a signed Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB-first if the msb-arg is true,
LSB-first otherwise.
This may be worth a primitive."
@@ -903,6 +1055,7 @@
signedWordAt:index put:value
"set the 2-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range -32768 .. +32676.
The value is stored in the machines natural byteorder.
This may be worth a primitive.
@@ -934,6 +1087,7 @@
signedWordAt:index put:value MSB:msb
"set the 2-bytes starting at index from the signed Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range -32768 .. +32676.
The value is stored MSB-first, if the msb-arg is true;
LSB-first otherwise.
@@ -961,7 +1115,8 @@
!
stringAt:index
- "return a string starting at index up to the 0-byte"
+ "return a string starting at index up to the 0-byte.
+ The index is a smalltalk index (i.e. 1-based)."
|stream i "{ Class: SmallInteger }" c|
@@ -978,7 +1133,8 @@
stringAt:index put:aString
"copy aString to the externalBytes, starting at index up to
- (and including) the 0-byte"
+ (and including) the 0-byte.
+ The index is a smalltalk index (i.e. 1-based)."
|i "{ Class: SmallInteger }"|
@@ -1004,7 +1160,8 @@
!
stringAt:index size:maxSize
- "return a string starting at index up to maxSize, or a 0-byte"
+ "return a string starting at index up to maxSize, or a 0-byte.
+ The index is a smalltalk index (i.e. 1-based)."
|stream c i "{ Class: SmallInteger }"|
@@ -1022,6 +1179,7 @@
unsignedLongAt:index
"return the 4-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order.
Subclasses may redefine this for better performance."
@@ -1040,6 +1198,7 @@
unsignedLongAt:index bigEndian:msb
"return the 4-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB-first, if the msb-arg is true;
LSB-first otherwise.
Subclasses may redefine this for better performance."
@@ -1085,6 +1244,7 @@
unsignedLongAt:index put:value
"set the 4-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value should be in the range 0 to 16rFFFFFFFF
(for negative values, the stored value is not defined).
The value is stored in the machines natural byte order.
@@ -1105,6 +1265,7 @@
unsignedLongAt:index put:aNumber bigEndian:msb
"set the 4-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value must be in the range 0 to 16rFFFFFFFF.
The value is stored MSB-first if msb is true; LSB-first otherwise.
Subclasses may redefine this for better performance."
@@ -1143,6 +1304,7 @@
unsignedLongLongAt:index bigEndian:msb
"return the 8-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
Depending on msb, the value is retrieved MSB or LSB-first."
|l
@@ -1176,6 +1338,7 @@
unsignedLongLongAt:index put:anInteger
"set the 8-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
The value is stored in natural byte order."
@@ -1187,6 +1350,7 @@
unsignedLongLongAt:index put:anInteger bigEndian:msb
"set the 8-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
Depending on msb, the value is stored MSB-first or LSB-first."
@@ -1222,6 +1386,7 @@
unsignedShortAt:index
"return the 2-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order
Subclasses may redefine this for better performance.
This is the ST80 equivalent of #wordAt:"
@@ -1235,6 +1400,7 @@
unsignedShortAt:index bigEndian:msb
"return the 2-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB-first (high 8 bits at lower index) if msb is true;
LSB-first (i.e. low 8-bits at lower byte index) if its false)"
@@ -1254,6 +1420,7 @@
unsignedShortAt:index put:value
"set the 2-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range 0 .. 16rFFFF.
The value is stored in the machines natural byteorder."
@@ -1273,6 +1440,7 @@
unsignedShortAt:index put:value bigEndian:msb
"set the 2-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range 0 .. 16rFFFF.
The value is stored LSB-first (i.e. the low 8bits are stored at the
lower index) if msb is false, MSB-first otherwise"
@@ -1311,6 +1479,7 @@
wordAt:index
"return the 2-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved in the machines natural byte order
Subclasses may redefine this for better performance."
@@ -1321,6 +1490,7 @@
wordAt:index MSB:msb
"return the 2-bytes starting at index as an (unsigned) Integer.
+ The index is a smalltalk index (i.e. 1-based).
The value is retrieved MSB (high 8 bits at lower index) if msb is true;
LSB-first (i.e. low 8-bits at lower byte index) if its false.
Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)"
@@ -1340,6 +1510,7 @@
wordAt:index put:value
"set the 2-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range 0 .. 16rFFFF.
The value is stored in the machines natural byteorder.
Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
@@ -1359,6 +1530,7 @@
wordAt:index put:value MSB:msb
"set the 2-bytes starting at index from the (unsigned) Integer value.
+ The index is a smalltalk index (i.e. 1-based).
The stored value must be in the range 0 .. 16rFFFF.
The value is stored LSB-first (i.e. the low 8bits are stored at the
lower index) if msb is false, MSB-first otherwise.
@@ -1446,7 +1618,8 @@
zeroByteStringAt:index maximumSize:count
"extract a zeroByte-delimited string, given initial index and
- maximum number of characters (bytes)"
+ maximum number of characters (bytes).
+ The index is a smalltalk index (i.e. 1-based)."
|bytes idx|
@@ -1461,7 +1634,8 @@
!UninterpretedBytes methodsFor:'misc'!
swapLongAt:byteIndex
- "swap the byteOrder of a long."
+ "swap the byteOrder of a long.
+ The index is a smalltalk index (i.e. 1-based)."
|t|
@@ -1489,6 +1663,6 @@
!UninterpretedBytes class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.23 1998-04-25 21:33:11 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.24 1998-05-08 13:26:50 cg Exp $'
! !
UninterpretedBytes initialize!