diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-06-12 07:34:34 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-06-12 07:34:34 +0400 |
commit | 5c3c114e0e84339f88892e08010bd8b1408431d1 (patch) | |
tree | 70763a0fa0fc3c9f7ecbf1242b479a55b07cf1e2 /src/Data/Torrent.hs | |
parent | 8b005c4eb0f58db974c342efe0821240f39a6331 (diff) |
~ Minor fixes.
* Annotate all required fields as strict. These are always used and
there is no reason to keep them lazy.
* Augment user errors with location.
Diffstat (limited to 'src/Data/Torrent.hs')
-rw-r--r-- | src/Data/Torrent.hs | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index 068e9cb6..ad57403e 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -21,6 +21,7 @@ | |||
21 | {-# LANGUAGE FlexibleInstances #-} | 21 | {-# LANGUAGE FlexibleInstances #-} |
22 | {-# LANGUAGE OverloadedStrings #-} | 22 | {-# LANGUAGE OverloadedStrings #-} |
23 | {-# LANGUAGE RecordWildCards #-} | 23 | {-# LANGUAGE RecordWildCards #-} |
24 | {-# LANGUAGE BangPatterns #-} | ||
24 | -- TODO refine interface | 25 | -- TODO refine interface |
25 | module Data.Torrent | 26 | module Data.Torrent |
26 | ( -- * Torrent | 27 | ( -- * Torrent |
@@ -83,14 +84,14 @@ type Time = Text | |||
83 | -- TODO more convenient form of torrent info. | 84 | -- TODO more convenient form of torrent info. |
84 | -- | Metainfo about particular torrent. | 85 | -- | Metainfo about particular torrent. |
85 | data Torrent = Torrent { | 86 | data Torrent = Torrent { |
86 | tInfoHash :: InfoHash | 87 | tInfoHash :: !InfoHash |
87 | -- ^ SHA1 hash of the 'TorrentInfo' of the 'Torrent'. | 88 | -- ^ SHA1 hash of the 'TorrentInfo' of the 'Torrent'. |
88 | 89 | ||
89 | , tAnnounce :: URI | 90 | , tAnnounce :: !URI |
90 | -- ^ The URL of the tracker. | 91 | -- ^ The URL of the tracker. |
91 | 92 | ||
92 | -- NOTE: out of lexicographic order! | 93 | -- NOTE: out of lexicographic order! |
93 | , tInfo :: ContentInfo | 94 | , tInfo :: !ContentInfo |
94 | -- ^ Info about each content file. | 95 | -- ^ Info about each content file. |
95 | 96 | ||
96 | , tAnnounceList :: Maybe [[URI]] | 97 | , tAnnounceList :: Maybe [[URI]] |
@@ -112,9 +113,9 @@ data Torrent = Torrent { | |||
112 | -- the info dictionary in the .torrent metafile. | 113 | -- the info dictionary in the .torrent metafile. |
113 | 114 | ||
114 | , tPublisher :: Maybe URI | 115 | , tPublisher :: Maybe URI |
115 | -- ^ Containing the RSA public key of the publisher of the torrent. | 116 | -- ^ Containing the RSA public key of the publisher of the |
116 | -- Private counterpart of this key that has the authority to allow | 117 | -- torrent. Private counterpart of this key that has the |
117 | -- new peers onto the swarm. | 118 | -- authority to allow new peers onto the swarm. |
118 | 119 | ||
119 | , tPublisherURL :: Maybe URI | 120 | , tPublisherURL :: Maybe URI |
120 | , tSignature :: Maybe ByteString | 121 | , tSignature :: Maybe ByteString |
@@ -144,22 +145,22 @@ simpleTorrent announce info = torrent announce info | |||
144 | -- | Info part of the .torrent file contain info about each content file. | 145 | -- | Info part of the .torrent file contain info about each content file. |
145 | data ContentInfo = | 146 | data ContentInfo = |
146 | SingleFile { | 147 | SingleFile { |
147 | ciLength :: Integer | 148 | ciLength :: !Integer |
148 | -- ^ Length of the file in bytes. | 149 | -- ^ Length of the file in bytes. |
149 | 150 | ||
150 | , ciMD5sum :: Maybe ByteString | 151 | , ciMD5sum :: Maybe ByteString |
151 | -- ^ 32 character long MD5 sum of the file. | 152 | -- ^ 32 character long MD5 sum of the file. |
152 | -- Used by third-party tools, not by bittorrent protocol itself. | 153 | -- Used by third-party tools, not by bittorrent protocol itself. |
153 | 154 | ||
154 | , ciName :: ByteString | 155 | , ciName :: !ByteString |
155 | -- ^ Suggested name of the file single file. | 156 | -- ^ Suggested name of the file single file. |
156 | 157 | ||
157 | 158 | ||
158 | 159 | ||
159 | , ciPieceLength :: Int | 160 | , ciPieceLength :: !Int |
160 | -- ^ Number of bytes in each piece. | 161 | -- ^ Number of bytes in each piece. |
161 | 162 | ||
162 | , ciPieces :: ByteString | 163 | , ciPieces :: !ByteString |
163 | -- ^ Concatenation of all 20-byte SHA1 hash values. | 164 | -- ^ Concatenation of all 20-byte SHA1 hash values. |
164 | 165 | ||
165 | , ciPrivate :: Maybe Bool | 166 | , ciPrivate :: Maybe Bool |
@@ -171,28 +172,28 @@ data ContentInfo = | |||
171 | } | 172 | } |
172 | 173 | ||
173 | | MultiFile { | 174 | | MultiFile { |
174 | ciFiles :: [FileInfo] | 175 | ciFiles :: ![FileInfo] |
175 | -- ^ List of the all files that torrent contains. | 176 | -- ^ List of the all files that torrent contains. |
176 | 177 | ||
177 | , ciName :: ByteString | 178 | , ciName :: !ByteString |
178 | -- | The file path of the directory in which to store all the files. | 179 | -- | The file path of the directory in which to store all the files. |
179 | 180 | ||
180 | , ciPieceLength :: Int | 181 | , ciPieceLength :: !Int |
181 | , ciPieces :: ByteString | 182 | , ciPieces :: !ByteString |
182 | , ciPrivate :: Maybe Bool | 183 | , ciPrivate :: Maybe Bool |
183 | } deriving (Show, Read, Eq) | 184 | } deriving (Show, Read, Eq) |
184 | 185 | ||
185 | 186 | ||
186 | -- | Contain info about one single file. | 187 | -- | Contain info about one single file. |
187 | data FileInfo = FileInfo { | 188 | data FileInfo = FileInfo { |
188 | fiLength :: Integer | 189 | fiLength :: !Integer |
189 | -- ^ Length of the file in bytes. | 190 | -- ^ Length of the file in bytes. |
190 | 191 | ||
191 | , fiMD5sum :: Maybe ByteString | 192 | , fiMD5sum :: Maybe ByteString |
192 | -- ^ 32 character long MD5 sum of the file. | 193 | -- ^ 32 character long MD5 sum of the file. |
193 | -- Used by third-party tools, not by bittorrent protocol itself. | 194 | -- Used by third-party tools, not by bittorrent protocol itself. |
194 | 195 | ||
195 | , fiPath :: [ByteString] | 196 | , fiPath :: ![ByteString] |
196 | -- ^ One or more string elements that together represent the | 197 | -- ^ One or more string elements that together represent the |
197 | -- path and filename. Each element in the list corresponds to | 198 | -- path and filename. Each element in the list corresponds to |
198 | -- either a directory name or (in the case of the last | 199 | -- either a directory name or (in the case of the last |
@@ -323,16 +324,18 @@ blockCount :: Int -- ^ Block size. | |||
323 | -> Int -- ^ Number of blocks. | 324 | -> Int -- ^ Number of blocks. |
324 | blockCount blkSize ci = contentLength ci `sizeInBase` blkSize | 325 | blockCount blkSize ci = contentLength ci `sizeInBase` blkSize |
325 | 326 | ||
326 | -- | File layout specifies the order and the size of each file in the storage. | 327 | -- | File layout specifies the order and the size of each file in the |
327 | -- Note that order of files is highly important since we coalesce all | 328 | -- storage. Note that order of files is highly important since we |
328 | -- the files in the given order to get the linear block address space. | 329 | -- coalesce all the files in the given order to get the linear block |
330 | -- address space. | ||
329 | -- | 331 | -- |
330 | type Layout = [(FilePath, Int)] | 332 | type Layout = [(FilePath, Int)] |
331 | 333 | ||
332 | -- | Extract files layout from torrent info with the given root path. | 334 | -- | Extract files layout from torrent info with the given root path. |
333 | contentLayout :: FilePath -- ^ Root path for the all torrent files. | 335 | contentLayout :: FilePath -- ^ Root path for the all torrent files. |
334 | -> ContentInfo -- ^ Torrent content information. | 336 | -> ContentInfo -- ^ Torrent content information. |
335 | -> Layout -- ^ The all file paths prefixed with the given root. | 337 | -> Layout -- ^ The all file paths prefixed with the |
338 | -- given root. | ||
336 | contentLayout rootPath = filesLayout | 339 | contentLayout rootPath = filesLayout |
337 | where | 340 | where |
338 | filesLayout (SingleFile { ciName = name, ciLength = len }) | 341 | filesLayout (SingleFile { ciName = name, ciLength = len }) |
@@ -356,7 +359,11 @@ isMultiFile _ = False | |||
356 | 359 | ||
357 | -- | Read and decode a .torrent file. | 360 | -- | Read and decode a .torrent file. |
358 | fromFile :: FilePath -> IO Torrent | 361 | fromFile :: FilePath -> IO Torrent |
359 | fromFile = B.readFile >=> either (throwIO . userError) return . decoded | 362 | fromFile path = do |
363 | contents <- B.readFile path | ||
364 | case decoded contents of | ||
365 | Right !t -> return t | ||
366 | Left msg -> throwIO $ userError $ msg ++ " while reading torrent" | ||
360 | 367 | ||
361 | {----------------------------------------------------------------------- | 368 | {----------------------------------------------------------------------- |
362 | Info hash | 369 | Info hash |