-- | functions for uri encoding/decoding ByteStrings module URI.Encoder (enc, dec) where import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BC import qualified Data.Vector as DV import Data.Word -- | enc - uri encodes a bytestring enc :: BS.ByteString -> BS.ByteString enc b = BS.concatMap enc' b enc' :: Word8 -> BS.ByteString enc' f = DV.unsafeIndex th'' (fromIntegral f) unreserved :: Word8 -> Bool unreserved a = a == 45 || a == 46 ||a == 95 || a == 126 || (a >= 65 && a <= 90) || (a >= 97 && a <= 122) -- | dec - uri decodes a bytestring dec :: BS.ByteString -> BS.ByteString dec b | BS.null b = b | otherwise = BS.concat $ [head b'] ++ [(fx $ tail b')] where b' = BS.split 37 b fx :: [BS.ByteString] -> BS.ByteString fx (ff:fz) = BS.concat $ [BS.pack $ [ (x' * 16) + y' ], z] ++ [fx fz] where x = BS.head ff y = BS.head $ BS.drop 1 ff x' = if x > 57 then (if x > 70 then x - 87 else x - 55) else x - 48 y' = if y > 57 then (if y > 70 then y - 87 else y - 55) else y - 48 z = BS.drop 2 ff fx [] = BS.pack [] f'' = foldr (\c a -> BS.pack (if unreserved c then [c] else (37 : (if c < 16 then [48] else []) ++ th [c])) : a) [] [0..255] th' = DV.fromList [48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]; th'' = DV.fromList f'' th :: [Word8] -> [Word8] th [] = [] th (f:fs) | f >= 16 = [th' DV.! (fromIntegral r')] ++ th [f - (16 * r')] ++ th fs | otherwise = [th' DV.! (fromIntegral f)] ++ th fs where r' = f `div` 16