From 6aa68125b6d476f0ad9372a0f0fbaa5c118e7096 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 18 Nov 2012 20:06:28 -0400 Subject: upload progress bars for webdav! --- Utility/Observed.hs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Utility/Observed.hs (limited to 'Utility') diff --git a/Utility/Observed.hs b/Utility/Observed.hs new file mode 100644 index 000000000..3ee973429 --- /dev/null +++ b/Utility/Observed.hs @@ -0,0 +1,43 @@ +module Utility.Observed where + +import qualified Data.ByteString.Lazy as L +import qualified Data.ByteString as S +import System.IO +import System.IO.Unsafe +import Foreign.Storable (Storable(sizeOf)) + +{- This is like L.hGetContents, but after each chunk is read, an action + - is run to observe the size of the chunk. + - + - Note that the observer is run in unsafeInterleaveIO, which means that + - it can be run at any time. It's even possible for observers to run out + - of order, as different parts of the ByteString are consumed. + - + - All the usual caveats about using unsafeInterleaveIO apply to the observers, + - so use caution. + -} +hGetContentsObserved :: Handle -> (Int -> IO ()) -> IO L.ByteString +hGetContentsObserved h observe = lazyRead + where + lazyRead = unsafeInterleaveIO loop + + loop = do + c <- S.hGetSome h defaultChunkSize + if S.null c + then do + hClose h + return $ L.empty + else do + observe $ S.length c + {- unsafeInterleaveIO causes this to be + - deferred until the data is read from the + - ByteString. -} + cs <- lazyRead + return $ L.append (L.fromChunks [c]) cs + +{- Same default chunk size Lazy ByteStrings use. -} +defaultChunkSize :: Int +defaultChunkSize = 32 * k - chunkOverhead + where + k = 1024 + chunkOverhead = 2 * sizeOf (undefined :: Int) -- GHC specific -- cgit v1.2.3