diff options
Diffstat (limited to 'src/Data/Torrent/Piece.hs')
-rw-r--r-- | src/Data/Torrent/Piece.hs | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/Data/Torrent/Piece.hs b/src/Data/Torrent/Piece.hs index 572b136f..9e7280b0 100644 --- a/src/Data/Torrent/Piece.hs +++ b/src/Data/Torrent/Piece.hs | |||
@@ -15,9 +15,9 @@ module Data.Torrent.Piece | |||
15 | PieceIx | 15 | PieceIx |
16 | , PieceCount | 16 | , PieceCount |
17 | , PieceSize | 17 | , PieceSize |
18 | , defaultPieceSize | ||
19 | , maxPieceSize | ||
20 | , minPieceSize | 18 | , minPieceSize |
19 | , maxPieceSize | ||
20 | , defaultPieceSize | ||
21 | 21 | ||
22 | -- * Piece data | 22 | -- * Piece data |
23 | , Piece (..) | 23 | , Piece (..) |
@@ -28,10 +28,14 @@ module Data.Torrent.Piece | |||
28 | -- * Piece control | 28 | -- * Piece control |
29 | , PieceInfo (..) | 29 | , PieceInfo (..) |
30 | , ppPieceInfo | 30 | , ppPieceInfo |
31 | , pieceCount | ||
32 | |||
33 | -- * Lens | ||
31 | , pieceLength | 34 | , pieceLength |
32 | , pieceHashes | 35 | , pieceHashes |
36 | |||
37 | -- * Validation | ||
33 | , pieceHash | 38 | , pieceHash |
34 | , pieceCount | ||
35 | , checkPieceLazy | 39 | , checkPieceLazy |
36 | 40 | ||
37 | -- * Internal | 41 | -- * Internal |
@@ -64,6 +68,13 @@ import Data.Torrent.Block | |||
64 | class Lint a where | 68 | class Lint a where |
65 | lint :: a -> Either String a | 69 | lint :: a -> Either String a |
66 | 70 | ||
71 | --class Validation a where | ||
72 | -- validate :: PieceInfo -> Piece a -> Bool | ||
73 | |||
74 | {----------------------------------------------------------------------- | ||
75 | -- Piece attributes | ||
76 | -----------------------------------------------------------------------} | ||
77 | |||
67 | -- | Number of pieces in torrent or a part of torrent. | 78 | -- | Number of pieces in torrent or a part of torrent. |
68 | type PieceCount = Int | 79 | type PieceCount = Int |
69 | 80 | ||
@@ -72,18 +83,17 @@ optimalPieceCount :: PieceCount | |||
72 | optimalPieceCount = 1000 | 83 | optimalPieceCount = 1000 |
73 | {-# INLINE optimalPieceCount #-} | 84 | {-# INLINE optimalPieceCount #-} |
74 | 85 | ||
75 | -- | NOTE: Have max and min size constrained to wide used | 86 | -- | Piece size should not be less than this value. |
76 | -- semi-standard values. This bounds should be used to make decision | ||
77 | -- about piece size for new torrents. | ||
78 | -- | ||
79 | maxPieceSize :: Int | ||
80 | maxPieceSize = 4 * 1024 * 1024 | ||
81 | {-# INLINE maxPieceSize #-} | ||
82 | |||
83 | minPieceSize :: Int | 87 | minPieceSize :: Int |
84 | minPieceSize = defaultTransferSize * 4 | 88 | minPieceSize = defaultTransferSize * 4 |
85 | {-# INLINE minPieceSize #-} | 89 | {-# INLINE minPieceSize #-} |
86 | 90 | ||
91 | -- | To prevent transfer degradation piece size should not exceed this | ||
92 | -- value. | ||
93 | maxPieceSize :: Int | ||
94 | maxPieceSize = 4 * 1024 * 1024 | ||
95 | {-# INLINE maxPieceSize #-} | ||
96 | |||
87 | toPow2 :: Int -> Int | 97 | toPow2 :: Int -> Int |
88 | toPow2 x = bit $ fromIntegral (leadingZeros (0 :: Int) - leadingZeros x) | 98 | toPow2 x = bit $ fromIntegral (leadingZeros (0 :: Int) - leadingZeros x) |
89 | 99 | ||
@@ -93,6 +103,10 @@ defaultPieceSize x = max minPieceSize $ min maxPieceSize $ toPow2 pc | |||
93 | where | 103 | where |
94 | pc = fromIntegral (x `div` fromIntegral optimalPieceCount) | 104 | pc = fromIntegral (x `div` fromIntegral optimalPieceCount) |
95 | 105 | ||
106 | {----------------------------------------------------------------------- | ||
107 | -- Piece data | ||
108 | -----------------------------------------------------------------------} | ||
109 | |||
96 | -- TODO check if pieceLength is power of 2 | 110 | -- TODO check if pieceLength is power of 2 |
97 | -- | Piece payload should be strict or lazy bytestring. | 111 | -- | Piece payload should be strict or lazy bytestring. |
98 | data Piece a = Piece | 112 | data Piece a = Piece |
@@ -118,10 +132,14 @@ pieceSize Piece {..} = fromIntegral (BL.length pieceData) | |||
118 | 132 | ||
119 | -- | Test if a block can be safely turned into a piece. | 133 | -- | Test if a block can be safely turned into a piece. |
120 | isPiece :: PieceSize -> Block BL.ByteString -> Bool | 134 | isPiece :: PieceSize -> Block BL.ByteString -> Bool |
121 | isPiece pieceSize blk @ (Block i offset _) = | 135 | isPiece pieceLen blk @ (Block i offset _) = |
122 | offset == 0 && blockSize blk == pieceSize && i >= 0 | 136 | offset == 0 && blockSize blk == pieceLen && i >= 0 |
123 | {-# INLINE isPiece #-} | 137 | {-# INLINE isPiece #-} |
124 | 138 | ||
139 | {----------------------------------------------------------------------- | ||
140 | -- Piece control | ||
141 | -----------------------------------------------------------------------} | ||
142 | |||
125 | newtype HashArray = HashArray { unHashArray :: ByteString } | 143 | newtype HashArray = HashArray { unHashArray :: ByteString } |
126 | deriving (Show, Read, Eq, BEncode) | 144 | deriving (Show, Read, Eq, BEncode) |
127 | 145 | ||
@@ -196,12 +214,10 @@ pieceHash PieceInfo {..} i = slice (hashsize * i) hashsize (unHashArray piPieceH | |||
196 | pieceCount :: PieceInfo -> PieceCount | 214 | pieceCount :: PieceInfo -> PieceCount |
197 | pieceCount PieceInfo {..} = BS.length (unHashArray piPieceHashes) `quot` hashsize | 215 | pieceCount PieceInfo {..} = BS.length (unHashArray piPieceHashes) `quot` hashsize |
198 | 216 | ||
217 | -- | Test if this is last piece in torrent content. | ||
199 | isLastPiece :: PieceInfo -> PieceIx -> Bool | 218 | isLastPiece :: PieceInfo -> PieceIx -> Bool |
200 | isLastPiece ci i = pieceCount ci == succ i | 219 | isLastPiece ci i = pieceCount ci == succ i |
201 | 220 | ||
202 | class Validation a where | ||
203 | validate :: PieceInfo -> Piece a -> Bool | ||
204 | |||
205 | -- | Validate piece with metainfo hash. | 221 | -- | Validate piece with metainfo hash. |
206 | checkPieceLazy :: PieceInfo -> Piece BL.ByteString -> Bool | 222 | checkPieceLazy :: PieceInfo -> Piece BL.ByteString -> Bool |
207 | checkPieceLazy pinfo @ PieceInfo {..} Piece {..} | 223 | checkPieceLazy pinfo @ PieceInfo {..} Piece {..} |