sha-streams (empty) → 0.1.0
raw patch · 5 files changed
+213/−0 lines, 5 filesdep +SHAdep +basedep +binarysetup-changed
Dependencies added: SHA, base, binary, bytestring, io-streams, sha-streams
Files
- LICENSE +27/−0
- Setup.hs +2/−0
- System/IO/Streams/SHA.hs +121/−0
- bin/sha-streams.hs +29/−0
- sha-streams.cabal +34/−0
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright: (c) Vo Minh Thu, 2013.++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ System/IO/Streams/SHA.hs view
@@ -0,0 +1,121 @@+{-# LANGUAGE DeriveDataTypeable #-}+module System.IO.Streams.SHA where++import Control.Exception (Exception, throwIO)+import Data.Binary.Get+import Data.Typeable (Typeable)+import System.IO.Streams.Internal (InputStream (..))+import qualified System.IO.Streams as S++import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as C+import Data.IORef (IORef, newIORef, readIORef, writeIORef)++import Data.Digest.Pure.SHA++sha1Input :: InputStream ByteString -> IO (InputStream ByteString, IO (Digest SHA1State))+sha1Input = shaInput sha1Incremental completeSha1Incremental++sha224Input :: InputStream ByteString -> IO (InputStream ByteString, IO (Digest SHA256State))+sha224Input = shaInput sha224Incremental completeSha224Incremental++sha256Input :: InputStream ByteString -> IO (InputStream ByteString, IO (Digest SHA256State))+sha256Input = shaInput sha256Incremental completeSha256Incremental++sha384Input :: InputStream ByteString -> IO (InputStream ByteString, IO (Digest SHA512State))+sha384Input = shaInput sha384Incremental completeSha384Incremental++sha512Input :: InputStream ByteString -> IO (InputStream ByteString, IO (Digest SHA512State))+sha512Input = shaInput sha512Incremental completeSha512Incremental++checkedSha1Input :: Digest SHA1State -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha1Input = checkedShaInput sha1Incremental completeSha1Incremental . showDigest++checkedSha224Input :: Digest SHA256State -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha224Input = checkedShaInput sha224Incremental completeSha224Incremental . showDigest++checkedSha256Input :: Digest SHA256State -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha256Input = checkedShaInput sha256Incremental completeSha256Incremental . showDigest++checkedSha384Input :: Digest SHA512State -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha384Input = checkedShaInput sha384Incremental completeSha384Incremental . showDigest++checkedSha512Input :: Digest SHA512State -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha512Input = checkedShaInput sha512Incremental completeSha512Incremental . showDigest++checkedSha1Input' :: String -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha1Input' = checkedShaInput sha1Incremental completeSha1Incremental++checkedSha224Input' :: String -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha224Input' = checkedShaInput sha224Incremental completeSha224Incremental++checkedSha256Input' :: String -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha256Input' = checkedShaInput sha256Incremental completeSha256Incremental++checkedSha384Input' :: String -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha384Input' = checkedShaInput sha384Incremental completeSha384Incremental++checkedSha512Input' :: String -> InputStream ByteString -> IO (InputStream ByteString)+checkedSha512Input' = checkedShaInput sha512Incremental completeSha512Incremental++-- | Inspired by `S.countInput`. The returned IO action can be run only+-- when the input stream is exhausted, otherwise an error occurs.+shaInput :: Decoder a -> (Decoder a -> Int -> Digest a)+ -> InputStream ByteString -> IO (InputStream ByteString, IO (Digest a))+shaInput increment end is = do+ ref <- newIORef (increment, 0)+ is' <- S.makeInputStream $ prod ref+ return $! (is', readIORef ref >>= uncurry complete)++ where++ prod ref = do+ mbs <- S.read is+ maybe+ (return Nothing)+ (\bs -> (modifyRef ref (uncurry $ modify bs)) >> (return $! Just bs))+ mbs++ complete decoder c = return $! end decoder c+ modify bs decoder c = (pushChunk decoder bs, c + (fromIntegral $ C.length bs))++-- | This returns an input stream exactly as the one being wrapped, but throws+-- an error if the computed SHA hash does not match the one given.+checkedShaInput :: Decoder a -> (Decoder a -> Int -> Digest a)+ -> String -> InputStream ByteString -> IO (InputStream ByteString)+checkedShaInput increment end digest is = do+ ref <- newIORef (increment, 0)+ is' <- S.makeInputStream $ prod ref+ return $! is'++ where++ prod ref = do+ mbs <- S.read is+ maybe+ (do r <- readIORef ref+ digest' <- uncurry complete r+ if digest == showDigest digest'+ then return Nothing+ else throwIO UnmatchedSHAException)+ (\bs -> (modifyRef ref (uncurry $ modify bs)) >> (return $! Just bs))+ mbs++ complete decoder c = return $! end decoder c+ modify bs decoder c = (pushChunk decoder bs, c + (fromIntegral $ C.length bs))++-- | Taken from System.IO.Streams.ByteString.+{-# INLINE modifyRef #-}+modifyRef :: IORef a -> (a -> a) -> IO ()+modifyRef ref f = do+ x <- readIORef ref+ writeIORef ref $! f x++-- | Exception raised by `checkedShaInput`.+data UnmatchedSHAException = UnmatchedSHAException+ deriving (Typeable)++instance Show UnmatchedSHAException where+ show _ = "Unmatched SHA exception."++instance Exception UnmatchedSHAException
+ bin/sha-streams.hs view
@@ -0,0 +1,29 @@+module Main (main) where++import qualified System.IO.Streams as S++import Data.Digest.Pure.SHA+import System.IO.Streams.SHA++main :: IO ()+main = do+ d1 <- S.withFileAsInput "bin/sha-streams.hs" $ \is -> do+ (is1, getSha1) <- sha1Input is+ (is224, getSha224) <- sha224Input is1+ (is256, getSha256) <- sha256Input is224+ (is384, getSha384) <- sha384Input is256+ (is512, getSha512) <- sha512Input is384+ S.skipToEof is512+ d1 <- getSha1+ putStrLn $ showDigest d1+ getSha224 >>= putStrLn . showDigest+ getSha256 >>= putStrLn . showDigest+ getSha384 >>= putStrLn . showDigest+ getSha512 >>= putStrLn . showDigest+ return d1++ -- This must throw an UnmatchedSHAException.+ S.withFileAsInput "System/IO/Streams/SHA.hs" $ \is -> do+ (is1, _) <- sha1Input is+ is1' <- checkedSha1Input d1 is1+ S.skipToEof is1'
+ sha-streams.cabal view
@@ -0,0 +1,34 @@+name: sha-streams+version: 0.1.0+Cabal-Version: >= 1.8+synopsis: SHA hashes for io-streams.+description: SHA hashes for io-streams.+category: System+license: BSD3+license-file: LICENSE+author: Vo Minh Thu+maintainer: thu@hypered.io+build-type: Simple+homepage: https://github.com/noteed/sha-streams++source-repository head+ type: git+ location: git://github.com/noteed/sha-streams.git++library+ build-depends: base == 4.*,+ binary == 0.7.*,+ bytestring == 0.9.*,+ io-streams == 1.1.*,+ SHA >= 1.6.3+ exposed-modules: System.IO.Streams.SHA+ ghc-options: -Wall++executable sha-streams+ hs-source-dirs: bin+ main-is: sha-streams.hs+ build-depends: base == 4.*,+ io-streams == 1.1.*,+ SHA >= 1.6.3,+ sha-streams+ ghc-options: -Wall