+{-
+ - Copyright (C) 2015-2016 Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
+ -
+ - This file is part of FuncTorrent.
+ -
+ - FuncTorrent is free software; you can redistribute it and/or modify
+ - it under the terms of the GNU General Public License as published by
+ - the Free Software Foundation; either version 3 of the License, or
+ - (at your option) any later version.
+ -
+ - FuncTorrent is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU General Public License for more details.
+ -
+ - You should have received a copy of the GNU General Public License
+ - along with FuncTorrent; if not, see <http://www.gnu.org/licenses/>
+ -}
+
{-# LANGUAGE OverloadedStrings #-}
module FuncTorrent.Bencode
(BVal(..)
- , bValToBList
- , bValToBytestr
- , bValToInfoDict
, bValToInteger
, bstrToString
, decode
import Data.ByteString (ByteString, length, concat)
import Data.ByteString.Char8 (unpack, pack)
+import Data.Char (isLetter, isAscii)
import Data.Map.Strict (Map, fromList, toList)
import Text.ParserCombinators.Parsec
import qualified Text.Parsec.ByteString as ParsecBS
| Bdict (Map String BVal)
deriving (Ord, Eq, Show)
+genNonEmptyString :: Gen String
+genNonEmptyString = arbitrary `suchThat` (\s -> ((s /= "") &&
+ (all isAscii s) &&
+ (all isLetter s)))
+
instance Arbitrary ByteString where
arbitrary = pack <$> arbitrary
bval n = oneof [ Bint <$> arbitrary
, Bstr <$> arbitrary
, Blist <$> vectorOf n (bval (n `div` 4))
- , do keys <- vectorOf n arbitrary
+ , do keys <- vectorOf n genNonEmptyString
vals <- vectorOf n (bval (n `div` 4))
return $ Bdict $ fromList $ zip keys vals ]
bValToBytestr (Bstr bs) = Just bs
bValToBytestr _ = Nothing
-bValToBList :: BVal -> Maybe [BVal]
-bValToBList (Blist lst) = Just lst
-bValToBList _ = Nothing
-
-bValToInfoDict :: BVal -> Maybe (Map String BVal)
-bValToInfoDict (Bdict dict) = Just dict
-bValToInfoDict _ = Nothing
-
bstrToString :: BVal -> Maybe String
bstrToString bval = unpack <$> bValToBytestr bval
-- Right (fromList [("publisher",Bstr "bob"),("publisher-webpage",Bstr "www.example.com"),("publisher.location",Bstr "home")])
bencDict :: ParsecBS.Parser (Map String BVal)
bencDict = between (char 'd') (char 'e') $ fromList <$> many kvpair
- where kvpair = do k <- bencStr
+ where kvpair = do k <- bdictKey
v <- bencVal
- return (unpack k, v)
+ return (k, v)
+ bdictKey = do
+ ds <- many1 digit <* char ':'
+ s <- count (read ds) anyChar
+ return s
+
bencVal :: ParsecBS.Parser BVal
bencVal = Bstr <$> bencStr <|>
where
kvlist :: [ByteString]
kvlist = [encPair kv | kv <- toList d]
- encPair (k, v) = concat [encode . Bstr . pack $ k, encode v]
+ encPair (k, v) = concat [encode (Bstr (pack k)), encode v]