module FuncTorrent.Bencode
(BVal(..)
, bValToBList
- , bValToBstr
+ , bValToBytestr
, bValToInfoDict
, bValToInteger
, bstrToString
import Data.ByteString (ByteString, length, concat)
import Data.ByteString.Char8 (unpack, pack)
import Data.Functor ((<$>))
-import Data.Map.Strict (Map, fromList, keys, (!))
+import Data.Map.Strict (Map, fromList, toList)
import Text.ParserCombinators.Parsec
import qualified Text.Parsec.ByteString as ParsecBS
bValToInteger (Bint x) = Just x
bValToInteger _ = Nothing
-bValToBstr :: BVal -> Maybe ByteString
-bValToBstr (Bstr bs) = Just bs
-bValToBstr _ = Nothing
+bValToBytestr :: BVal -> Maybe ByteString
+bValToBytestr (Bstr bs) = Just bs
+bValToBytestr _ = Nothing
bValToBList :: BVal -> Maybe [BVal]
bValToBList (Blist lst) = Just lst
bValToInfoDict _ = Nothing
bstrToString :: BVal -> Maybe String
-bstrToString bval = unpack <$> bValToBstr bval
+bstrToString bval = unpack <$> bValToBytestr bval
-- $setup
-- >>> import Data.Either
-- Right ""
--
bencStr :: ParsecBS.Parser ByteString
-bencStr = do _ <- spaces
- ds <- many1 digit <* char ':'
+bencStr = do ds <- many1 digit <* char ':'
s <- count (read ds) anyChar
return (pack s)
-- >>> isLeft $ parse bencInt "Bint" (pack "i002e")
-- True
bencInt :: ParsecBS.Parser Integer
-bencInt = do _ <- spaces
- ds <- between (char 'i') (char 'e') numbers
+bencInt = do ds <- between (char 'i') (char 'e') numbers
return (read ds)
where numbers = do d' <- char '-' <|> digit
ds' <- many digit
-- >>> parse bencList "Blist" (pack "l4:spam4:eggsli42eee")
-- Right [Bstr "spam",Bstr "eggs",Blist [Bint 42]]
bencList :: ParsecBS.Parser [BVal]
-bencList = do _ <- spaces
- between (char 'l') (char 'e') (many bencVal)
+bencList = between (char 'l') (char 'e') (many bencVal)
-- | parse dict
--
encode (Bdict d) = concat ["d", concat kvlist, "e"]
where
kvlist :: [ByteString]
- kvlist = [concat [encode . Bstr . pack $ k , encode (d ! k)] | k <- keys d]
+ kvlist = [encPair kv | kv <- toList d]
+ encPair (k, v) = concat [encode . Bstr . pack $ k, encode v]