diff options
-rw-r--r-- | network-bittorrent.cabal | 1 | ||||
-rw-r--r-- | src/Data/Torrent.hs | 25 | ||||
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Block.hs | 35 | ||||
-rw-r--r-- | src/Network/BitTorrent/Tracker.hs | 1 |
4 files changed, 52 insertions, 10 deletions
diff --git a/network-bittorrent.cabal b/network-bittorrent.cabal index 5cd46216..8c6fd84d 100644 --- a/network-bittorrent.cabal +++ b/network-bittorrent.cabal | |||
@@ -57,6 +57,7 @@ library | |||
57 | , HTTP >= 4000.2 | 57 | , HTTP >= 4000.2 |
58 | , cryptohash | 58 | , cryptohash |
59 | 59 | ||
60 | , filepath == 1.* | ||
60 | 61 | ||
61 | extensions: PatternGuards | 62 | extensions: PatternGuards |
62 | hs-source-dirs: src | 63 | hs-source-dirs: src |
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index e6ed8813..226126f2 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -11,7 +11,8 @@ | |||
11 | module Data.Torrent | 11 | module Data.Torrent |
12 | ( module Data.Torrent.InfoHash | 12 | ( module Data.Torrent.InfoHash |
13 | , Torrent(..), ContentInfo(..), FileInfo(..) | 13 | , Torrent(..), ContentInfo(..), FileInfo(..) |
14 | , contenLength, pieceCount | 14 | , contentLength, pieceCount |
15 | , contentLayout | ||
15 | , fromFile | 16 | , fromFile |
16 | ) where | 17 | ) where |
17 | 18 | ||
@@ -24,7 +25,7 @@ import Data.Text (Text) | |||
24 | import Data.BEncode | 25 | import Data.BEncode |
25 | import Data.Torrent.InfoHash | 26 | import Data.Torrent.InfoHash |
26 | import Network.URI | 27 | import Network.URI |
27 | 28 | import System.FilePath | |
28 | 29 | ||
29 | type Time = Text | 30 | type Time = Text |
30 | 31 | ||
@@ -229,6 +230,26 @@ contentLength MultiFile { ciFiles = tfs } = sum (map fiLength tfs) | |||
229 | pieceCount :: ContentInfo -> Int | 230 | pieceCount :: ContentInfo -> Int |
230 | pieceCount ti = contentLength ti `sizeInBase` ciPieceLength ti | 231 | pieceCount ti = contentLength ti `sizeInBase` ciPieceLength ti |
231 | 232 | ||
233 | -- | File layout specifies the order and the size of each file in the storage. | ||
234 | -- Note that order of files is highly important since we coalesce all | ||
235 | -- the files in the given order to get the linear block address space. | ||
236 | -- | ||
237 | type Layout = [(FilePath, Int)] | ||
238 | |||
239 | fileInfo :: ContentInfo -> [FileInfo] | ||
240 | fileInfo (SingleFile { ciName = name, ciLength = len, ciMD5sum = md5 }) | ||
241 | = [FileInfo len md5 [name]] | ||
242 | fileInfo (MultiFile { ciFiles = fs }) = fs | ||
243 | |||
244 | fileLayout :: FileInfo -> (FilePath, Int) | ||
245 | fileLayout (FileInfo { fiLength = len, fiPath = name }) = (path, fromIntegral len) | ||
246 | where -- WARN use utf8 encoding in name | ||
247 | path = joinPath (map BC.unpack name) | ||
248 | |||
249 | |||
250 | contentLayout :: ContentInfo -> Layout | ||
251 | contentLayout = map fileLayout . fileInfo | ||
252 | |||
232 | 253 | ||
233 | -- | Read and decode a .torrent file. | 254 | -- | Read and decode a .torrent file. |
234 | fromFile :: FilePath -> IO (Result Torrent) | 255 | fromFile :: FilePath -> IO (Result Torrent) |
diff --git a/src/Network/BitTorrent/PeerWire/Block.hs b/src/Network/BitTorrent/PeerWire/Block.hs index 33e3dead..a5bc4f32 100644 --- a/src/Network/BitTorrent/PeerWire/Block.hs +++ b/src/Network/BitTorrent/PeerWire/Block.hs | |||
@@ -1,25 +1,41 @@ | |||
1 | module Network.BitTorrent.PeerWire.Block | 1 | module Network.BitTorrent.PeerWire.Block |
2 | ( BlockIx(..), Block(..) | 2 | ( BlockIx(..), Block(..) |
3 | , BlockLIx, PieceLIx | ||
3 | , defaultBlockSize | 4 | , defaultBlockSize |
4 | , blockRange, ixRange, pieceIx | 5 | , pieceIx, blockIx |
5 | , isPiece | 6 | , blockRange, ixRange, isPiece |
6 | ) where | 7 | ) where |
7 | 8 | ||
9 | import Control.Applicative | ||
8 | import Data.ByteString (ByteString) | 10 | import Data.ByteString (ByteString) |
9 | import qualified Data.ByteString as B | 11 | import qualified Data.ByteString as B |
10 | import Data.Int | 12 | import Data.Int |
11 | 13 | ||
14 | type BlockLIx = Int | ||
15 | type PieceLIx = Int | ||
16 | |||
12 | 17 | ||
13 | data BlockIx = BlockIx { | 18 | data BlockIx = BlockIx { |
14 | ixPiece :: {-# UNPACK #-} !Int -- ^ Zero-based piece index. | 19 | -- ^ Zero-based piece index. |
15 | , ixOffset :: {-# UNPACK #-} !Int -- ^ Zero-based byte offset within the piece. | 20 | ixPiece :: {-# UNPACK #-} !PieceLIx |
16 | , ixLength :: {-# UNPACK #-} !Int -- ^ Block size starting from offset. | 21 | |
22 | -- ^ Zero-based byte offset within the piece. | ||
23 | , ixOffset :: {-# UNPACK #-} !Int | ||
24 | |||
25 | -- ^ Block size starting from offset. | ||
26 | , ixLength :: {-# UNPACK #-} !Int | ||
17 | } deriving (Show, Eq) | 27 | } deriving (Show, Eq) |
18 | 28 | ||
29 | |||
19 | data Block = Block { | 30 | data Block = Block { |
20 | blkPiece :: Int -- ^ Zero-based piece index. | 31 | -- ^ Zero-based piece index. |
21 | , blkOffset :: Int -- ^ Zero-based byte offset within the piece. | 32 | blkPiece :: PieceLIx |
22 | , blkData :: ByteString -- ^ Payload. | 33 | |
34 | -- ^ Zero-based byte offset within the piece. | ||
35 | , blkOffset :: Int | ||
36 | |||
37 | -- ^ Payload. | ||
38 | , blkData :: ByteString | ||
23 | } deriving (Show, Eq) | 39 | } deriving (Show, Eq) |
24 | 40 | ||
25 | 41 | ||
@@ -37,6 +53,9 @@ pieceIx :: Int -> Int -> BlockIx | |||
37 | pieceIx i = BlockIx i 0 | 53 | pieceIx i = BlockIx i 0 |
38 | {-# INLINE pieceIx #-} | 54 | {-# INLINE pieceIx #-} |
39 | 55 | ||
56 | blockIx :: Block -> BlockIx | ||
57 | blockIx = BlockIx <$> blkPiece <*> blkOffset <*> B.length . blkData | ||
58 | |||
40 | blockRange :: (Num a, Integral a) => Int -> Block -> (a, a) | 59 | blockRange :: (Num a, Integral a) => Int -> Block -> (a, a) |
41 | blockRange pieceSize blk = (offset, offset + len) | 60 | blockRange pieceSize blk = (offset, offset + len) |
42 | where | 61 | where |
diff --git a/src/Network/BitTorrent/Tracker.hs b/src/Network/BitTorrent/Tracker.hs index 4275e5fe..643aca16 100644 --- a/src/Network/BitTorrent/Tracker.hs +++ b/src/Network/BitTorrent/Tracker.hs | |||
@@ -8,6 +8,7 @@ | |||
8 | -- | 8 | -- |
9 | {-# OPTIONS -fno-warn-orphans #-} | 9 | {-# OPTIONS -fno-warn-orphans #-} |
10 | {-# LANGUAGE OverloadedStrings #-} | 10 | {-# LANGUAGE OverloadedStrings #-} |
11 | -- make higher level api | ||
11 | module Network.BitTorrent.Tracker | 12 | module Network.BitTorrent.Tracker |
12 | ( module Network.BitTorrent.Tracker.Scrape | 13 | ( module Network.BitTorrent.Tracker.Scrape |
13 | , Progress(..), TSession(..) | 14 | , Progress(..), TSession(..) |