# HG changeset patch # User Claus Gittinger # Date 894634010 -7200 # Node ID a947253084322d26c836d429c9387c43c1699985 # Parent 1228d4ba9518efcbd912dcaa8ca0224806569e15 added comments; started tuning common multibyte access methods diff -r 1228d4ba9518 -r a94725308432 UIBytes.st --- a/UIBytes.st Fri May 08 15:24:35 1998 +0200 +++ b/UIBytes.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/Attic/UIBytes.st,v 1.23 1998-04-25 21:33:11 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/Attic/UIBytes.st,v 1.24 1998-05-08 13:26:50 cg Exp $' ! ! UninterpretedBytes initialize! diff -r 1228d4ba9518 -r a94725308432 UninterpretedBytes.st --- 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!