CRC32Stream.st
changeset 3024 c7022e1963b0
parent 2963 76da9963f31e
child 4238 ab8390ef187a
--- a/CRC32Stream.st	Sat Jun 29 13:32:33 2013 +0200
+++ b/CRC32Stream.st	Tue Jul 02 13:55:39 2013 +0200
@@ -229,7 +229,7 @@
 hashValue
     "return the computed CRC"
 
-    ^ crc bitXor:16rFFFFFFFF
+    ^ crc bitXor:16rFFFFFFFF.
 ! !
 
 !CRC32Stream methodsFor:'writing'!
@@ -237,125 +237,108 @@
 nextPutBytes:count from:anObject startingAt:start
     "add the hash of anObject to the computed hash so far."
 
-    | argSize "{ Class:SmallInteger }"
-      byte    "{ Class:SmallInteger }" |
-
 %{
     if (__bothSmallInteger(count, start)) {
-	int len, offs;
-	int objSize, nInstVars, nInstBytes;
-	unsigned char *extPtr;
+        int len, offs;
+        int objSize;
+        unsigned char *extPtr;
 
-	len = __intVal(count);
-	offs = __intVal(start) - 1;
+        len = __intVal(count);
+        offs = __intVal(start) - 1;
 
-	if (__isExternalBytesLike(anObject)) {
-	    OBJ sz;
+        if (__isExternalBytesLike(anObject)) {
+            OBJ sz = __externalBytesSize(anObject);
 
-	    nInstBytes = 0;
-	    extPtr = (char *)__externalBytesAddress(anObject);
-	    sz = __externalBytesSize(anObject);
-	    if (__isSmallInteger(sz)) {
-		objSize = __intVal(sz);
-	    } else {
-		objSize = 0; /* unknown */
-	    }
-	} else {
-	    OBJ oClass;
+            extPtr = (unsigned char *)__externalBytesAddress(anObject);
+            if (__isSmallInteger(sz)) {
+                objSize = __intVal(sz);
+            } else {
+                objSize = 0; /* unknown */
+            }
+        } else {
+            int nInstVars, nInstBytes;
+            OBJ oClass = __Class(anObject);
 
-	    oClass = __Class(anObject);
-	    switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
-		case BYTEARRAY:
-		case WORDARRAY:
-		case LONGARRAY:
-		case SWORDARRAY:
-		case SLONGARRAY:
-		case FLOATARRAY:
-		case DOUBLEARRAY:
-		    break;
-		default:
-		    goto bad;
-	    }
-	    nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
-	    nInstBytes = __OBJS2BYTES__(nInstVars);
-	    // nInstBytes is the number of bytes occupied by pointer instance variables
-	    // subtract from size and add to byte-pointer
-	    objSize = __Size(anObject) - OHDR_SIZE - nInstBytes;
-	    extPtr = (char *)__byteArrayVal(anObject)+nInstBytes;
-	}
+            switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+                case BYTEARRAY:
+                case WORDARRAY:
+                case LONGARRAY:
+                case SWORDARRAY:
+                case SLONGARRAY:
+                case FLOATARRAY:
+                case DOUBLEARRAY:
+                    break;
+                default:
+                    goto bad;
+            }
+            nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+            nInstBytes = __OBJS2BYTES__(nInstVars);
+            // nInstBytes is the number of bytes occupied by pointer instance variables
+            // subtract from size and add to byte-pointer
+            objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
+            extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
+        }
 
-	if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
-	    {
-		unsigned int _crc;
-		unsigned int *_crcTable;
-		unsigned char *cp = extPtr+offs;
-		unsigned n = len;
+        if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
+            unsigned int _crc;
+            unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
+            unsigned char *cp = extPtr+offs;
+            unsigned int n = len;
 
-#if POINTER_SIZE == 8
-		_crc = (unsigned) (__intVal( __INST(crc) ));
-#else
-		if (__isSmallInteger(__INST(crc)) ) {
-		    _crc = (unsigned) (__intVal( __INST(crc) ));
-		} else {
-		    _crc = __unsignedLongIntVal( __INST(crc) );
-		}
-#endif
-		_crcTable = __integerArrayVal( __INST(crcTable) );
+            if (sizeof(INT) == 8 || __isSmallInteger(__INST(crc)) ) {
+                _crc = (unsigned int) (__intVal( __INST(crc) ));
+            } else {
+                _crc = __unsignedLongIntVal( __INST(crc) );
+            }
 
 #ifdef __LSBFIRST__
-                if (((unsigned INT)cp & 3) == 0) {
-                    // word aligned
-                    while (n >= 4) {
-                        unsigned word;
-                        unsigned _idx;
+            if (((unsigned INT)cp & 3) == 0) {
+                // word aligned
+                for ( ; n >= 4 ; n -= 4, cp += 4) {
+                    unsigned int word;
+                    unsigned char _idx;
 
-                        word = ((unsigned int *)cp)[0];
-                        _idx = (_crc ^ word) & 0xFF;
-                        _crc = _crcTable[_idx] ^ (_crc >> 8);
-                        _idx = (_crc ^ (word>>8)) & 0xFF;
-                        _crc = _crcTable[_idx] ^ (_crc >> 8);
-                        _idx = (_crc ^ (word>>16)) & 0xFF;
-                        _crc = _crcTable[_idx] ^ (_crc >> 8);
-                        _idx = (_crc ^ (word>>24)) & 0xFF;
-                        _crc = _crcTable[_idx] ^ (_crc >> 8);
-                        cp += 4;
-                        n -= 4;
-                    }
+                    word = ((unsigned int *)cp)[0];
+                    _idx = (_crc ^ word) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (word>>8)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (word>>16)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (word>>24)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
                 }
+            }
 #endif
-		while (n > 3) {
-		    unsigned _idx;
+            for ( ; n >= 4 ; n -= 4, cp += 4) {
+                unsigned char _idx;
 
-		    _idx = (_crc ^ cp[0]) & 0xFF;
-		    _crc = _crcTable[_idx] ^ (_crc >> 8);
-		    _idx = (_crc ^ cp[1]) & 0xFF;
-		    _crc = _crcTable[_idx] ^ (_crc >> 8);
-		    _idx = (_crc ^ cp[2]) & 0xFF;
-		    _crc = _crcTable[_idx] ^ (_crc >> 8);
-		    _idx = (_crc ^ cp[3]) & 0xFF;
-		    _crc = _crcTable[_idx] ^ (_crc >> 8);
-		    cp += 4;
-		    n -= 4;
-		}
-		while (n > 0) {
-		    unsigned _byte = *cp++;
-		    unsigned _idx;
+                _idx = (_crc ^ cp[0]) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+                _idx = (_crc ^ cp[1]) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+                _idx = (_crc ^ cp[2]) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+                _idx = (_crc ^ cp[3]) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+            }
+            while (n-- > 0) {
+                unsigned char _idx = (_crc ^ *cp++) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+            }
 
-		    _idx = (_crc ^ _byte) & 0xFF;
-		    _crc = _crcTable[_idx] ^ (_crc >> 8);
-		    n--;
-		}
-#if POINTER_SIZE == 8
-		__INST(crc) = __MKSMALLINT(_crc);
-#else
-		{
-		    OBJ t;
-		    __INST(crc) = t = __MKUINT(_crc); __STORE(self, t);
-		}
-#endif
-	    }
-	    RETURN (count);
-	}
+            if (sizeof(INT) == 8 || _crc <= _MAX_INT)
+                __INST(crc) = __MKSMALLINT(_crc);
+            else {
+                // this code fails with gcc 4.7.2:
+                // __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
+                OBJ temp = __MKUINT(_crc); 
+                __INST(crc) = temp; __STORESELF(crc);
+            }
+
+            // if (__unsignedLongIntVal(__INST(crc)) == 4294967295) printf("inst: %d crc: %d new: %d\n", __unsignedLongIntVal(__INST(crc)), _crc, __unsignedLongIntVal(temp));
+            RETURN (count);
+        }
     }
 bad: ;
 %}.
@@ -367,11 +350,11 @@
 !CRC32Stream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.26 2013-04-02 09:10:14 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.27 2013-07-02 11:55:39 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.26 2013-04-02 09:10:14 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.27 2013-07-02 11:55:39 stefan Exp $'
 ! !