]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/checksums/common/common.factor
factor: trim using lists
[factor.git] / basis / checksums / common / common.factor
index 1f25efef24c72e6a5c03de1a3790bed5d902a642..d313b238d70f8f3267ef096e5278b81d3bdafc15 100644 (file)
@@ -1,21 +1,51 @@
 ! Copyright (C) 2006, 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.bitwise strings io.binary namespaces
-make grouping ;
+USING: accessors byte-arrays byte-vectors checksums endian
+grouping kernel make math sequences ;
 IN: checksums.common
 
-SYMBOL: bytes-read
+: calculate-pad-length ( length -- length' )
+    [ 56 < 55 119 ? ] keep - ;
 
-: calculate-pad-length ( length -- pad-length )
-    dup 56 < 55 119 ? swap - ;
-
-: pad-last-block ( str big-endian? length -- str )
+: pad-last-block ( bytes big-endian? length -- blocks )
     [
-        rot %
-        HEX: 80 ,
-        dup HEX: 3f bitand calculate-pad-length 0 <string> %
-        3 shift 8 rot [ >be ] [ >le ] if %
-    ] "" make 64 group ;
-
-: update-old-new ( old new -- )
-    [ get >r get r> ] 2keep >r >r w+ dup r> set r> set ; inline
+        [ % ] 2dip 0x80 ,
+        [ 0x3f bitand calculate-pad-length <byte-array> % ]
+        [ 3 shift 8 rot [ >be ] [ >le ] if % ] bi
+    ] B{ } make 64 group ;
+
+MIXIN: block-checksum
+
+INSTANCE: block-checksum checksum
+
+TUPLE: block-checksum-state < checksum-state
+    { bytes-read integer }
+    { block-size integer } ;
+
+GENERIC: checksum-block ( bytes checksum-state -- )
+
+! Update the bytes-read before calculating checksum in case
+! checksum uses this in the calculation.
+M:: block-checksum-state add-checksum-bytes ( state data -- state )
+    state block-size>> :> block-size
+    state bytes>> length :> initial-len
+    initial-len data length + block-size /mod :> ( n extra )
+    data state bytes>> [ push-all ] keep :> all-bytes
+    all-bytes block-size <groups>
+    extra zero? [ f ] [ unclip-last-slice ] if :> ( blocks remain )
+
+    state [ initial-len - ] change-bytes-read drop
+
+    blocks [
+        state [ block-size + ] change-bytes-read
+        checksum-block
+    ] each
+
+    state [ extra + ] change-bytes-read
+    remain [ >byte-vector ] [ BV{ } clone ] if* >>bytes ;
+
+M: block-checksum checksum-bytes
+    [ swap add-checksum-bytes get-checksum ] with-checksum-state ;
+
+M: block-checksum checksum-stream
+    [ swap add-checksum-stream get-checksum ] with-checksum-state ;