diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-06-30 05:18:24 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-06-30 05:18:24 +0400 |
commit | c15da2e2b376d81671f35e821e94db19e59d5ddd (patch) | |
tree | 7bcc2c929df2dd49f27ef3083eb830344b3d7685 /src/Data | |
parent | f556bf196bf07308f024cc43c1a51dfd4c21188c (diff) |
+ Add very basic storage operations.
Now we can download and make some progress, but very unstable.
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/Bitfield.hs | 23 | ||||
-rw-r--r-- | src/Data/Torrent.hs | 15 |
2 files changed, 24 insertions, 14 deletions
diff --git a/src/Data/Bitfield.hs b/src/Data/Bitfield.hs index 46e0a71f..89461fd2 100644 --- a/src/Data/Bitfield.hs +++ b/src/Data/Bitfield.hs | |||
@@ -32,6 +32,7 @@ module Data.Bitfield | |||
32 | 32 | ||
33 | -- * Construction | 33 | -- * Construction |
34 | , haveAll, haveNone, have, singleton | 34 | , haveAll, haveNone, have, singleton |
35 | , interval | ||
35 | , adjustSize | 36 | , adjustSize |
36 | 37 | ||
37 | -- * Query | 38 | -- * Query |
@@ -137,6 +138,10 @@ singleton ix pc = have ix (haveNone pc) | |||
137 | adjustSize :: PieceCount -> Bitfield -> Bitfield | 138 | adjustSize :: PieceCount -> Bitfield -> Bitfield |
138 | adjustSize s Bitfield {..} = Bitfield s bfSet | 139 | adjustSize s Bitfield {..} = Bitfield s bfSet |
139 | 140 | ||
141 | -- | NOTE: for internal use only | ||
142 | interval :: PieceCount -> PieceIx -> PieceIx -> Bitfield | ||
143 | interval pc a b = Bitfield pc (S.interval a b) | ||
144 | |||
140 | {----------------------------------------------------------------------- | 145 | {----------------------------------------------------------------------- |
141 | Query | 146 | Query |
142 | -----------------------------------------------------------------------} | 147 | -----------------------------------------------------------------------} |
@@ -174,16 +179,14 @@ notMember ix bf @ Bitfield {..} | |||
174 | | otherwise = True | 179 | | otherwise = True |
175 | 180 | ||
176 | -- | Find first available piece index. | 181 | -- | Find first available piece index. |
177 | findMin :: Bitfield -> Maybe PieceIx | 182 | findMin :: Bitfield -> PieceIx |
178 | findMin Bitfield {..} | 183 | findMin = S.findMin . bfSet |
179 | | S.null bfSet = Nothing | 184 | {-# INLINE findMin #-} |
180 | | otherwise = Just (S.findMin bfSet) | ||
181 | 185 | ||
182 | -- | Find last available piece index. | 186 | -- | Find last available piece index. |
183 | findMax :: Bitfield -> Maybe PieceIx | 187 | findMax :: Bitfield -> PieceIx |
184 | findMax Bitfield {..} | 188 | findMax = S.findMax . bfSet |
185 | | S.null bfSet = Nothing | 189 | {-# INLINE findMax #-} |
186 | | otherwise = Just (S.findMax bfSet) | ||
187 | 190 | ||
188 | isSubsetOf :: Bitfield -> Bitfield -> Bool | 191 | isSubsetOf :: Bitfield -> Bitfield -> Bool |
189 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b | 192 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b |
@@ -333,11 +336,11 @@ strategyClass threshold = classify . completeness | |||
333 | 336 | ||
334 | -- | Select the first available piece. | 337 | -- | Select the first available piece. |
335 | strictFirst :: Selector | 338 | strictFirst :: Selector |
336 | strictFirst h a _ = findMin (difference a h) | 339 | strictFirst h a _ = Just $ findMin (difference a h) |
337 | 340 | ||
338 | -- | Select the last available piece. | 341 | -- | Select the last available piece. |
339 | strictLast :: Selector | 342 | strictLast :: Selector |
340 | strictLast h a _ = findMax (difference a h) | 343 | strictLast h a _ = Just $ findMax (difference a h) |
341 | 344 | ||
342 | -- | | 345 | -- | |
343 | rarestFirst :: Selector | 346 | rarestFirst :: Selector |
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index 551a260c..bdd38630 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -34,6 +34,8 @@ module Data.Torrent | |||
34 | , contentLength, pieceCount, blockCount | 34 | , contentLength, pieceCount, blockCount |
35 | , isSingleFile, isMultiFile | 35 | , isSingleFile, isMultiFile |
36 | 36 | ||
37 | , checkPiece | ||
38 | |||
37 | -- * Info hash | 39 | -- * Info hash |
38 | #if defined (TESTING) | 40 | #if defined (TESTING) |
39 | , InfoHash(..) | 41 | , InfoHash(..) |
@@ -77,6 +79,9 @@ import Network.URI | |||
77 | import System.FilePath | 79 | import System.FilePath |
78 | import Numeric | 80 | import Numeric |
79 | 81 | ||
82 | import Data.ByteString.Internal | ||
83 | import Debug.Trace | ||
84 | |||
80 | 85 | ||
81 | type Time = Text | 86 | type Time = Text |
82 | 87 | ||
@@ -141,6 +146,8 @@ simpleTorrent announce info = torrent announce info | |||
141 | Nothing Nothing Nothing | 146 | Nothing Nothing Nothing |
142 | Nothing Nothing | 147 | Nothing Nothing |
143 | 148 | ||
149 | -- TODO check if pieceLength is power of 2 | ||
150 | |||
144 | -- | Info part of the .torrent file contain info about each content file. | 151 | -- | Info part of the .torrent file contain info about each content file. |
145 | data ContentInfo = | 152 | data ContentInfo = |
146 | SingleFile { | 153 | SingleFile { |
@@ -361,14 +368,14 @@ slice from to = B.take to . B.drop from | |||
361 | 368 | ||
362 | -- | Extract validation hash by specified piece index. | 369 | -- | Extract validation hash by specified piece index. |
363 | pieceHash :: ContentInfo -> Int -> ByteString | 370 | pieceHash :: ContentInfo -> Int -> ByteString |
364 | pieceHash ci ix = slice offset size (ciPieces ci) | 371 | pieceHash ci ix = slice (hashsize * ix) hashsize (ciPieces ci) |
365 | where | 372 | where |
366 | offset = ciPieceLength ci * ix | 373 | hashsize = 20 |
367 | size = ciPieceLength ci | ||
368 | 374 | ||
369 | -- | Validate piece with metainfo hash. | 375 | -- | Validate piece with metainfo hash. |
370 | checkPiece :: ContentInfo -> Int -> ByteString -> Bool | 376 | checkPiece :: ContentInfo -> Int -> ByteString -> Bool |
371 | checkPiece ci ix piece | 377 | checkPiece ci ix piece @ (PS _ off si) |
378 | | traceShow (ix, off, si) True | ||
372 | = B.length piece == ciPieceLength ci | 379 | = B.length piece == ciPieceLength ci |
373 | && hash piece == InfoHash (pieceHash ci ix) | 380 | && hash piece == InfoHash (pieceHash ci ix) |
374 | 381 | ||