packages feed

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 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