From 0411025eb72ce0f5e5484b770d126779221b7c34 Mon Sep 17 00:00:00 2001 From: Sam T Date: Wed, 24 Apr 2013 00:49:02 +0400 Subject: ~ Add some utility functions. --- network-bittorrent.cabal | 1 + src/Data/Torrent.hs | 25 +++++++++++++++++++++-- src/Network/BitTorrent/PeerWire/Block.hs | 35 ++++++++++++++++++++++++-------- 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 , HTTP >= 4000.2 , cryptohash + , filepath == 1.* extensions: PatternGuards 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 @@ module Data.Torrent ( module Data.Torrent.InfoHash , Torrent(..), ContentInfo(..), FileInfo(..) - , contenLength, pieceCount + , contentLength, pieceCount + , contentLayout , fromFile ) where @@ -24,7 +25,7 @@ import Data.Text (Text) import Data.BEncode import Data.Torrent.InfoHash import Network.URI - +import System.FilePath type Time = Text @@ -229,6 +230,26 @@ contentLength MultiFile { ciFiles = tfs } = sum (map fiLength tfs) pieceCount :: ContentInfo -> Int pieceCount ti = contentLength ti `sizeInBase` ciPieceLength ti +-- | File layout specifies the order and the size of each file in the storage. +-- Note that order of files is highly important since we coalesce all +-- the files in the given order to get the linear block address space. +-- +type Layout = [(FilePath, Int)] + +fileInfo :: ContentInfo -> [FileInfo] +fileInfo (SingleFile { ciName = name, ciLength = len, ciMD5sum = md5 }) + = [FileInfo len md5 [name]] +fileInfo (MultiFile { ciFiles = fs }) = fs + +fileLayout :: FileInfo -> (FilePath, Int) +fileLayout (FileInfo { fiLength = len, fiPath = name }) = (path, fromIntegral len) + where -- WARN use utf8 encoding in name + path = joinPath (map BC.unpack name) + + +contentLayout :: ContentInfo -> Layout +contentLayout = map fileLayout . fileInfo + -- | Read and decode a .torrent file. 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 @@ module Network.BitTorrent.PeerWire.Block ( BlockIx(..), Block(..) + , BlockLIx, PieceLIx , defaultBlockSize - , blockRange, ixRange, pieceIx - , isPiece + , pieceIx, blockIx + , blockRange, ixRange, isPiece ) where +import Control.Applicative import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.Int +type BlockLIx = Int +type PieceLIx = Int + data BlockIx = BlockIx { - ixPiece :: {-# UNPACK #-} !Int -- ^ Zero-based piece index. - , ixOffset :: {-# UNPACK #-} !Int -- ^ Zero-based byte offset within the piece. - , ixLength :: {-# UNPACK #-} !Int -- ^ Block size starting from offset. + -- ^ Zero-based piece index. + ixPiece :: {-# UNPACK #-} !PieceLIx + + -- ^ Zero-based byte offset within the piece. + , ixOffset :: {-# UNPACK #-} !Int + + -- ^ Block size starting from offset. + , ixLength :: {-# UNPACK #-} !Int } deriving (Show, Eq) + data Block = Block { - blkPiece :: Int -- ^ Zero-based piece index. - , blkOffset :: Int -- ^ Zero-based byte offset within the piece. - , blkData :: ByteString -- ^ Payload. + -- ^ Zero-based piece index. + blkPiece :: PieceLIx + + -- ^ Zero-based byte offset within the piece. + , blkOffset :: Int + + -- ^ Payload. + , blkData :: ByteString } deriving (Show, Eq) @@ -37,6 +53,9 @@ pieceIx :: Int -> Int -> BlockIx pieceIx i = BlockIx i 0 {-# INLINE pieceIx #-} +blockIx :: Block -> BlockIx +blockIx = BlockIx <$> blkPiece <*> blkOffset <*> B.length . blkData + blockRange :: (Num a, Integral a) => Int -> Block -> (a, a) blockRange pieceSize blk = (offset, offset + len) 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 @@ -- {-# OPTIONS -fno-warn-orphans #-} {-# LANGUAGE OverloadedStrings #-} +-- make higher level api module Network.BitTorrent.Tracker ( module Network.BitTorrent.Tracker.Scrape , Progress(..), TSession(..) -- cgit v1.2.3