#REFACTORING by cg
authorClaus Gittinger <cg@exept.de>
Sat, 16 Mar 2019 21:44:25 +0100
changeset 4846 f5b34b8c44e3
parent 4845 36770d6f14bf
child 4847 c76689ab85bf
#REFACTORING by cg class: CRCStream added: #nextPutBytes:from:startingAt:
CRCStream.st
--- a/CRCStream.st	Sat Mar 16 21:42:14 2019 +0100
+++ b/CRCStream.st	Sat Mar 16 21:44:25 2019 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "{ Package: 'stx:libbasic2' }"
 
 "{ NameSpace: Smalltalk }"
@@ -157,6 +159,150 @@
     "Modified: / 16-03-2019 / 21:27:59 / Claus Gittinger"
 ! !
 
+!CRCStream methodsFor:'writing'!
+
+nextPutBytes:count from:anObject startingAt:start
+    "add the hash of anObject to the computed hash so far."
+
+%{
+    if (__bothSmallInteger(count, start)) {
+        int len, offs;
+        int objSize;
+        unsigned char *extPtr;
+
+        len = __intVal(count);
+        offs = __intVal(start) - 1;
+
+        if (__isExternalBytesLike(anObject)) {
+            OBJ sz = __externalBytesSize(anObject);
+
+            extPtr = (unsigned char *)__externalBytesAddress(anObject);
+            if (__isSmallInteger(sz)) {
+                objSize = __intVal(sz);
+            } else {
+                objSize = 0; /* unknown */
+            }
+        } else {
+            int nInstVars, nInstBytes;
+            OBJ 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 = __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 = __integerArrayVal( __INST(crcTable) );
+            unsigned char *cp = extPtr+offs;
+            unsigned int n = len;
+
+            if (sizeof(INT) == 8 || __isSmallInteger(__INST(crc)) ) {
+                _crc = (unsigned int) (__intVal( __INST(crc) ));
+            } else {
+                _crc = __unsignedLongIntVal( __INST(crc) );
+            }
+
+#ifdef __LSBFIRST__
+# if __POINTER_SIZE__ == 8
+            if (((unsigned INT)cp & 7) == 0) {
+                // longword aligned
+                for ( ; n >= 8 ; n -= 8, cp += 8) {
+                    unsigned INT lWord;
+                    unsigned char _idx;
+
+                    lWord = ((unsigned INT *)cp)[0];
+                    _idx = (_crc ^ lWord) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>8)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>16)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>24)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    
+                    _idx = (_crc ^ (lWord>>32)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>40)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>48)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                    _idx = (_crc ^ (lWord>>56)) & 0xFF;
+                    _crc = _crcTable[_idx] ^ (_crc >> 8);
+                }
+            }
+# endif            
+            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);
+                }
+            }
+#endif
+            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);
+            }
+            while (n-- > 0) {
+                unsigned char _idx = (_crc ^ *cp++) & 0xFF;
+                _crc = _crcTable[_idx] ^ (_crc >> 8);
+            }
+
+            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: ;
+%}.
+    self error:'invalid argument'
+
+    "Created: / 09-01-2012 / 16:48:35 / cg"
+    "Modified: / 16-03-2019 / 21:40:02 / Claus Gittinger"
+! !
+
 !CRCStream class methodsFor:'documentation'!
 
 version_CVS