module Data.Aeson.Micro.Parser where import Control.Exception as E import Control.Monad import Data.Char import Data.Word import qualified GHC.Foreign as GHC import GHC.IO.Encoding import System.IO.Unsafe import Text.Read (readMaybe) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS.Char8 decodeEscapedHex :: BS.ByteString -> Maybe Char decodeEscapedHex bs = do [0x5c,0x75,d1,d2,d3,d4] <- pure (BS.unpack bs) let cp = (0x10*((0x10*((0x10 * h2n d1) + h2n d2)) + h2n d3)) + h2n d4 guard (not (0xd800 <= cp && cp <= 0xdfff)) pure (chr cp) decodeEscapedHexSurr :: BS.ByteString -> Maybe Char decodeEscapedHexSurr bs = do [0x5c,0x75,h1,h2,h3,h4,0x5c,0x75,l1,l2,l3,l4] <- pure (BS.unpack bs) let hsurr = (0x10*((0x10*((0x10 * h2n h1) + h2n h2)) + h2n h3)) + h2n h4 lsurr = (0x10*((0x10*((0x10 * h2n l1) + h2n l2)) + h2n l3)) + h2n l4 guard ((0xd800 <= hsurr && hsurr <= 0xdbff) && (0xdc00 <= lsurr && lsurr <= 0xdfff)) let cp = 0x10000 + ((hsurr-0xd800)*0x400) + (lsurr-0xdc00) pure (chr cp) decodeNumber :: BS.ByteString -> Maybe Double decodeNumber = readMaybe . BS.Char8.unpack h2n :: Word8 -> Int h2n w | 0x30 <= w && w <= 0x39 = fromIntegral (w-0x30) | 0x41 <= w && w <= 0x46 = fromIntegral (w-0x37) | 0x61 <= w && w <= 0x66 = fromIntegral (w-0x57) | otherwise = undefined decodeEscaped :: BS.ByteString -> Maybe Char decodeEscaped bs = do [0x5c,c] <- pure (BS.unpack bs) case c of 0x22 -> pure '\x22' 0x5c -> pure '\x5c' 0x2f -> pure '\x2f' 0x62 -> pure '\x08' 0x66 -> pure '\x0c' 0x6e -> pure '\x0a' 0x72 -> pure '\x0d' 0x74 -> pure '\x09' _ -> Nothing decodeUnescaped :: BS.ByteString -> Maybe String decodeUnescaped = decodeString utf8 decodeString :: TextEncoding -> BS.ByteString -> Maybe String decodeString te bs = unsafePerformIO (decodeStringIO te bs) {-# NOINLINE decodeStringIO #-} decodeStringIO :: TextEncoding -> BS.ByteString -> IO (Maybe String) decodeStringIO te bs = cvtEx <$> try (BS.useAsCStringLen bs (GHC.peekCStringLen te)) where cvtEx :: Either IOException a -> Maybe a cvtEx = either (const Nothing) Just