diff options
Diffstat (limited to 'src/Network/BitTorrent/PeerWire/Block.hs')
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Block.hs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/Network/BitTorrent/PeerWire/Block.hs b/src/Network/BitTorrent/PeerWire/Block.hs new file mode 100644 index 00000000..33e3dead --- /dev/null +++ b/src/Network/BitTorrent/PeerWire/Block.hs | |||
@@ -0,0 +1,56 @@ | |||
1 | module Network.BitTorrent.PeerWire.Block | ||
2 | ( BlockIx(..), Block(..) | ||
3 | , defaultBlockSize | ||
4 | , blockRange, ixRange, pieceIx | ||
5 | , isPiece | ||
6 | ) where | ||
7 | |||
8 | import Data.ByteString (ByteString) | ||
9 | import qualified Data.ByteString as B | ||
10 | import Data.Int | ||
11 | |||
12 | |||
13 | data BlockIx = BlockIx { | ||
14 | ixPiece :: {-# UNPACK #-} !Int -- ^ Zero-based piece index. | ||
15 | , ixOffset :: {-# UNPACK #-} !Int -- ^ Zero-based byte offset within the piece. | ||
16 | , ixLength :: {-# UNPACK #-} !Int -- ^ Block size starting from offset. | ||
17 | } deriving (Show, Eq) | ||
18 | |||
19 | data Block = Block { | ||
20 | blkPiece :: Int -- ^ Zero-based piece index. | ||
21 | , blkOffset :: Int -- ^ Zero-based byte offset within the piece. | ||
22 | , blkData :: ByteString -- ^ Payload. | ||
23 | } deriving (Show, Eq) | ||
24 | |||
25 | |||
26 | -- | Widely used semi-official block size. | ||
27 | defaultBlockSize :: Int | ||
28 | defaultBlockSize = 16 * 1024 | ||
29 | |||
30 | |||
31 | isPiece :: Int -> Block -> Bool | ||
32 | isPiece pieceSize (Block i offset bs) = | ||
33 | offset == 0 && B.length bs == pieceSize && i >= 0 | ||
34 | {-# INLINE isPiece #-} | ||
35 | |||
36 | pieceIx :: Int -> Int -> BlockIx | ||
37 | pieceIx i = BlockIx i 0 | ||
38 | {-# INLINE pieceIx #-} | ||
39 | |||
40 | blockRange :: (Num a, Integral a) => Int -> Block -> (a, a) | ||
41 | blockRange pieceSize blk = (offset, offset + len) | ||
42 | where | ||
43 | offset = fromIntegral pieceSize * fromIntegral (blkPiece blk) | ||
44 | + fromIntegral (blkOffset blk) | ||
45 | len = fromIntegral (B.length (blkData blk)) | ||
46 | {-# INLINE blockRange #-} | ||
47 | {-# SPECIALIZE blockRange :: Int -> Block -> (Int64, Int64) #-} | ||
48 | |||
49 | ixRange :: (Num a, Integral a) => Int -> BlockIx -> (a, a) | ||
50 | ixRange pieceSize ix = (offset, offset + len) | ||
51 | where | ||
52 | offset = fromIntegral pieceSize * fromIntegral (ixPiece ix) | ||
53 | + fromIntegral (ixOffset ix) | ||
54 | len = fromIntegral (ixLength ix) | ||
55 | {-# INLINE ixRange #-} | ||
56 | {-# SPECIALIZE ixRange :: Int -> BlockIx -> (Int64, Int64) #-} | ||