diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Data/Torrent/Bitfield.hs | 13 | ||||
-rw-r--r-- | src/System/Torrent/Storage.hs | 29 |
2 files changed, 37 insertions, 5 deletions
diff --git a/src/Data/Torrent/Bitfield.hs b/src/Data/Torrent/Bitfield.hs index 02a4c14f..8cdae69f 100644 --- a/src/Data/Torrent/Bitfield.hs +++ b/src/Data/Torrent/Bitfield.hs | |||
@@ -62,6 +62,7 @@ module Data.Torrent.Bitfield | |||
62 | , rarest | 62 | , rarest |
63 | 63 | ||
64 | -- * Combine | 64 | -- * Combine |
65 | , insert | ||
65 | , union | 66 | , union |
66 | , intersection | 67 | , intersection |
67 | , difference | 68 | , difference |
@@ -196,6 +197,10 @@ findMax = S.findMax . bfSet | |||
196 | isSubsetOf :: Bitfield -> Bitfield -> Bool | 197 | isSubsetOf :: Bitfield -> Bitfield -> Bool |
197 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b | 198 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b |
198 | 199 | ||
200 | {----------------------------------------------------------------------- | ||
201 | -- Availability | ||
202 | -----------------------------------------------------------------------} | ||
203 | |||
199 | -- | Frequencies are needed in piece selection startegies which use | 204 | -- | Frequencies are needed in piece selection startegies which use |
200 | -- availability quantity to find out the optimal next piece index to | 205 | -- availability quantity to find out the optimal next piece index to |
201 | -- download. | 206 | -- download. |
@@ -240,6 +245,14 @@ rarest xs | |||
240 | Combine | 245 | Combine |
241 | -----------------------------------------------------------------------} | 246 | -----------------------------------------------------------------------} |
242 | 247 | ||
248 | insert :: PieceIx -> Bitfield -> Bitfield | ||
249 | insert pix bf @ Bitfield {..} | ||
250 | | 0 <= pix && pix < bfSize = Bitfield | ||
251 | { bfSet = S.insert pix bfSet | ||
252 | , bfSize = bfSize | ||
253 | } | ||
254 | | otherwise = bf | ||
255 | |||
243 | -- | Find indices at least one peer have. | 256 | -- | Find indices at least one peer have. |
244 | union :: Bitfield -> Bitfield -> Bitfield | 257 | union :: Bitfield -> Bitfield -> Bitfield |
245 | union a b = {-# SCC union #-} Bitfield { | 258 | union a b = {-# SCC union #-} Bitfield { |
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs index 8aa1aa99..a8b0bdc6 100644 --- a/src/System/Torrent/Storage.hs +++ b/src/System/Torrent/Storage.hs | |||
@@ -44,9 +44,12 @@ module System.Torrent.Storage | |||
44 | 44 | ||
45 | import Control.Applicative | 45 | import Control.Applicative |
46 | import Control.Exception | 46 | import Control.Exception |
47 | import Control.Monad as M | ||
47 | import Control.Monad.Trans | 48 | import Control.Monad.Trans |
48 | import Data.ByteString.Lazy as BL | 49 | import Data.ByteString.Lazy as BL |
49 | import Data.Conduit | 50 | import Data.Conduit as C |
51 | import Data.Conduit.Binary as C | ||
52 | import Data.Conduit.List as C | ||
50 | import Data.Typeable | 53 | import Data.Typeable |
51 | 54 | ||
52 | import Data.Torrent.Bitfield as BF | 55 | import Data.Torrent.Bitfield as BF |
@@ -156,10 +159,26 @@ sinkStorage s = do | |||
156 | awaitForever $ \ piece -> | 159 | awaitForever $ \ piece -> |
157 | liftIO $ writePiece piece s | 160 | liftIO $ writePiece piece s |
158 | 161 | ||
159 | -- | TODO examples of use | 162 | -- | This function can be used to generate 'InfoDict' from a set of |
163 | -- opened files. | ||
160 | genPieceInfo :: Storage -> IO PieceInfo | 164 | genPieceInfo :: Storage -> IO PieceInfo |
161 | genPieceInfo = undefined | 165 | genPieceInfo s = do |
166 | hashes <- sourceStorage s $= C.map hashPiece $$ C.sinkLbs | ||
167 | return $ PieceInfo (pieceLen s) (HashList (BL.toStrict hashes)) | ||
162 | 168 | ||
163 | -- | TODO examples of use | 169 | -- | Verify storage. |
170 | -- | ||
171 | -- Throws 'InvalidSize' if piece info size do not match with storage | ||
172 | -- piece size. | ||
173 | -- | ||
164 | getBitfield :: Storage -> PieceInfo -> IO Bitfield | 174 | getBitfield :: Storage -> PieceInfo -> IO Bitfield |
165 | getBitfield = undefined \ No newline at end of file | 175 | getBitfield s @ Storage {..} pinfo @ PieceInfo {..} |
176 | | pieceLen /= piPieceLength = throwIO (InvalidSize piPieceLength) | ||
177 | | otherwise = M.foldM verifyPiece (BF.haveNone total) [0..total - 1] | ||
178 | where | ||
179 | total = totalPieces s | ||
180 | |||
181 | verifyPiece :: Bitfield -> PieceIx -> IO Bitfield | ||
182 | verifyPiece bf pix = do | ||
183 | valid <- checkPieceLazy pinfo <$> readPiece pix s | ||
184 | return $ if valid then BF.insert pix bf else bf | ||