CRC32Stream.st
changeset 4898 358715fe8ff2
parent 4890 e2c11ec25c50
child 4901 98825b2502d8
--- a/CRC32Stream.st	Sat Mar 23 11:48:37 2019 +0100
+++ b/CRC32Stream.st	Sat Mar 23 11:48:47 2019 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 2003 by eXept Software AG
 	      All Rights Reserved
@@ -143,71 +141,73 @@
 "
 
   expect 60C1D0A0
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream hashValueOf:'resume') hexPrintString
-								[exEnd]
+                                                                [exEnd]
 
   expect 16r60C1D0A0
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream new
-			    nextPut:$r;
-			    nextPut:$e;
-			    nextPut:$s;
-			    nextPut:$u;
-			    nextPut:$m;
-			    nextPut:$e;
-			    hashValue) hexPrintString
-								[exEnd]
+                            nextPut:$r;
+                            nextPut:$e;
+                            nextPut:$s;
+                            nextPut:$u;
+                            nextPut:$m;
+                            nextPut:$e;
+                            hashValue) hexPrintString
+                                                                [exEnd]
 
   expect 16r70E46888:
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream hashValueOf:#[1 2 3 4 5 6 7]) hexPrintString
-								[exEnd]
+                                                                [exEnd]
 
   expect 16r8CD04C73:
-								[exBegin]
+                                                                [exBegin]
     self information:((CRC32Stream hashValueOf:#[16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
-								[exEnd]
+             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
+                                                                [exEnd]
 
   timing throughput:
   230Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
-								[exBegin]
+                                                                [exBegin]
     |hashStream n t|
 
     hashStream := CRC32Stream new.
     n := 2000000.
     t := Time millisecondsToRun:[
-	    n timesRepeat:[
-		hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
-	    ].
-	 ].
+            n timesRepeat:[
+                hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+            ].
+         ].
     t := (t / 1000) asFloat.
     Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
-    Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
-    Transcript show:(n*50/1024 / t); showCR:' Kb/s'
-								[exEnd]
+    Transcript show:t; show:' seconds for '; show:(50*n/1024/1024) asFloat; showCR:' Mb'.
+    Transcript show:(n*50/1024/1024 / t); showCR:' Mb/s'
+                                                                [exEnd]
 
   500Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
-								[exBegin]
-    |hashStream n t|
+                                                                [exBegin]
+    |hashStream s n t l|
 
     hashStream := CRC32Stream newCastagnoli.
     n := 2000000.
+    s := '12345678901234567890123456789012345678901234567890'.
+    l := s size.
     t := Time millisecondsToRun:[
-	    n timesRepeat:[
-		hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
-	    ].
-	 ].
+            n timesRepeat:[
+                hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+            ].
+         ].
     t := (t / 1000) asFloat.
     Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
-    Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
-    Transcript show:(n*50/1024 / t); showCR:' Kb/s'
-								[exEnd]
+    Transcript show:t; show:' seconds for '; show:(l*n/1024/1024) asFloat; showCR:' Mb'.
+    Transcript show:(n*l/1024/1024 / t); showCR:' Mb/s'
+                                                                [exEnd]
   the real speed is shown with longer inputs...
-								[exBegin]
+                                                                [exBegin]
     |hashStream n t l s|
 
     hashStream := CRC32Stream newCastagnoli.
@@ -215,42 +215,42 @@
     s := '1234567890' ,* 10000.
     l := s size.
     t := Time millisecondsToRun:[
-	    n timesRepeat:[
-		hashStream nextPutAll:s
-	    ].
-	 ].
+            n timesRepeat:[
+                hashStream nextPutAll:s
+            ].
+         ].
     t := (t / 1000) asFloat.
     Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
-    Transcript show:t; show:' seconds for '; show:(l*n/1024) asFloat; showCR:' Kb'.
+    Transcript show:t; show:' seconds for '; show:(l*n/1024/1024) asFloat; showCR:' Mb'.
     Transcript show:(n*l/1024/1024 / t); showCR:' Mb/s'
-								[exEnd]
+                                                                [exEnd]
 
   test vectors from https://tools.ietf.org/html/rfc3720#page-217:
 
   expect 0
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'') hexPrintString
-								[exEnd]
+                                                                [exEnd]
   expect C1D04330
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'a') hexPrintString
-								[exEnd]
+                                                                [exEnd]
   expect E3069283
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'123456789') hexPrintString
-								[exEnd]
+                                                                [exEnd]
   expect 8A9136AA
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:0)) hexPrintString
-								[exEnd]
+                                                                [exEnd]
   expect 62a8ab43
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:16rFF)) hexPrintString
-								[exEnd]
+                                                                [exEnd]
   expect 46dd794e
-								[exBegin]
+                                                                [exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(0 to:31) asByteArray) hexPrintString
-								[exEnd]
+                                                                [exEnd]
 
 "
 ! !
@@ -427,110 +427,119 @@
      and works only for the castagnoli polynom"
 
 %{  /* NOCONTEXT */
+#define HAS_CRC
 #if defined(HAS_CRC)
 
+    int len, offs;
+
+    // fetch first - check later
+    len = __intVal(count);
+    offs = __intVal(start) - 1;
+
     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);
+        int objSize;
+        unsigned char *extPtr;
 
-	    extPtr = (unsigned char *)__externalBytesAddress(anObject);
-	    if (__isSmallInteger(sz)) {
-		objSize = __intVal(sz);
-	    } else {
-		objSize = 0; /* unknown */
-	    }
-	} else {
-	    int nInstVars, nInstBytes;
-	    OBJ oClass = __Class(anObject);
+        // the most common first
+        if (__isStringLike(anObject)) {
+            objSize = __stringSize(anObject);
+            extPtr = (unsigned char *)__stringVal(anObject);
+        } else if (__isByteArray(anObject)) {
+            objSize = __byteArraySize(anObject);
+            extPtr = (unsigned char *)__byteArrayVal(anObject);
+        } else 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;
-	}
+            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 ((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 (__isSmallInteger(__INST(crc))) {
-		_crc = (unsigned int) (__intVal( __INST(crc) ));
-	    } else {
-		_crc = __unsignedLongIntVal( __INST(crc) );
-	    }
+            _crc = (unsigned int) (__intVal( __INST(crc) ));
+            if (!__isSmallInteger(__INST(crc))) {
+                _crc = __unsignedLongIntVal( __INST(crc) );
+            }
 
 # if __POINTER_SIZE__ == 8
-	    if (((unsigned INT)cp & 7) == 0) {
-		// longword aligned
-		for ( ; n >= 32 ; n -= 32, cp += 32) {
-		    unsigned INT w0 = ((unsigned INT *)cp)[0];
-		    unsigned INT w1, w2, w3;
+            if (((unsigned INT)cp & 7) == 0) {
+                // longword aligned
+                for ( ; n >= 32 ; n -= 32, cp += 32) {
+                    unsigned INT w0 = ((unsigned INT *)cp)[0];
+                    unsigned INT w1, w2, w3;
 
-		    _crc = __crc32_u64(_crc, w0);
-		    w1 = ((unsigned INT *)cp)[1];
-		    _crc = __crc32_u64(_crc, w1);
-		    w2 = ((unsigned INT *)cp)[2];
-		    _crc = __crc32_u64(_crc, w2);
-		    w3 = ((unsigned INT *)cp)[3];
-		    _crc = __crc32_u64(_crc, w3);
-		}
-		for ( ; n >= 8 ; n -= 8, cp += 8) {
-		    _crc = __crc32_u64(_crc, ((unsigned INT *)cp)[0]);
-		}
-	    }
+                    _crc = __crc32_u64(_crc, w0);
+                    w1 = ((unsigned INT *)cp)[1];
+                    _crc = __crc32_u64(_crc, w1);
+                    w2 = ((unsigned INT *)cp)[2];
+                    _crc = __crc32_u64(_crc, w2);
+                    w3 = ((unsigned INT *)cp)[3];
+                    _crc = __crc32_u64(_crc, w3);
+                }
+                for ( ; n >= 8 ; n -= 8, cp += 8) {
+                    _crc = __crc32_u64(_crc, ((unsigned INT *)cp)[0]);
+                }
+            }
 # endif // __POINTER_SIZE__ == 8
-	    if (((unsigned INT)cp & 3) == 0) {
-		// word aligned
-		for ( ; n >= 4 ; n -= 4, cp += 4) {
-		    _crc = __crc32_u32(_crc, ((unsigned int *)cp)[0]);
-		}
-	    }
-	    for ( ; n >= 4 ; n -= 4, cp += 4) {
-		_crc = __crc32_u8(_crc, cp[0]);
-		_crc = __crc32_u8(_crc, cp[1]);
-		_crc = __crc32_u8(_crc, cp[2]);
-		_crc = __crc32_u8(_crc, cp[3]);
-	    }
-	    while (n-- > 0) {
-		unsigned char ch = *cp++;
+            if (((unsigned INT)cp & 3) == 0) {
+                // word aligned
+                for ( ; n >= 4 ; n -= 4, cp += 4) {
+                    _crc = __crc32_u32(_crc, ((unsigned int *)cp)[0]);
+                }
+            }
+            for ( ; n >= 4 ; n -= 4, cp += 4) {
+                _crc = __crc32_u8(_crc, cp[0]);
+                _crc = __crc32_u8(_crc, cp[1]);
+                _crc = __crc32_u8(_crc, cp[2]);
+                _crc = __crc32_u8(_crc, cp[3]);
+            }
+            while (n-- > 0) {
+                unsigned char ch = *cp++;
 
-		_crc = __crc32_u8(_crc, ch);
-	    }
+                _crc = __crc32_u8(_crc, ch);
+            }
 
-	    if ((__POINTER_SIZE__==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 ((__POINTER_SIZE__==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);
+            }
 
-	    RETURN (count);
-	}
+            RETURN (count);
+        }
     }
 bad: ;
 #endif
@@ -538,6 +547,7 @@
     self primitiveFailed
 
     "Created: / 17-03-2019 / 16:44:27 / Claus Gittinger"
+    "Modified: / 23-03-2019 / 10:11:14 / Claus Gittinger"
 ! !
 
 !CRC32Stream class methodsFor:'documentation'!
@@ -549,3 +559,4 @@
 version_CVS
     ^ '$Header$'
 ! !
+