From 74f2cf6141d2a9aebe8bd5c7fdb5c116f38ef4a1 Mon Sep 17 00:00:00 2001 From: Sam Truzjan Date: Fri, 1 Nov 2013 12:56:27 +0400 Subject: Document Piece module --- src/Data/Torrent.hs | 9 ++++++++- src/Data/Torrent/Block.hs | 7 ++++++- src/Data/Torrent/Piece.hs | 48 +++++++++++++++++++++++++++++++---------------- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index 36b9de50..8d62b068 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs @@ -26,6 +26,8 @@ module Data.Torrent ( -- * Info dictionary InfoDict (..) + + -- ** Lenses , infohash , layoutInfo , pieceInfo @@ -33,6 +35,8 @@ module Data.Torrent -- * Torrent file , Torrent(..) + + -- ** Lenses , announce , announceList , comment @@ -44,11 +48,14 @@ module Data.Torrent , publisherURL , signature + -- * Construction , nullTorrent - -- * IO + -- * File paths , torrentExt , isTorrentPath + + -- * IO , fromFile , toFile ) where diff --git a/src/Data/Torrent/Block.hs b/src/Data/Torrent/Block.hs index affbfa78..cb50302c 100644 --- a/src/Data/Torrent/Block.hs +++ b/src/Data/Torrent/Block.hs @@ -53,9 +53,14 @@ import Text.PrettyPrint -----------------------------------------------------------------------} -- | Zero-based index of piece in torrent content. -type PieceIx = Int +type PieceIx = Int -- | Size of piece in bytes. Should be a power of 2. +-- +-- NOTE: Have max and min size constrained to wide used +-- semi-standard values. This bounds should be used to make decision +-- about piece size for new torrents. +-- type PieceSize = Int {----------------------------------------------------------------------- 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 PieceIx , PieceCount , PieceSize - , defaultPieceSize - , maxPieceSize , minPieceSize + , maxPieceSize + , defaultPieceSize -- * Piece data , Piece (..) @@ -28,10 +28,14 @@ module Data.Torrent.Piece -- * Piece control , PieceInfo (..) , ppPieceInfo + , pieceCount + + -- * Lens , pieceLength , pieceHashes + + -- * Validation , pieceHash - , pieceCount , checkPieceLazy -- * Internal @@ -64,6 +68,13 @@ import Data.Torrent.Block class Lint a where lint :: a -> Either String a +--class Validation a where +-- validate :: PieceInfo -> Piece a -> Bool + +{----------------------------------------------------------------------- +-- Piece attributes +-----------------------------------------------------------------------} + -- | Number of pieces in torrent or a part of torrent. type PieceCount = Int @@ -72,18 +83,17 @@ optimalPieceCount :: PieceCount optimalPieceCount = 1000 {-# INLINE optimalPieceCount #-} --- | NOTE: Have max and min size constrained to wide used --- semi-standard values. This bounds should be used to make decision --- about piece size for new torrents. --- -maxPieceSize :: Int -maxPieceSize = 4 * 1024 * 1024 -{-# INLINE maxPieceSize #-} - +-- | Piece size should not be less than this value. minPieceSize :: Int minPieceSize = defaultTransferSize * 4 {-# INLINE minPieceSize #-} +-- | To prevent transfer degradation piece size should not exceed this +-- value. +maxPieceSize :: Int +maxPieceSize = 4 * 1024 * 1024 +{-# INLINE maxPieceSize #-} + toPow2 :: Int -> Int toPow2 x = bit $ fromIntegral (leadingZeros (0 :: Int) - leadingZeros x) @@ -93,6 +103,10 @@ defaultPieceSize x = max minPieceSize $ min maxPieceSize $ toPow2 pc where pc = fromIntegral (x `div` fromIntegral optimalPieceCount) +{----------------------------------------------------------------------- +-- Piece data +-----------------------------------------------------------------------} + -- TODO check if pieceLength is power of 2 -- | Piece payload should be strict or lazy bytestring. data Piece a = Piece @@ -118,10 +132,14 @@ pieceSize Piece {..} = fromIntegral (BL.length pieceData) -- | Test if a block can be safely turned into a piece. isPiece :: PieceSize -> Block BL.ByteString -> Bool -isPiece pieceSize blk @ (Block i offset _) = - offset == 0 && blockSize blk == pieceSize && i >= 0 +isPiece pieceLen blk @ (Block i offset _) = + offset == 0 && blockSize blk == pieceLen && i >= 0 {-# INLINE isPiece #-} +{----------------------------------------------------------------------- +-- Piece control +-----------------------------------------------------------------------} + newtype HashArray = HashArray { unHashArray :: ByteString } deriving (Show, Read, Eq, BEncode) @@ -196,12 +214,10 @@ pieceHash PieceInfo {..} i = slice (hashsize * i) hashsize (unHashArray piPieceH pieceCount :: PieceInfo -> PieceCount pieceCount PieceInfo {..} = BS.length (unHashArray piPieceHashes) `quot` hashsize +-- | Test if this is last piece in torrent content. isLastPiece :: PieceInfo -> PieceIx -> Bool isLastPiece ci i = pieceCount ci == succ i -class Validation a where - validate :: PieceInfo -> Piece a -> Bool - -- | Validate piece with metainfo hash. checkPieceLazy :: PieceInfo -> Piece BL.ByteString -> Bool checkPieceLazy pinfo @ PieceInfo {..} Piece {..} -- cgit v1.2.3