]> gitweb.factorcode.org Git - factor.git/commitdiff
checksums.process: initial commit
authorAlexander Iljin <ajsoft@yandex.ru>
Wed, 22 Jun 2016 01:07:55 +0000 (04:07 +0300)
committerJohn Benediktsson <mrjbq7@gmail.com>
Tue, 20 Sep 2016 03:18:06 +0000 (20:18 -0700)
extra/checksums/process/authors.txt [new file with mode: 0644]
extra/checksums/process/process-docs.factor [new file with mode: 0644]
extra/checksums/process/process.factor [new file with mode: 0644]
extra/checksums/process/summary.txt [new file with mode: 0644]

diff --git a/extra/checksums/process/authors.txt b/extra/checksums/process/authors.txt
new file mode 100644 (file)
index 0000000..8e1955f
--- /dev/null
@@ -0,0 +1 @@
+Alexander Ilin
diff --git a/extra/checksums/process/process-docs.factor b/extra/checksums/process/process-docs.factor
new file mode 100644 (file)
index 0000000..b0c4fb2
--- /dev/null
@@ -0,0 +1,55 @@
+! Copyright (C) 2016 Alexander Ilin.
+! See http://factorcode.org/license.txt for BSD license.
+USING: checksums checksums.common destructors help.markup help.syntax
+kernel strings ;
+IN: checksums.process
+
+ABOUT: "checksums.process"
+
+ARTICLE: "checksums.process" "Checksumming with External Utilities"
+"With the " { $vocab-link "checksums.process" } " vocabulary any console utility can be used to checksum data, provided it supports a certain interface: it should accept input data on STDIN and output result to STDOUT. The output should consist of the hexadecimal checksum string, terminated with \" *-\". For instance, all the checksums from the GNU CoreUtils package support this mode of operation as the default."
+$nl
+"The " { $link checksum-process } " tuple holds a launch descriptor (see " { $link "io.launcher.descriptors" } ") of the utility, e.g. \"sha1sum\". When the " { $link initialize-checksum-state } " method is called on it, a new instance of the checksum utility is started in the background. In Factor it is represented by the " { $link process-state } " tuple. You can then use " { $link add-checksum-bytes } " to stream data to it. When done, call " { $link get-checksum } " to read the resulting checksum and dispose of the tuple in one step. If you want to cancel the work without calling " { $link get-checksum } ", you must " { $link dispose } " of the tuple so that the underlying process is terminated."
+$nl
+"The " { $link checksum-bytes } " and the " { $link checksum-stream } " methods encapsulate the above protocol, including instantiation and disposal of the " { $link process-state } " tuple."
+{ $examples
+    { $example "USING: byte-arrays checksums checksums.process ;"
+    "\"test\" >byte-array \"sha1sum\" <checksum-process> checksum-bytes ."
+    "B{
+    169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135
+    152 47 187 211
+}" }
+    $nl
+    { $example "USING: checksums checksums.common checksums.process"
+    "io io.encodings.binary namespaces ;"
+    "\"LICENSE.txt\" binary ["
+    "    input-stream get \"sha1sum\" <checksum-process> checksum-stream"
+    "] with-file-reader ."
+    "B{
+    125 80 102 9 175 178 81 111 33 59 33 149 187 70 193 32 81
+    188 89 156
+}" }
+} ;
+
+HELP: <checksum-process>
+{ $values
+    { "launch-desc" "see " { $link "io.launcher.descriptors" } }
+    { "checksum-process" "a new instance of " { $link checksum-process } }
+}
+{ $description "This is a simple constructor for the " { $link checksum-process } " tuple." } ;
+
+HELP: checksum-process
+{ $class-description "This is an instance of the " { $link block-checksum } " mixin. It calculates checksums by running a console utility as described in the " { $slot "launch-desc" } " slot, piping data to it and receiving the output at the end. Each call to " { $link initialize-checksum-state } " starts a new external process, which is represented by a " { $link process-state } " instance. The latter also holds the resulting checksum." } ;
+
+HELP: process-state
+{ $class-description "This class represents the current state of a " { $link checksum-process } " checksum calculation. It has an associated external console application running until it is disposed. You may call " { $link add-checksum-bytes } " multiple times to pipe data to the external utility. When finished, call " { $link get-checksum } " to receive the result and terminate the process, or " { $link dispose } " to discard the result and terminate the process. After the first " { $link get-checksum } " call the returned value is stored in the " { $slot "result" } " slot, and subsequent calls return the same value." }
+{ $notes "It is not possible to add more data to the checksum after the first get-checksum call."
+$nl
+"Most code should use " { $link with-checksum-state } " to make sure the external process is disposed of. Higher level words like " { $link checksum-bytes } " and " { $link checksum-stream } " use it to perform the disposal." } ;
+
+HELP: trim-hash
+{ $values
+    { "str" "a string returned by a console hashing utility" }
+    { "str'" "extracted hash string" }
+}
+{ $description "This is a helper word for " { $link process-state } "'s " { $link get-checksum } " implementation. It looks for the hash terminator string \" *-\" and returns everything before it." } ;
diff --git a/extra/checksums/process/process.factor b/extra/checksums/process/process.factor
new file mode 100644 (file)
index 0000000..53cae08
--- /dev/null
@@ -0,0 +1,34 @@
+! Copyright (C) 2016 Alexander Ilin.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors checksums checksums.common combinators destructors
+io io.encodings.binary io.launcher kernel math.parser sequences
+strings ;
+IN: checksums.process
+
+TUPLE: checksum-process launch-desc ;
+INSTANCE: checksum-process block-checksum
+C: <checksum-process> checksum-process
+
+TUPLE: process-state < disposable proc result ;
+
+M: checksum-process initialize-checksum-state ( checksum -- checksum-state )
+    launch-desc>> binary <process-stream> process-state new-disposable swap >>proc ;
+
+M: process-state dispose* ( process-state -- )
+    proc>> [ dispose ] when* ;
+
+M: process-state add-checksum-bytes ( process-state bytes -- process-state' )
+    over proc>> stream-write ;
+
+: trim-hash ( str -- str' ) dup " *-" swap start head ;
+
+M: process-state get-checksum ( checksum-state -- value )
+    dup result>> [
+        dup proc>> [
+            [
+                [ out>> dispose ] keep
+                stream-contents >string trim-hash hex-string>bytes
+            ] with-disposal
+        ] [ B{ } clone ] if*
+        [ >>result ] keep
+    ] unless* nip ;
diff --git a/extra/checksums/process/summary.txt b/extra/checksums/process/summary.txt
new file mode 100644 (file)
index 0000000..c34973b
--- /dev/null
@@ -0,0 +1 @@
+Checksum using console utilities