summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Data/Bitfield.hs39
-rw-r--r--src/Network/BitTorrent/PeerWire/Message.hs8
-rw-r--r--src/Network/BitTorrent/Tracker.hs2
3 files changed, 32 insertions, 17 deletions
diff --git a/src/Data/Bitfield.hs b/src/Data/Bitfield.hs
index ee0570e7..56365bf7 100644
--- a/src/Data/Bitfield.hs
+++ b/src/Data/Bitfield.hs
@@ -17,6 +17,7 @@ module Data.Bitfield
17 17
18 -- * Construction 18 -- * Construction
19 , haveAll, haveNone, have 19 , haveAll, haveNone, have
20 , adjustSize
20 21
21 -- * Query 22 -- * Query
22 , Data.Bitfield.null 23 , Data.Bitfield.null
@@ -31,8 +32,7 @@ module Data.Bitfield
31 , difference 32 , difference
32 33
33 -- * Serialization 34 -- * Serialization
34 , getBitfield, putBitfield 35 , fromBitmap, toBitmap
35 , bitfieldByteCount
36 36
37#if defined (TESTING) 37#if defined (TESTING)
38 -- * Debug 38 -- * Debug
@@ -42,15 +42,18 @@ module Data.Bitfield
42 42
43import Control.Monad 43import Control.Monad
44import Control.Monad.ST 44import Control.Monad.ST
45import Data.ByteString (ByteString)
46import qualified Data.ByteString as B
47import qualified Data.ByteString.Lazy as Lazy
45import Data.Vector.Unboxed (Vector) 48import Data.Vector.Unboxed (Vector)
46import qualified Data.Vector.Unboxed as V 49import qualified Data.Vector.Unboxed as V
47import qualified Data.Vector.Unboxed.Mutable as VM 50import qualified Data.Vector.Unboxed.Mutable as VM
48import Data.IntervalSet (IntSet) 51import Data.IntervalSet (IntSet)
49import qualified Data.IntervalSet as S 52import qualified Data.IntervalSet as S
53import qualified Data.IntervalSet.ByteString as S
50import Data.List (foldl') 54import Data.List (foldl')
51import Data.Monoid 55import Data.Monoid
52import Data.Ratio 56import Data.Ratio
53import Data.Serialize
54import Network.BitTorrent.PeerWire.Block 57import Network.BitTorrent.PeerWire.Block
55 58
56 59
@@ -97,6 +100,11 @@ have ix Bitfield {..}
97 | 0 <= ix && ix < bfSize = Bitfield bfSize (S.insert ix bfSet) 100 | 0 <= ix && ix < bfSize = Bitfield bfSize (S.insert ix bfSet)
98 | otherwise = Bitfield bfSize bfSet 101 | otherwise = Bitfield bfSize bfSet
99 102
103-- | Assign new size to bitfield. FIXME Normally, size should be only
104-- decreased, otherwise exception raised.
105adjustSize :: PieceCount -> Bitfield -> Bitfield
106adjustSize s Bitfield {..} = Bitfield s bfSet
107
100{----------------------------------------------------------------------- 108{-----------------------------------------------------------------------
101 Query 109 Query
102-----------------------------------------------------------------------} 110-----------------------------------------------------------------------}
@@ -200,17 +208,22 @@ unions = foldl' union (haveNone 0)
200 Serialization 208 Serialization
201-----------------------------------------------------------------------} 209-----------------------------------------------------------------------}
202 210
203-- | 211-- | Unpack 'Bitfield' from tightly packed bit array. Note resulting
204getBitfield :: Int -> Get Bitfield 212-- size might be more than real bitfield size, use 'adjustSize'.
205getBitfield = error "getBitfield" 213fromBitmap :: ByteString -> Bitfield
206 214fromBitmap bs = Bitfield {
207-- | 215 bfSize = B.length bs * 8
208putBitfield :: Bitfield -> Put 216 , bfSet = S.fromByteString bs
209putBitfield = error "putBitfield" 217 }
218{-# INLINE fromBitmap #-}
210 219
211-- | 220-- | Pack a 'Bitfield' to tightly packed bit array.
212bitfieldByteCount :: Bitfield -> Int 221toBitmap :: Bitfield -> Lazy.ByteString
213bitfieldByteCount = error "bitfieldByteCount" 222toBitmap Bitfield {..} = Lazy.fromChunks [intsetBM, alignment]
223 where
224 byteSize = bfSize `div` 8 + if bfSize `mod` 8 == 0 then 0 else 1
225 alignment = B.replicate (byteSize - B.length intsetBM) 0
226 intsetBM = S.toByteString bfSet
214 227
215{----------------------------------------------------------------------- 228{-----------------------------------------------------------------------
216 Debug 229 Debug
diff --git a/src/Network/BitTorrent/PeerWire/Message.hs b/src/Network/BitTorrent/PeerWire/Message.hs
index 6515fdf2..3895ed5f 100644
--- a/src/Network/BitTorrent/PeerWire/Message.hs
+++ b/src/Network/BitTorrent/PeerWire/Message.hs
@@ -7,6 +7,7 @@ module Network.BitTorrent.PeerWire.Message
7 7
8import Control.Applicative 8import Control.Applicative
9import qualified Data.ByteString as B 9import qualified Data.ByteString as B
10import qualified Data.ByteString.Lazy as Lazy
10import Data.Serialize 11import Data.Serialize
11import Text.PrettyPrint 12import Text.PrettyPrint
12import Network 13import Network
@@ -91,7 +92,7 @@ instance Serialize Message where
91 0x02 -> return Interested 92 0x02 -> return Interested
92 0x03 -> return NotInterested 93 0x03 -> return NotInterested
93 0x04 -> Have <$> getInt 94 0x04 -> Have <$> getInt
94 0x05 -> Bitfield <$> getBitfield (pred len) 95 0x05 -> (Bitfield . fromBitmap) <$> getByteString (pred len)
95 0x06 -> Request <$> get 96 0x06 -> Request <$> get
96 0x07 -> Piece <$> getBlock (len - 9) 97 0x07 -> Piece <$> getBlock (len - 9)
97 0x08 -> Cancel <$> get 98 0x08 -> Cancel <$> get
@@ -118,8 +119,9 @@ instance Serialize Message where
118 put Interested = putInt 1 >> putWord8 0x02 119 put Interested = putInt 1 >> putWord8 0x02
119 put NotInterested = putInt 1 >> putWord8 0x03 120 put NotInterested = putInt 1 >> putWord8 0x03
120 put (Have i) = putInt 5 >> putWord8 0x04 >> putInt i 121 put (Have i) = putInt 5 >> putWord8 0x04 >> putInt i
121 put (Bitfield b) = putInt l >> putWord8 0x05 >> putBitfield b 122 put (Bitfield bf) = putInt l >> putWord8 0x05 >> putLazyByteString b
122 where l = succ (bitfieldByteCount b) 123 where b = toBitmap bf
124 l = succ (fromIntegral (Lazy.length b))
123 {-# INLINE l #-} 125 {-# INLINE l #-}
124 put (Request blk) = putInt 13 >> putWord8 0x06 >> put blk 126 put (Request blk) = putInt 13 >> putWord8 0x06 >> put blk
125 put (Piece blk) = putInt l >> putWord8 0x07 >> putBlock 127 put (Piece blk) = putInt l >> putWord8 0x07 >> putBlock
diff --git a/src/Network/BitTorrent/Tracker.hs b/src/Network/BitTorrent/Tracker.hs
index 2e599002..aaa08f3c 100644
--- a/src/Network/BitTorrent/Tracker.hs
+++ b/src/Network/BitTorrent/Tracker.hs
@@ -145,7 +145,7 @@ data TSession = TSession {
145newSession :: Progress -> Int -> [PeerAddr] -> IO TSession 145newSession :: Progress -> Int -> [PeerAddr] -> IO TSession
146newSession pr i ps = TSession <$> newTVarIO pr 146newSession pr i ps = TSession <$> newTVarIO pr
147 <*> newIORef i 147 <*> newIORef i
148 <*> newTVarIO psx 148 <*> newTVarIO ps
149 149
150getPeerList :: TSession -> IO [PeerAddr] 150getPeerList :: TSession -> IO [PeerAddr]
151getPeerList = readTVarIO . sePeers 151getPeerList = readTVarIO . sePeers