summaryrefslogtreecommitdiff
path: root/Remote/Helper
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-11-16 23:16:18 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-11-16 23:16:18 -0400
commit039e3ffdfad86fa4e39ca777273be65a7be893db (patch)
treeee10649fbc59636b6d0911d6a40440e0c8b74612 /Remote/Helper
parent373a90aa69eef415b1ec00740dce9f729f8c6b19 (diff)
webdav now checks presence of and receives chunked content
Note that receiving encrypted chunked content currently involves buffering. (So does doing so with the directory special remote.)
Diffstat (limited to 'Remote/Helper')
-rw-r--r--Remote/Helper/Chunked.hs28
1 files changed, 26 insertions, 2 deletions
diff --git a/Remote/Helper/Chunked.hs b/Remote/Helper/Chunked.hs
index 59117eaca..dd6e3eb0d 100644
--- a/Remote/Helper/Chunked.hs
+++ b/Remote/Helper/Chunked.hs
@@ -13,6 +13,7 @@ import Types.Remote
import qualified Data.Map as M
import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString as S
import Data.Int
import qualified Control.Exception as E
@@ -45,8 +46,8 @@ chunkCount = ".chunkcount"
{- Parses the String from the chunkCount file, and returns the files that
- are used to store the chunks. -}
-getChunks :: FilePath -> String -> [FilePath]
-getChunks basedest chunkcount = take count $ map (basedest ++) chunkStream
+listChunks :: FilePath -> String -> [FilePath]
+listChunks basedest chunkcount = take count $ map (basedest ++) chunkStream
where
count = fromMaybe 0 $ readish chunkcount
@@ -119,3 +120,26 @@ storeChunked chunksize dests storer content =
let (chunk, b') = L.splitAt sz b
storer d chunk
storechunks sz (d:useddests) ds b'
+
+{- Write a L.ByteString to a file, updating a progress meter
+ - after each chunk of the L.ByteString, typically every 64 kb or so. -}
+meteredWriteFile :: MeterUpdate -> FilePath -> L.ByteString -> IO ()
+meteredWriteFile meterupdate dest b =
+ meteredWriteFileChunks meterupdate dest (L.toChunks b) feeder
+ where
+ feeder chunks = return ([], chunks)
+
+{- Writes a series of S.ByteString chunks to a file, updating a progress
+ - meter after each chunk. The feeder is called to get more chunks. -}
+meteredWriteFileChunks :: MeterUpdate -> FilePath -> s -> (s -> IO (s, [S.ByteString])) -> IO ()
+meteredWriteFileChunks meterupdate dest startstate feeder =
+ E.bracket (openFile dest WriteMode) hClose (feed startstate [])
+ where
+ feed state [] h = do
+ (state', cs) <- feeder state
+ unless (null cs) $
+ feed state' cs h
+ feed state (c:cs) h = do
+ S.hPut h c
+ meterupdate $ toInteger $ S.length c
+ feed state cs h