--- 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