From 045111e10c0197f1a235bb886df2e446285a6f70 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 19 Jan 2014 18:16:28 +0100 Subject: 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. --- guix/hash.scm | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'guix') 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 +;;; Copyright © 2012, 2013, 2014 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -25,7 +25,8 @@ (define-module (guix hash) #:use-module (srfi srfi-11) #:export (sha256 open-sha256-port - port-sha256)) + port-sha256 + open-sha256-input-port)) ;;; Commentary: ;;; @@ -128,4 +129,41 @@ (define (port-sha256 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 -- cgit v1.2.3