summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--network-bittorrent.cabal1
-rw-r--r--src/Data/Torrent.hs25
-rw-r--r--src/Network/BitTorrent/PeerWire/Block.hs35
-rw-r--r--src/Network/BitTorrent/Tracker.hs1
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 @@
11module Data.Torrent 11module 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)
24import Data.BEncode 25import Data.BEncode
25import Data.Torrent.InfoHash 26import Data.Torrent.InfoHash
26import Network.URI 27import Network.URI
27 28import System.FilePath
28 29
29type Time = Text 30type Time = Text
30 31
@@ -229,6 +230,26 @@ contentLength MultiFile { ciFiles = tfs } = sum (map fiLength tfs)
229pieceCount :: ContentInfo -> Int 230pieceCount :: ContentInfo -> Int
230pieceCount ti = contentLength ti `sizeInBase` ciPieceLength ti 231pieceCount 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--
237type Layout = [(FilePath, Int)]
238
239fileInfo :: ContentInfo -> [FileInfo]
240fileInfo (SingleFile { ciName = name, ciLength = len, ciMD5sum = md5 })
241 = [FileInfo len md5 [name]]
242fileInfo (MultiFile { ciFiles = fs }) = fs
243
244fileLayout :: FileInfo -> (FilePath, Int)
245fileLayout (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
250contentLayout :: ContentInfo -> Layout
251contentLayout = map fileLayout . fileInfo
252
232 253
233-- | Read and decode a .torrent file. 254-- | Read and decode a .torrent file.
234fromFile :: FilePath -> IO (Result Torrent) 255fromFile :: 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 @@
1module Network.BitTorrent.PeerWire.Block 1module 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
9import Control.Applicative
8import Data.ByteString (ByteString) 10import Data.ByteString (ByteString)
9import qualified Data.ByteString as B 11import qualified Data.ByteString as B
10import Data.Int 12import Data.Int
11 13
14type BlockLIx = Int
15type PieceLIx = Int
16
12 17
13data BlockIx = BlockIx { 18data 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
19data Block = Block { 30data 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
37pieceIx i = BlockIx i 0 53pieceIx i = BlockIx i 0
38{-# INLINE pieceIx #-} 54{-# INLINE pieceIx #-}
39 55
56blockIx :: Block -> BlockIx
57blockIx = BlockIx <$> blkPiece <*> blkOffset <*> B.length . blkData
58
40blockRange :: (Num a, Integral a) => Int -> Block -> (a, a) 59blockRange :: (Num a, Integral a) => Int -> Block -> (a, a)
41blockRange pieceSize blk = (offset, offset + len) 60blockRange 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
11module Network.BitTorrent.Tracker 12module Network.BitTorrent.Tracker
12 ( module Network.BitTorrent.Tracker.Scrape 13 ( module Network.BitTorrent.Tracker.Scrape
13 , Progress(..), TSession(..) 14 , Progress(..), TSession(..)