--- a/UninterpretedBytes.st Mon Sep 19 08:39:59 2016 +0100
+++ b/UninterpretedBytes.st Mon Sep 19 08:46:27 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
@@ -14,10 +16,10 @@
"{ NameSpace: Smalltalk }"
ArrayedCollection subclass:#UninterpretedBytes
- instanceVariableNames:''
- classVariableNames:'IsBigEndian'
- poolDictionaries:''
- category:'Collections-Abstract'
+ instanceVariableNames:''
+ classVariableNames:'IsBigEndian'
+ poolDictionaries:''
+ category:'Collections-Abstract'
!
!UninterpretedBytes primitiveDefinitions!
@@ -743,7 +745,7 @@
longLongAt:index
"return the 8-bytes starting at index as a signed Integer.
The index is a smalltalk index (i.e. 1-based).
- The value is retrieved in the machineÄs natural byte order.
+ The value is retrieved in the machineÄs natural byte order.
This may be worth a primitive."
^ self signedInt64At:index MSB:IsBigEndian
@@ -4388,13 +4390,17 @@
!UninterpretedBytes methodsFor:'hashing'!
computeXorHashFrom:startIndex to:endIndex
- "compute and answer the SmallInteger-Hash of the bytes
+ "compute and answer the 32bit SmallInteger-Hash of the bytes
from startIndex to endIndex.
If endindex = 0 or endIndex > size, hash up the size.
NOTE: startIndex and endIndex are only hints about what should be hashed.
In fact, more bytes could be involved in hashing.
- SO ARRAYS MUST BE EQUAL TO HASH TO THE SAME VALUE"
+ SO ARRAYS MUST BE EQUAL TO HASH TO THE SAME VALUE.
+
+ Also NOTE:
+ used to return a 32bit hash on 32bit machines and a 64bit integer on 64bit cpus.
+ changed to return the same for all (in case hash values are used for other purposes)."
|w|
@@ -4407,8 +4413,13 @@
if (cp) {
INT sidx = ((unsigned INT)__smallIntegerVal(startIndex)) - 1;
INT eidx = ((unsigned INT)__smallIntegerVal(endIndex)) - 1;
+// # define H_INT INT
+// # define _MAX_H_INT _MAX_INT;
+# define H_INT int
+# define _MAX_H_INT 0x3FFFFFFF
+
unsigned char *ep;
- unsigned INT hash = 0, hash2 = 0, carry;
+ unsigned H_INT hash = 0, hash2 = 0, carry;
int i;
if (eidx < 0 || eidx >= sz) eidx = sz - 1;
@@ -4427,37 +4438,39 @@
* if the same bytes are at different positions
*/
- if ((INT)cp & (sizeof(INT)-1)) {
+ if ((H_INT)cp & (sizeof(H_INT)-1)) {
/* not aligned */
for (i=0; cp <= ep; cp++) {
hash2 = (hash2 << 8) | *cp;
- if (++i == sizeof(INT)) {
+ if (++i == sizeof(H_INT)) {
hash ^= hash2;
i = hash2 = 0;
}
}
} else {
/* aligned */
- for (; cp+sizeof(INT) <= ep; cp += sizeof(INT)) {
- hash ^= *(unsigned INT *)cp;
+ for (; cp+sizeof(H_INT) <= ep; cp += sizeof(H_INT)) {
+ hash ^= *(unsigned H_INT *)cp;
}
for (; cp <= ep; cp++) {
hash2 = (hash2 << 8) | *cp;
}
}
#else
- for (i=0; cp <= ep-sizeof(INT); cp += sizeof(INT)) {
+ for (i=0; cp <= ep-sizeof(H_INT); cp += sizeof(H_INT)) {
hash2 = cp[0];
hash2 = (hash2 << 8) | cp[1];
hash2 = (hash2 << 8) | cp[2];
hash2 = (hash2 << 8) | cp[3];
-#if __POINTER_SIZE__ == 8
- hash2 = (hash2 << 8) | cp[4];
- hash2 = (hash2 << 8) | cp[5];
- hash2 = (hash2 << 8) | cp[6];
- hash2 = (hash2 << 8) | cp[7];
-#endif
+# if 0
+ if (sizeof(H_INT) == 8) {
+ hash2 = (hash2 << 8) | cp[4];
+ hash2 = (hash2 << 8) | cp[5];
+ hash2 = (hash2 << 8) | cp[6];
+ hash2 = (hash2 << 8) | cp[7];
+ }
+# endif
/*
* multiply by large prime to scramble bits and
* to avoid a 0 result from
@@ -4472,11 +4485,11 @@
hash ^= (hash * 31415821) ^ hash2;
/*
- * fold the high bits not fitting into a SmallInteger
+ * fold the high bits not fitting into a H_INT
*/
- carry = hash & ~_MAX_INT;
+ carry = hash & ~_MAX_H_INT;
if (carry) {
- hash = (hash & _MAX_INT) ^ (carry >> 8);
+ hash = (hash & _MAX_H_INT) ^ (carry >> 8);
}
RETURN(__mkSmallInteger(hash));
@@ -4492,7 +4505,7 @@
#[1 2 3 4] computeXorHashFrom:1 to:0.
#[1 2 3 4 5] computeXorHashFrom:1 to:4.
#[1 2 3 4 1 2 3 4] computeXorHashFrom:1 to:8.
- #[1 2 3 4 5 6 7 8] computeXorHashFrom:2 to:8.
+ #[1 2 3 4 5 6 7 8] computeXorHashFrom:2 to:8.
#[2 3 4 5 6 7 8] computeXorHashFrom:1 to:7.
#[2 3 4 5 6 7 8] computeXorHashFrom:1 to:8.
"