--- 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 $'
! !