diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-01 11:04:42 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-01 11:04:42 +0400 |
commit | 09fbfdacd0b160459baf7827c0d7342bd2ca5983 (patch) | |
tree | 41d12dd6a2c67a0f4ef0c747969521d32deaee26 /src/Data | |
parent | 0853bc857b370ed5f7a453a18a7b03b28cd3b410 (diff) |
Add documentation to Layout module
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/Torrent.hs | 1 | ||||
-rw-r--r-- | src/Data/Torrent/Block.hs | 33 | ||||
-rw-r--r-- | src/Data/Torrent/Layout.hs | 47 | ||||
-rw-r--r-- | src/Data/Torrent/Piece.hs | 2 | ||||
-rw-r--r-- | src/Data/Torrent/Tree.hs | 16 |
5 files changed, 58 insertions, 41 deletions
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index 90ec0cc4..36b9de50 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -23,7 +23,6 @@ | |||
23 | {-# LANGUAGE DeriveDataTypeable #-} | 23 | {-# LANGUAGE DeriveDataTypeable #-} |
24 | {-# LANGUAGE TemplateHaskell #-} | 24 | {-# LANGUAGE TemplateHaskell #-} |
25 | {-# OPTIONS -fno-warn-orphans #-} | 25 | {-# OPTIONS -fno-warn-orphans #-} |
26 | -- TODO refine interface | ||
27 | module Data.Torrent | 26 | module Data.Torrent |
28 | ( -- * Info dictionary | 27 | ( -- * Info dictionary |
29 | InfoDict (..) | 28 | InfoDict (..) |
diff --git a/src/Data/Torrent/Block.hs b/src/Data/Torrent/Block.hs index ca3bef45..17907a39 100644 --- a/src/Data/Torrent/Block.hs +++ b/src/Data/Torrent/Block.hs | |||
@@ -7,12 +7,14 @@ | |||
7 | -- | 7 | -- |
8 | -- TODO | 8 | -- TODO |
9 | -- | 9 | -- |
10 | {-# LANGUAGE TemplateHaskell #-} | 10 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
11 | {-# LANGUAGE TemplateHaskell #-} | ||
11 | module Data.Torrent.Block | 12 | module Data.Torrent.Block |
12 | ( -- * Block attributes | 13 | ( -- * Block attributes |
13 | BlockLIx | 14 | BlockLIx |
14 | , PieceLIx | 15 | , PieceLIx |
15 | , BlockSize (..) | 16 | , BlockSize |
17 | , defaultTransferSize | ||
16 | 18 | ||
17 | -- * Block index | 19 | -- * Block index |
18 | , BlockIx(..) | 20 | , BlockIx(..) |
@@ -50,17 +52,14 @@ import Text.PrettyPrint | |||
50 | -- Block attributes | 52 | -- Block attributes |
51 | -----------------------------------------------------------------------} | 53 | -----------------------------------------------------------------------} |
52 | 54 | ||
53 | newtype BlockSize = BlockSize { unBlockSize :: Int } | 55 | type BlockSize = Int |
54 | deriving (Show, Eq, Num, ToJSON, FromJSON) | ||
55 | |||
56 | -- | Widely used semi-official block size. | ||
57 | instance Default BlockSize where | ||
58 | def = 16 * 1024 | ||
59 | {-# INLINE def #-} | ||
60 | |||
61 | type BlockLIx = Int | 56 | type BlockLIx = Int |
62 | type PieceLIx = Int | 57 | type PieceLIx = Int |
63 | 58 | ||
59 | -- | Widely used semi-official block size. | ||
60 | defaultTransferSize :: BlockSize | ||
61 | defaultTransferSize = 16 * 1024 | ||
62 | |||
64 | {----------------------------------------------------------------------- | 63 | {----------------------------------------------------------------------- |
65 | Block Index | 64 | Block Index |
66 | -----------------------------------------------------------------------} | 65 | -----------------------------------------------------------------------} |
@@ -98,33 +97,33 @@ instance Serialize BlockIx where | |||
98 | {-# SPECIALIZE instance Serialize BlockIx #-} | 97 | {-# SPECIALIZE instance Serialize BlockIx #-} |
99 | get = BlockIx <$> getInt | 98 | get = BlockIx <$> getInt |
100 | <*> getInt | 99 | <*> getInt |
101 | <*> (BlockSize <$> getInt) | 100 | <*> getInt |
102 | {-# INLINE get #-} | 101 | {-# INLINE get #-} |
103 | 102 | ||
104 | put BlockIx {..} = do | 103 | put BlockIx {..} = do |
105 | putInt ixPiece | 104 | putInt ixPiece |
106 | putInt ixOffset | 105 | putInt ixOffset |
107 | putInt (unBlockSize ixLength) | 106 | putInt ixLength |
108 | {-# INLINE put #-} | 107 | {-# INLINE put #-} |
109 | 108 | ||
110 | instance Binary BlockIx where | 109 | instance Binary BlockIx where |
111 | {-# SPECIALIZE instance Binary BlockIx #-} | 110 | {-# SPECIALIZE instance Binary BlockIx #-} |
112 | get = BlockIx <$> getIntB | 111 | get = BlockIx <$> getIntB |
113 | <*> getIntB | 112 | <*> getIntB |
114 | <*> (BlockSize <$> getIntB) | 113 | <*> getIntB |
115 | {-# INLINE get #-} | 114 | {-# INLINE get #-} |
116 | 115 | ||
117 | put BlockIx {..} = do | 116 | put BlockIx {..} = do |
118 | putIntB ixPiece | 117 | putIntB ixPiece |
119 | putIntB ixOffset | 118 | putIntB ixOffset |
120 | putIntB (unBlockSize ixLength) | 119 | putIntB ixLength |
121 | 120 | ||
122 | -- | Format block index in human readable form. | 121 | -- | Format block index in human readable form. |
123 | ppBlockIx :: BlockIx -> Doc | 122 | ppBlockIx :: BlockIx -> Doc |
124 | ppBlockIx BlockIx {..} = | 123 | ppBlockIx BlockIx {..} = |
125 | "piece = " <> int ixPiece <> "," <+> | 124 | "piece = " <> int ixPiece <> "," <+> |
126 | "offset = " <> int ixOffset <> "," <+> | 125 | "offset = " <> int ixOffset <> "," <+> |
127 | "length = " <> int (unBlockSize ixLength) | 126 | "length = " <> int ixLength |
128 | 127 | ||
129 | {----------------------------------------------------------------------- | 128 | {----------------------------------------------------------------------- |
130 | Block | 129 | Block |
@@ -158,7 +157,7 @@ isPiece pieceSize (Block i offset bs) = | |||
158 | {-# INLINE isPiece #-} | 157 | {-# INLINE isPiece #-} |
159 | 158 | ||
160 | pieceIx :: Int -> Int -> BlockIx | 159 | pieceIx :: Int -> Int -> BlockIx |
161 | pieceIx i = BlockIx i 0 . BlockSize | 160 | pieceIx i = BlockIx i 0 |
162 | {-# INLINE pieceIx #-} | 161 | {-# INLINE pieceIx #-} |
163 | 162 | ||
164 | blockIx :: Block Lazy.ByteString -> BlockIx | 163 | blockIx :: Block Lazy.ByteString -> BlockIx |
@@ -177,5 +176,5 @@ ixRange pieceSize i = (offset, offset + len) | |||
177 | where | 176 | where |
178 | offset = fromIntegral pieceSize * fromIntegral (ixPiece i) | 177 | offset = fromIntegral pieceSize * fromIntegral (ixPiece i) |
179 | + fromIntegral (ixOffset i) | 178 | + fromIntegral (ixOffset i) |
180 | len = fromIntegral (unBlockSize (ixLength i)) | 179 | len = fromIntegral (ixLength i) |
181 | {-# INLINE ixRange #-} | 180 | {-# INLINE ixRange #-} |
diff --git a/src/Data/Torrent/Layout.hs b/src/Data/Torrent/Layout.hs index 409426be..6f0668f2 100644 --- a/src/Data/Torrent/Layout.hs +++ b/src/Data/Torrent/Layout.hs | |||
@@ -5,6 +5,8 @@ | |||
5 | -- Stability : experimental | 5 | -- Stability : experimental |
6 | -- Portability : portable | 6 | -- Portability : portable |
7 | -- | 7 | -- |
8 | -- | ||
9 | -- | ||
8 | {-# LANGUAGE BangPatterns #-} | 10 | {-# LANGUAGE BangPatterns #-} |
9 | {-# LANGUAGE FlexibleInstances #-} | 11 | {-# LANGUAGE FlexibleInstances #-} |
10 | {-# LANGUAGE StandaloneDeriving #-} | 12 | {-# LANGUAGE StandaloneDeriving #-} |
@@ -13,25 +15,33 @@ | |||
13 | {-# LANGUAGE TemplateHaskell #-} | 15 | {-# LANGUAGE TemplateHaskell #-} |
14 | {-# OPTIONS -fno-warn-orphans #-} | 16 | {-# OPTIONS -fno-warn-orphans #-} |
15 | module Data.Torrent.Layout | 17 | module Data.Torrent.Layout |
16 | ( -- * File attribytes | 18 | ( -- * File attributes |
17 | FileOffset | 19 | FileOffset |
18 | , FileSize | 20 | , FileSize |
19 | 21 | ||
20 | -- * Single file info | 22 | -- * Single file info |
21 | , FileInfo (..) | 23 | , FileInfo (..) |
24 | |||
25 | -- ** Lens | ||
22 | , fileLength | 26 | , fileLength |
23 | , filePath | 27 | , filePath |
24 | , fileMD5Sum | 28 | , fileMD5Sum |
25 | 29 | ||
26 | -- * File layout | 30 | -- * File layout |
27 | , LayoutInfo (..) | 31 | , LayoutInfo (..) |
32 | |||
33 | -- ** Lens | ||
28 | , singleFile | 34 | , singleFile |
29 | , multiFile | 35 | , multiFile |
30 | , rootDirName | 36 | , rootDirName |
37 | |||
38 | -- ** Predicates | ||
31 | , isSingleFile | 39 | , isSingleFile |
32 | , isMultiFile | 40 | , isMultiFile |
33 | , fileNumber | 41 | |
42 | -- ** Folds | ||
34 | , contentLength | 43 | , contentLength |
44 | , fileCount | ||
35 | , blockCount | 45 | , blockCount |
36 | 46 | ||
37 | -- * Flat file layout | 47 | -- * Flat file layout |
@@ -60,11 +70,14 @@ import Data.Typeable | |||
60 | import System.FilePath | 70 | import System.FilePath |
61 | import System.Posix.Types | 71 | import System.Posix.Types |
62 | 72 | ||
73 | import Data.Torrent.Block | ||
74 | |||
63 | 75 | ||
64 | {----------------------------------------------------------------------- | 76 | {----------------------------------------------------------------------- |
65 | -- File attribytes | 77 | -- File attribytes |
66 | -----------------------------------------------------------------------} | 78 | -----------------------------------------------------------------------} |
67 | 79 | ||
80 | -- | Size of a file in bytes. | ||
68 | type FileSize = FileOffset | 81 | type FileSize = FileOffset |
69 | 82 | ||
70 | deriving instance FromJSON FileOffset | 83 | deriving instance FromJSON FileOffset |
@@ -75,7 +88,7 @@ deriving instance BEncode FileOffset | |||
75 | -- File info both either from info dict or file list | 88 | -- File info both either from info dict or file list |
76 | -----------------------------------------------------------------------} | 89 | -----------------------------------------------------------------------} |
77 | 90 | ||
78 | -- | Contain info about one single file. | 91 | -- | Contain metainfo about one single file. |
79 | data FileInfo a = FileInfo { | 92 | data FileInfo a = FileInfo { |
80 | fiLength :: {-# UNPACK #-} !FileSize | 93 | fiLength :: {-# UNPACK #-} !FileSize |
81 | -- ^ Length of the file in bytes. | 94 | -- ^ Length of the file in bytes. |
@@ -87,9 +100,9 @@ data FileInfo a = FileInfo { | |||
87 | 100 | ||
88 | , fiName :: !a | 101 | , fiName :: !a |
89 | -- ^ One or more string elements that together represent the | 102 | -- ^ One or more string elements that together represent the |
90 | -- path and filename. Each element in the list corresponds to | 103 | -- path and filename. Each element in the list corresponds to |
91 | -- either a directory name or (in the case of the last | 104 | -- either a directory name or (in the case of the last element) |
92 | -- element) the filename. For example, the file: | 105 | -- the filename. For example, the file: |
93 | -- | 106 | -- |
94 | -- > "dir1/dir2/file.ext" | 107 | -- > "dir1/dir2/file.ext" |
95 | -- | 108 | -- |
@@ -152,9 +165,16 @@ instance BEncode (FileInfo ByteString) where | |||
152 | -- Original torrent file layout info | 165 | -- Original torrent file layout info |
153 | -----------------------------------------------------------------------} | 166 | -----------------------------------------------------------------------} |
154 | 167 | ||
168 | -- | Original (found in torrent file) layout info is either: | ||
169 | -- | ||
170 | -- * Single file with its /name/. | ||
171 | -- | ||
172 | -- * Multiple files with its relative file /paths/. | ||
173 | -- | ||
155 | data LayoutInfo | 174 | data LayoutInfo |
156 | = SingleFile | 175 | = SingleFile |
157 | { liFile :: !(FileInfo ByteString) | 176 | { -- | Single file info. |
177 | liFile :: !(FileInfo ByteString) | ||
158 | } | 178 | } |
159 | | MultiFile | 179 | | MultiFile |
160 | { -- | List of the all files that torrent contains. | 180 | { -- | List of the all files that torrent contains. |
@@ -212,16 +232,14 @@ contentLength :: LayoutInfo -> FileSize | |||
212 | contentLength SingleFile { liFile = FileInfo {..} } = fiLength | 232 | contentLength SingleFile { liFile = FileInfo {..} } = fiLength |
213 | contentLength MultiFile { liFiles = tfs } = sum (L.map fiLength tfs) | 233 | contentLength MultiFile { liFiles = tfs } = sum (L.map fiLength tfs) |
214 | 234 | ||
215 | -- | Get count of all files in torrent. | 235 | -- | Get number of all files in torrent. |
216 | fileNumber :: LayoutInfo -> Int | 236 | fileCount :: LayoutInfo -> Int |
217 | fileNumber SingleFile {..} = 1 | 237 | fileCount SingleFile {..} = 1 |
218 | fileNumber MultiFile {..} = L.length liFiles | 238 | fileCount MultiFile {..} = L.length liFiles |
219 | 239 | ||
220 | -- | Find number of blocks of the specified size. If torrent size is | 240 | -- | Find number of blocks of the specified size. If torrent size is |
221 | -- not a multiple of block size then the count is rounded up. | 241 | -- not a multiple of block size then the count is rounded up. |
222 | blockCount :: Int -- ^ Block size. | 242 | blockCount :: BlockSize -> LayoutInfo -> Int |
223 | -> LayoutInfo -- ^ Torrent content info. | ||
224 | -> Int -- ^ Number of blocks. | ||
225 | blockCount blkSize ci = contentLength ci `sizeInBase` blkSize | 243 | blockCount blkSize ci = contentLength ci `sizeInBase` blkSize |
226 | 244 | ||
227 | {----------------------------------------------------------------------- | 245 | {----------------------------------------------------------------------- |
@@ -249,6 +267,7 @@ flatLayout prefixPath MultiFile {..} = L.map mkPath liFiles | |||
249 | path = prefixPath </> BC.unpack liDirName | 267 | path = prefixPath </> BC.unpack liDirName |
250 | </> joinPath (L.map BC.unpack fiName) | 268 | </> joinPath (L.map BC.unpack fiName) |
251 | 269 | ||
270 | -- | Calculate offset of each file based on its length, incrementally. | ||
252 | accumOffsets :: Layout FileSize -> Layout FileOffset | 271 | accumOffsets :: Layout FileSize -> Layout FileOffset |
253 | accumOffsets = go 0 | 272 | accumOffsets = go 0 |
254 | where | 273 | where |
diff --git a/src/Data/Torrent/Piece.hs b/src/Data/Torrent/Piece.hs index 96624729..27bc4879 100644 --- a/src/Data/Torrent/Piece.hs +++ b/src/Data/Torrent/Piece.hs | |||
@@ -85,7 +85,7 @@ maxPieceSize = 4 * 1024 * 1024 | |||
85 | {-# INLINE maxPieceSize #-} | 85 | {-# INLINE maxPieceSize #-} |
86 | 86 | ||
87 | minPieceSize :: Int | 87 | minPieceSize :: Int |
88 | minPieceSize = unBlockSize def * 4 | 88 | minPieceSize = defaultTransferSize * 4 |
89 | {-# INLINE minPieceSize #-} | 89 | {-# INLINE minPieceSize #-} |
90 | 90 | ||
91 | -- | NOTE: Have max and min size constrained to wide used | 91 | -- | NOTE: Have max and min size constrained to wide used |
diff --git a/src/Data/Torrent/Tree.hs b/src/Data/Torrent/Tree.hs index e9a337a1..8c18041a 100644 --- a/src/Data/Torrent/Tree.hs +++ b/src/Data/Torrent/Tree.hs | |||
@@ -15,8 +15,8 @@ module Data.Torrent.Tree | |||
15 | , Data.Torrent.Tree.lookup | 15 | , Data.Torrent.Tree.lookup |
16 | , lookupDir | 16 | , lookupDir |
17 | 17 | ||
18 | , fileCount | 18 | , fileNumber |
19 | , dirCount | 19 | , dirNumber |
20 | ) where | 20 | ) where |
21 | 21 | ||
22 | import Control.Arrow | 22 | import Control.Arrow |
@@ -62,10 +62,10 @@ lookupDir ps d | |||
62 | File _ -> Nothing | 62 | File _ -> Nothing |
63 | Dir es -> Just $ M.toList es | 63 | Dir es -> Just $ M.toList es |
64 | 64 | ||
65 | fileCount :: DirTree a -> Sum Int | 65 | fileNumber :: DirTree a -> Sum Int |
66 | fileCount File {..} = Sum 1 | 66 | fileNumber File {..} = Sum 1 |
67 | fileCount Dir {..} = foldMap fileCount children | 67 | fileNumber Dir {..} = foldMap fileNumber children |
68 | 68 | ||
69 | dirCount :: DirTree a -> Sum Int | 69 | dirNumber :: DirTree a -> Sum Int |
70 | dirCount File {..} = Sum 0 | 70 | dirNumber File {..} = Sum 0 |
71 | dirCount Dir {..} = Sum 1 <> foldMap dirCount children | 71 | dirNumber Dir {..} = Sum 1 <> foldMap dirNumber children |