summaryrefslogtreecommitdiff
path: root/guix/hash.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-01-19 18:16:28 +0100
committerLudovic Courtès <ludo@gnu.org>2014-01-24 00:01:49 +0100
commit045111e10c0197f1a235bb886df2e446285a6f70 (patch)
tree78df65f724743cc75caad8749d796584b8e3ef17 /guix/hash.scm
parentd28684b5a5369ac87b0a2d3ae125a54d74826a2e (diff)
downloadguix-patches-045111e10c0197f1a235bb886df2e446285a6f70.tar
guix-patches-045111e10c0197f1a235bb886df2e446285a6f70.tar.gz
hash: Add 'open-sha256-input-port', for Guile > 2.0.9.
* guix/hash.scm (open-sha256-input-port): New procedure. * tests/hash.scm (supports-unbuffered-cbip?): New procedure. ("open-sha256-input-port, empty", "open-sha256-input-port, hello", "open-sha256-input-port, hello, one two", "open-sha256-input-port, hello, read from wrapped port"): New tests.
Diffstat (limited to 'guix/hash.scm')
-rw-r--r--guix/hash.scm42
1 files changed, 40 insertions, 2 deletions
diff --git a/guix/hash.scm b/guix/hash.scm
index 92ecaf78d5..fb85f47586 100644
--- a/guix/hash.scm
+++ b/guix/hash.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -25,7 +25,8 @@
#:use-module (srfi srfi-11)
#:export (sha256
open-sha256-port
- port-sha256))
+ port-sha256
+ open-sha256-input-port))
;;; Commentary:
;;;
@@ -128,4 +129,41 @@ output port."
(close-port out)
(get)))
+(define (open-sha256-input-port port)
+ "Return an input port that wraps PORT and a thunk to get the hash of all the
+data read from PORT. The thunk always returns the same value."
+ (define md
+ (open-sha256-md))
+
+ (define (read! bv start count)
+ (let ((n (get-bytevector-n! port bv start count)))
+ (if (eof-object? n)
+ 0
+ (begin
+ (unless digest
+ (let ((ptr (bytevector->pointer bv start)))
+ (md-write md ptr n)))
+ n))))
+
+ (define digest #f)
+
+ (define (finalize!)
+ (let ((ptr (md-read md 0)))
+ (set! digest (bytevector-copy (pointer->bytevector ptr 32)))
+ (md-close md)))
+
+ (define (get-hash)
+ (unless digest
+ (finalize!))
+ digest)
+
+ (define (unbuffered port)
+ ;; Guile <= 2.0.9 does not support 'setvbuf' on custom binary input ports.
+ ;; If you get a wrong-type-arg error here, the fix is to upgrade Guile. :-)
+ (setvbuf port _IONBF)
+ port)
+
+ (values (unbuffered (make-custom-binary-input-port "sha256" read! #f #f #f))
+ get-hash))
+
;;; hash.scm ends here