24 | 24 |
deriving (Eq, Show, Read)
|
25 | 25 |
|
26 | 26 |
decode :: ByteString -> Maybe (Value, ByteString)
|
27 | |
decode bs = go
|
28 | |
where go = case BS.uncons bs of
|
29 | |
Just (108, rs) -> decodeList
|
30 | |
Just (100, rs) -> decodeDict
|
31 | |
Just (105, rs) -> decodeInt
|
32 | |
Just (102, rs) -> decodeFloat
|
| 27 |
decode = go
|
| 28 |
where go bs = case BS.uncons bs of
|
| 29 |
Just (108, rs) -> decodeList [] rs
|
| 30 |
Just (100, rs) -> decodeDict [] rs
|
| 31 |
Just (105, rs) -> decodeInt rs
|
| 32 |
Just (102, rs) -> decodeFloat rs
|
33 | 33 |
Just (i , rs)
|
34 | |
| isDigit (fromIntegral i) ->
|
35 | |
let (is, rs') = BS.break (== 58) rs
|
36 | |
len = toNum (toDigit i) is
|
37 | |
(str, rs'') = BS.splitAt len (BS.tail rs')
|
38 | |
in Just (String (BS.toStrict str), rs'')
|
| 34 |
| isDigit (fromIntegral i) -> do
|
| 35 |
(s, rs) <- decodeBS bs
|
| 36 |
return (String s, rs)
|
39 | 37 |
| otherwise -> Nothing
|
| 38 |
decodeList ls bs = case BS.uncons bs of
|
| 39 |
Just (101, rs) -> Just (List ls, rs)
|
| 40 |
_ -> do
|
| 41 |
(x, rs) <- go bs
|
| 42 |
decodeList (ls ++ [x]) rs
|
| 43 |
decodeDict ls bs = case BS.uncons bs of
|
| 44 |
Just (101, rs) -> Just (Dict (M.fromList ls), rs)
|
| 45 |
_ -> do
|
| 46 |
(k, rs) <- decodeBS bs
|
| 47 |
(v, rs') <- go rs
|
| 48 |
decodeDict ((k,v):ls) rs'
|
| 49 |
decodeInt bs =
|
| 50 |
let (is, rs) = BS.break (== 101) bs
|
| 51 |
in return (Integer (toNum 0 is), BS.tail rs)
|
| 52 |
decodeFloat bs =
|
| 53 |
let (fs, rs) = BS.splitAt 4 bs
|
| 54 |
in return (Float 0.0, BS.tail rs)
|
| 55 |
decodeBS bs =
|
| 56 |
let (is, rs') = BS.break (== 58) bs
|
| 57 |
len = toNum 0 is
|
| 58 |
(str, rs'') = BS.splitAt len (BS.tail rs')
|
| 59 |
in Just (BS.toStrict str, rs'')
|
| 60 |
|
| 61 |
asDict :: Value -> Maybe (Map B.ByteString Value)
|
| 62 |
asDict (Dict ds) = Just ds
|
| 63 |
asDict _ = Nothing
|
| 64 |
|
| 65 |
asList :: Value -> Maybe [Value]
|
| 66 |
asList (List ls) = Just ls
|
| 67 |
asList _ = Nothing
|
| 68 |
|
| 69 |
asFloat :: Value -> Maybe Float
|
| 70 |
asFloat (Float f) = Just f
|
| 71 |
asFloat (Integer i) = Just (fromIntegral i)
|
| 72 |
asFloat _ = Nothing
|
| 73 |
|
| 74 |
lookup :: B.ByteString -> Value -> Maybe Value
|
| 75 |
lookup k (Dict ds) = M.lookup k ds
|
| 76 |
lookup _ _ = Nothing
|
40 | 77 |
|
41 | 78 |
isDigit :: Word8 -> Bool
|
42 | 79 |
isDigit n = n >= 48 && n <= 57
|
|
46 | 83 |
|
47 | 84 |
toNum :: Int64 -> ByteString -> Int64
|
48 | 85 |
toNum n (BS.uncons->Just(b, bs)) =
|
49 | |
toNum (n * 10 + fromIntegral b) bs
|
| 86 |
toNum (n * 10 + toDigit b) bs
|
50 | 87 |
toNum n _ = n
|
51 | |
|
52 | 88 |
|
53 | 89 |
encode :: Value -> ByteString
|
54 | 90 |
encode = BL.toLazyByteString . go
|