summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-10-17 09:49:42 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-10-17 09:49:42 +0400
commit2f5450c06b70b5d9b319d651af5934aa4e5f97c4 (patch)
treebe1e87fb94445a8ac1c4b6ce231c31e000a5d2ee /src/Network
parent3d61d2d9b12bc41853aa388048da96460b34605d (diff)
Update library to use bencoding == 0.4.*
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/KRPC.hs22
-rw-r--r--src/Network/KRPC/Protocol.hs81
-rw-r--r--src/Network/KRPC/Scheme.hs22
3 files changed, 68 insertions, 57 deletions
diff --git a/src/Network/KRPC.hs b/src/Network/KRPC.hs
index 0428669b..27363515 100644
--- a/src/Network/KRPC.hs
+++ b/src/Network/KRPC.hs
@@ -120,7 +120,9 @@ import Control.Applicative
120import Control.Exception 120import Control.Exception
121import Control.Monad.Trans.Control 121import Control.Monad.Trans.Control
122import Control.Monad.IO.Class 122import Control.Monad.IO.Class
123import Data.BEncode 123import Data.BEncode as BE
124import Data.BEncode.BDict as BE
125import Data.BEncode.Types as BE
124import Data.ByteString.Char8 as BC 126import Data.ByteString.Char8 as BC
125import Data.List as L 127import Data.List as L
126import Data.Map as M 128import Data.Map as M
@@ -226,20 +228,24 @@ method = Method
226{-# INLINE method #-} 228{-# INLINE method #-}
227 229
228lookupKey :: ParamName -> BDict -> Result BValue 230lookupKey :: ParamName -> BDict -> Result BValue
229lookupKey x = maybe (Left ("not found key " ++ BC.unpack x)) Right . M.lookup x 231lookupKey x = maybe (Left ("not found key " ++ BC.unpack x)) Right . BE.lookup x
230 232
231extractArgs :: [ParamName] -> BDict -> Result BValue 233extractArgs :: [ParamName] -> BDict -> Result BValue
232extractArgs [] d = Right $ if M.null d then BList [] else BDict d 234extractArgs [] d = Right $ if BE.null d then BList [] else BDict d
233extractArgs [x] d = lookupKey x d 235extractArgs [x] d = lookupKey x d
234extractArgs xs d = BList <$> mapM (`lookupKey` d) xs 236extractArgs xs d = BList <$> mapM (`lookupKey` d) xs
235{-# INLINE extractArgs #-} 237{-# INLINE extractArgs #-}
236 238
237injectVals :: [ParamName] -> BValue -> [(ParamName, BValue)] 239zipBDict :: [BKey] -> [BValue] -> BDict
238injectVals [] (BList []) = [] 240zipBDict (k : ks) (v : vs) = Cons k v (zipBDict ks vs)
239injectVals [] (BDict d ) = M.toList d 241zipBDict _ _ = Nil
242
243injectVals :: [ParamName] -> BValue -> BDict
244injectVals [] (BList []) = BE.empty
245injectVals [] (BDict d ) = d
240injectVals [] be = invalidParamList [] be 246injectVals [] be = invalidParamList [] be
241injectVals [p] arg = [(p, arg)] 247injectVals [p] arg = BE.singleton p arg
242injectVals ps (BList as) = L.zip ps as 248injectVals ps (BList as) = zipBDict ps as
243injectVals ps be = invalidParamList ps be 249injectVals ps be = invalidParamList ps be
244{-# INLINE injectVals #-} 250{-# INLINE injectVals #-}
245 251
diff --git a/src/Network/KRPC/Protocol.hs b/src/Network/KRPC/Protocol.hs
index 1e7bd7c3..67a4057d 100644
--- a/src/Network/KRPC/Protocol.hs
+++ b/src/Network/KRPC/Protocol.hs
@@ -17,6 +17,7 @@
17{-# LANGUAGE MultiParamTypeClasses #-} 17{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE FunctionalDependencies #-} 18{-# LANGUAGE FunctionalDependencies #-}
19{-# LANGUAGE DefaultSignatures #-} 19{-# LANGUAGE DefaultSignatures #-}
20{-# LANGUAGE DeriveDataTypeable #-}
20module Network.KRPC.Protocol 21module Network.KRPC.Protocol
21 ( -- * Error 22 ( -- * Error
22 KError(..) 23 KError(..)
@@ -46,9 +47,7 @@ module Network.KRPC.Protocol
46 47
47 -- * Re-exports 48 -- * Re-exports
48 , encode 49 , encode
49 , encoded
50 , decode 50 , decode
51 , decoded
52 , toBEncode 51 , toBEncode
53 , fromBEncode 52 , fromBEncode
54 ) where 53 ) where
@@ -59,11 +58,14 @@ import Control.Monad
59import Control.Monad.IO.Class 58import Control.Monad.IO.Class
60import Control.Monad.Trans.Control 59import Control.Monad.Trans.Control
61 60
62import Data.BEncode 61import Data.BEncode as BE
62import Data.BEncode.BDict as BE
63import Data.BEncode.Types as BE
63import Data.ByteString as B 64import Data.ByteString as B
64import Data.ByteString.Char8 as BC 65import Data.ByteString.Char8 as BC
65import qualified Data.ByteString.Lazy as LB 66import qualified Data.ByteString.Lazy as LB
66import Data.Map as M 67import Data.Map as M
68import Data.Typeable
67 69
68import Network.Socket hiding (recvFrom) 70import Network.Socket hiding (recvFrom)
69import Network.Socket.ByteString 71import Network.Socket.ByteString
@@ -89,20 +91,21 @@ data KError
89 91
90 -- | Occur when client trying to call method server don't know. 92 -- | Occur when client trying to call method server don't know.
91 | MethodUnknown { errorMessage :: ByteString } 93 | MethodUnknown { errorMessage :: ByteString }
92 deriving (Show, Read, Eq, Ord) 94 deriving (Show, Read, Eq, Ord, Typeable)
93 95
94instance BEncode KError where 96instance BEncode KError where
95 {-# SPECIALIZE instance BEncode KError #-} 97 {-# SPECIALIZE instance BEncode KError #-}
96 {-# INLINE toBEncode #-} 98 {-# INLINE toBEncode #-}
97 toBEncode e = fromAscAssocs -- WARN: keep keys sorted 99 toBEncode e = toDict $
98 [ "e" --> (errorCode e, errorMessage e) 100 "e" .=! (errorCode e, errorMessage e)
99 , "y" --> ("e" :: ByteString) 101 .: "y" .=! ("e" :: ByteString)
100 ] 102 .: endDict
101 103
102 {-# INLINE fromBEncode #-} 104 {-# INLINE fromBEncode #-}
103 fromBEncode (BDict d) 105 fromBEncode be @ (BDict d)
104 | M.lookup "y" d == Just (BString "e") 106 | BE.lookup "y" d == Just (BString "e")
105 = uncurry mkKError <$> d >-- "e" 107 = (`fromDict` be) $ do
108 uncurry mkKError <$>! "e"
106 109
107 fromBEncode _ = decodingError "KError" 110 fromBEncode _ = decodingError "KError"
108 111
@@ -140,33 +143,30 @@ type ParamName = ByteString
140-- 143--
141data KQuery = KQuery { 144data KQuery = KQuery {
142 queryMethod :: MethodName 145 queryMethod :: MethodName
143 , queryArgs :: Map ParamName BValue 146 , queryArgs :: BDict
144 } deriving (Show, Read, Eq, Ord) 147 } deriving (Show, Read, Eq, Ord, Typeable)
145 148
146instance BEncode KQuery where 149instance BEncode KQuery where
147 {-# SPECIALIZE instance BEncode KQuery #-} 150 {-# SPECIALIZE instance BEncode KQuery #-}
148 {-# INLINE toBEncode #-} 151 {-# INLINE toBEncode #-}
149 toBEncode (KQuery m args) = fromAscAssocs -- WARN: keep keys sorted 152 toBEncode (KQuery m args) = toDict $
150 [ "a" --> BDict args 153 "a" .=! BDict args
151 , "q" --> m 154 .: "q" .=! m
152 , "y" --> ("q" :: ByteString) 155 .: "y" .=! ("q" :: ByteString)
153 ] 156 .: endDict
154 157
155 {-# INLINE fromBEncode #-} 158 {-# INLINE fromBEncode #-}
156 fromBEncode (BDict d) 159 fromBEncode bv @ (BDict d)
157 | M.lookup "y" d == Just (BString "q") = 160 | BE.lookup "y" d == Just (BString "q") = (`fromDict` bv) $ do
158 KQuery <$> d >-- "q" 161 KQuery <$>! "q" <*>! "a"
159 <*> d >-- "a"
160 162
161 fromBEncode _ = decodingError "KQuery" 163 fromBEncode _ = decodingError "KQuery"
162 164
163kquery :: MethodName -> [(ParamName, BValue)] -> KQuery 165kquery :: MethodName -> BDict -> KQuery
164kquery name args = KQuery name (M.fromList args) 166kquery = KQuery
165{-# INLINE kquery #-} 167{-# INLINE kquery #-}
166 168
167 169
168
169
170type ValName = ByteString 170type ValName = ByteString
171 171
172-- | KResponse used to signal that callee successufully process a 172-- | KResponse used to signal that callee successufully process a
@@ -179,25 +179,24 @@ type ValName = ByteString
179-- > { "y" : "r", "r" : [<val1>, <val2>, ...] } 179-- > { "y" : "r", "r" : [<val1>, <val2>, ...] }
180-- 180--
181newtype KResponse = KResponse { respVals :: BDict } 181newtype KResponse = KResponse { respVals :: BDict }
182 deriving (Show, Read, Eq, Ord) 182 deriving (Show, Read, Eq, Ord, Typeable)
183 183
184instance BEncode KResponse where 184instance BEncode KResponse where
185 {-# INLINE toBEncode #-} 185 {-# INLINE toBEncode #-}
186 toBEncode (KResponse vals) = fromAscAssocs -- WARN: keep keys sorted 186 toBEncode (KResponse vals) = toDict $
187 [ "r" --> vals 187 "r" .=! vals
188 , "y" --> ("r" :: ByteString) 188 .: "y" .=! ("r" :: ByteString)
189 ] 189 .: endDict
190 190
191 {-# INLINE fromBEncode #-} 191 {-# INLINE fromBEncode #-}
192 fromBEncode (BDict d) 192 fromBEncode bv @ (BDict d)
193 | M.lookup "y" d == Just (BString "r") = 193 | BE.lookup "y" d == Just (BString "r") = (`fromDict` bv) $ do
194 KResponse <$> d >-- "r" 194 KResponse <$>! "r"
195 195
196 fromBEncode _ = decodingError "KDict" 196 fromBEncode _ = decodingError "KDict"
197 197
198 198kresponse :: BDict -> KResponse
199kresponse :: [(ValName, BValue)] -> KResponse 199kresponse = KResponse
200kresponse = KResponse . M.fromList
201{-# INLINE kresponse #-} 200{-# INLINE kresponse #-}
202 201
203type KRemoteAddr = SockAddr 202type KRemoteAddr = SockAddr
@@ -219,15 +218,15 @@ maxMsgSize = 64 * 1024 -- bench: max UDP MTU
219{-# INLINE maxMsgSize #-} 218{-# INLINE maxMsgSize #-}
220 219
221sendMessage :: BEncode msg => msg -> KRemoteAddr -> KRemote -> IO () 220sendMessage :: BEncode msg => msg -> KRemoteAddr -> KRemote -> IO ()
222sendMessage msg addr sock = sendManyTo sock (LB.toChunks (encoded msg)) addr 221sendMessage msg addr sock = sendManyTo sock (LB.toChunks (encode msg)) addr
223{-# INLINE sendMessage #-} 222{-# INLINE sendMessage #-}
224 223
225recvResponse :: KRemote -> IO (Either KError KResponse) 224recvResponse :: KRemote -> IO (Either KError KResponse)
226recvResponse sock = do 225recvResponse sock = do
227 (raw, _) <- recvFrom sock maxMsgSize 226 (raw, _) <- recvFrom sock maxMsgSize
228 return $ case decoded raw of 227 return $ case decode raw of
229 Right resp -> Right resp 228 Right resp -> Right resp
230 Left decE -> Left $ case decoded raw of 229 Left decE -> Left $ case decode raw of
231 Right kerror -> kerror 230 Right kerror -> kerror
232 _ -> ProtocolError (BC.pack decE) 231 _ -> ProtocolError (BC.pack decE)
233 232
@@ -252,7 +251,7 @@ remoteServer servAddr action = bracket (liftIO bindServ) (liftIO . sClose) loop
252 reply <- handleMsg bs addr 251 reply <- handleMsg bs addr
253 liftIO $ sendMessage reply addr sock 252 liftIO $ sendMessage reply addr sock
254 where 253 where
255 handleMsg bs addr = case decoded bs of 254 handleMsg bs addr = case decode bs of
256 Right query -> (either toBEncode toBEncode <$> action addr query) 255 Right query -> (either toBEncode toBEncode <$> action addr query)
257 `Lifted.catch` (return . toBEncode . serverError) 256 `Lifted.catch` (return . toBEncode . serverError)
258 Left decodeE -> return $ toBEncode (ProtocolError (BC.pack decodeE)) 257 Left decodeE -> return $ toBEncode (ProtocolError (BC.pack decodeE))
diff --git a/src/Network/KRPC/Scheme.hs b/src/Network/KRPC/Scheme.hs
index 15f0b677..59d2c627 100644
--- a/src/Network/KRPC/Scheme.hs
+++ b/src/Network/KRPC/Scheme.hs
@@ -21,6 +21,9 @@ module Network.KRPC.Scheme
21 ) where 21 ) where
22 22
23import Control.Applicative 23import Control.Applicative
24import Data.BEncode as BE
25import Data.BEncode.BDict as BS
26import Data.BEncode.Types as BS
24import Data.Map as M 27import Data.Map as M
25import Data.Set as S 28import Data.Set as S
26 29
@@ -45,19 +48,23 @@ class KMessage message scheme | message -> scheme where
45 48
46 49
47instance KMessage KError ErrorCode where 50instance KMessage KError ErrorCode where
48 {-# SPECIALIZE instance KMessage KError ErrorCode #-}
49 scheme = errorCode 51 scheme = errorCode
50 {-# INLINE scheme #-} 52 {-# INLINE scheme #-}
51 53
52
53data KQueryScheme = KQueryScheme { 54data KQueryScheme = KQueryScheme {
54 qscMethod :: MethodName 55 qscMethod :: MethodName
55 , qscParams :: Set ParamName 56 , qscParams :: Set ParamName
56 } deriving (Show, Read, Eq, Ord) 57 } deriving (Show, Read, Eq, Ord)
57 58
59bdictKeys :: BDict -> [BKey]
60bdictKeys (Cons k _ xs) = k : bdictKeys xs
61bdictKeys Nil = []
62
58instance KMessage KQuery KQueryScheme where 63instance KMessage KQuery KQueryScheme where
59 {-# SPECIALIZE instance KMessage KQuery KQueryScheme #-} 64 scheme q = KQueryScheme
60 scheme q = KQueryScheme (queryMethod q) (M.keysSet (queryArgs q)) 65 { qscMethod = queryMethod q
66 , qscParams = S.fromAscList $ bdictKeys $ queryArgs q
67 }
61 {-# INLINE scheme #-} 68 {-# INLINE scheme #-}
62 69
63methodQueryScheme :: Method a b -> KQueryScheme 70methodQueryScheme :: Method a b -> KQueryScheme
@@ -65,14 +72,13 @@ methodQueryScheme = KQueryScheme <$> methodName
65 <*> S.fromList . methodParams 72 <*> S.fromList . methodParams
66{-# INLINE methodQueryScheme #-} 73{-# INLINE methodQueryScheme #-}
67 74
68 75newtype KResponseScheme = KResponseScheme
69newtype KResponseScheme = KResponseScheme { 76 { rscVals :: Set ValName
70 rscVals :: Set ValName
71 } deriving (Show, Read, Eq, Ord) 77 } deriving (Show, Read, Eq, Ord)
72 78
73instance KMessage KResponse KResponseScheme where 79instance KMessage KResponse KResponseScheme where
74 {-# SPECIALIZE instance KMessage KResponse KResponseScheme #-} 80 {-# SPECIALIZE instance KMessage KResponse KResponseScheme #-}
75 scheme = KResponseScheme . keysSet . respVals 81 scheme = KResponseScheme . S.fromAscList . bdictKeys . respVals
76 {-# INLINE scheme #-} 82 {-# INLINE scheme #-}
77 83
78methodRespScheme :: Method a b -> KResponseScheme 84methodRespScheme :: Method a b -> KResponseScheme