upload progress bars for webdav!
This commit is contained in:
parent
c8751be151
commit
afa2f9c967
4 changed files with 66 additions and 11 deletions
43
Utility/Observed.hs
Normal file
43
Utility/Observed.hs
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue