summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Exchange/Extension.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Exchange/Extension.hs')
-rw-r--r--src/Network/BitTorrent/Exchange/Extension.hs67
1 files changed, 36 insertions, 31 deletions
diff --git a/src/Network/BitTorrent/Exchange/Extension.hs b/src/Network/BitTorrent/Exchange/Extension.hs
index a4d72f96..e81cdb87 100644
--- a/src/Network/BitTorrent/Exchange/Extension.hs
+++ b/src/Network/BitTorrent/Exchange/Extension.hs
@@ -12,54 +12,59 @@
12-- 12--
13module Network.BitTorrent.Exchange.Extension 13module Network.BitTorrent.Exchange.Extension
14 ( -- * Capabilities 14 ( -- * Capabilities
15 Capabilities 15 Caps
16 , ppCaps, defaultCaps
17 , enabledCaps
18 16
19 -- * Extensions 17 -- * Extensions
20 , Extension(..) 18 , Extension(..)
21 , defaultExtensions, ppExtension
22 , encodeExts, decodeExts
23 ) where 19 ) where
24 20
25import Data.Bits 21import Data.Bits
22import Data.Default
23import Data.Monoid
26import Data.Word 24import Data.Word
27import Text.PrettyPrint 25import Text.PrettyPrint
26import Text.PrettyPrint.Class
28 27
28class (Enum a, Bounded a) => Capability a where
29 capMask :: a -> Word64
30 capRequires :: a -> Word64
29 31
30type Capabilities = Word64 32newtype Caps a = Caps Word64
31 33
32ppCaps :: Capabilities -> Doc 34instance (Pretty a, Capability a) => Pretty (Caps a) where
33ppCaps = hcat . punctuate ", " . map ppExtension . decodeExts 35 pretty = hcat . punctuate ", " . map pretty . toList
34 36
35defaultCaps :: Capabilities 37instance Default (Caps a) where
36defaultCaps = 0 38 def = Caps 0
39 {-# INLINE def #-}
37 40
38enabledCaps :: Capabilities -- ^ of the client. 41instance Monoid (Caps a) where
39 -> Capabilities -- ^ of the peer. 42 mempty = Caps (-1)
40 -> Capabilities -- ^ should be considered as enabled. 43 {-# INLINE mempty #-}
41enabledCaps = (.&.)
42 44
45 mappend (Caps a) (Caps b) = Caps (a .&. b)
46 {-# INLINE mappend #-}
43 47
44data Extension = ExtDHT -- ^ BEP 5 48allowed :: Capability a => a -> Caps a -> Bool
45 | ExtFast -- ^ BEP 6 49allowed = member
46 deriving (Show, Eq, Ord, Enum, Bounded) 50fromList :: Capability a => [a] -> Caps a
51fromList = Caps . foldr (.&.) 0 . map capMask
47 52
48ppExtension :: Extension -> Doc 53toList :: Capability a => Caps a -> [a]
49ppExtension ExtDHT = "DHT" 54toList (Caps rb) = filter (testMask rb . capMask) [minBound..maxBound]
50ppExtension ExtFast = "Fast Extension" 55 where
56 testMask bits x = bits .&. x > 0
51 57
52extensionMask :: Extension -> Word64
53extensionMask ExtDHT = 0x01
54extensionMask ExtFast = 0x04
55 58
56defaultExtensions :: [Extension] 59data Extension
57defaultExtensions = [] 60 = ExtDHT -- ^ BEP 5
61 | ExtFast -- ^ BEP 6
62 deriving (Show, Eq, Ord, Enum, Bounded)
58 63
59encodeExts :: [Extension] -> Capabilities 64instance Pretty Extension where
60encodeExts = foldr (.&.) 0 . map extensionMask 65 pretty ExtDHT = "DHT"
66 pretty ExtFast = "Fast Extension"
61 67
62decodeExts :: Capabilities -> [Extension] 68instance Capability Extension where
63decodeExts rb = filter (testMask rb . extensionMask) [minBound..maxBound] 69 capMask ExtDHT = 0x01
64 where 70 capMask ExtFast = 0x04
65 testMask bits x = bits .&. x > 0