{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}

module System.AbstractFilePath.Data.ByteString.Short.Decode (decodeUtf16LE, decodeUtf16LEWith, decodeUtf16LE', decodeUtf16LE'', decodeUtf8, decodeUtf8With, decodeUtf8', strictDecode, lenientDecode, OnError, OnDecodeError, UnicodeException(..)) where

import Data.ByteString.Internal
    ( ByteString )
import Data.ByteString.Short
    ( ShortByteString, toShort )
import Data.Bits
    ( shiftL )
import Data.Typeable (Typeable)
import Data.Word
    ( Word16, Word8 )
import GHC.Word (Word8(..), Word16(..))
import Control.Exception
import qualified Data.ByteString.Short as BS
    ( index, length )
import GHC.IO
    ( unsafeDupablePerformIO )
import GHC.Base
import Control.DeepSeq (NFData, rnf)
import Numeric (showHex)
#if !MIN_VERSION_base(4,16,0)

word8ToWord#  :: Word# -> Word#
word16ToWord# :: Word# -> Word#
word8ToWord# :: Word# -> Word#
word8ToWord#  Word#
w = Word#
w
word16ToWord# :: Word# -> Word#
word16ToWord# Word#
w = Word#
w
{-# INLINE word16ToWord# #-}
{-# INLINE word8ToWord# #-}

#endif

unsafeChr16 :: Word16 -> Char
unsafeChr16 :: Word16 -> Char
unsafeChr16 (W16# Word#
w#) = Char# -> Char
C# (Int# -> Char#
chr# (Word# -> Int#
word2Int# (Word# -> Word#
word16ToWord# Word#
w#)))
{-# INLINE unsafeChr16 #-}

unsafeChr8 :: Word8 -> Char
unsafeChr8 :: Word8 -> Char
unsafeChr8 (W8# Word#
w#) = Char# -> Char
C# (Int# -> Char#
chr# (Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
w#)))
{-# INLINE unsafeChr8 #-}

-- | /O(n)/ Convert a 'ByteString' into a 'Stream Char', using UTF-8
-- encoding.
streamUtf8 :: OnDecodeError -> ShortByteString -> [Char]
streamUtf8 :: OnDecodeError -> ShortByteString -> [Char]
streamUtf8 OnDecodeError
onErr ShortByteString
bs = Int -> [Char]
go Int
0
    where
      l :: Int
l = ShortByteString -> Int
BS.length ShortByteString
bs
      go :: Int -> [Char]
go Int
i
          | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l = []
          | Word8 -> Bool
validate1_8 Word8
x1 = (Word8 -> Char
unsafeChr8 Word8
x1) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
          | Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l Bool -> Bool -> Bool
&& Word8 -> Word8 -> Bool
validate2_8 Word8
x1 Word8
x2 = (Word8 -> Word8 -> Char
chr2 Word8
x1 Word8
x2) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2)
          | Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l Bool -> Bool -> Bool
&& Word8 -> Word8 -> Word8 -> Bool
validate3_8 Word8
x1 Word8
x2 Word8
x3 = (Word8 -> Word8 -> Word8 -> Char
chr3 Word8
x1 Word8
x2 Word8
x3) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
3)
          | Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l Bool -> Bool -> Bool
&& Word8 -> Word8 -> Word8 -> Word8 -> Bool
validate4_8 Word8
x1 Word8
x2 Word8
x3 Word8
x4 = (Word8 -> Word8 -> Word8 -> Word8 -> Char
chr4 Word8
x1 Word8
x2 Word8
x3 Word8
x4) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4)
          | Bool
otherwise = [Char] -> [Char] -> OnDecodeError -> Maybe Word8 -> [Char]
decodeError [Char]
"streamUtf8" [Char]
"UTF-8" OnDecodeError
onErr (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
x1) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
          where
            x1 :: Word8
x1 = Int -> Word8
idx Int
i
            x2 :: Word8
x2 = Int -> Word8
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
            x3 :: Word8
x3 = Int -> Word8
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)
            x4 :: Word8
x4 = Int -> Word8
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)
            idx :: Int -> Word8
idx = ShortByteString -> Int -> Word8
BS.index ShortByteString
bs
{-# INLINE [0] streamUtf8 #-}

-- | /O(n)/ Convert a 'ShortByteString' into a 'Stream Char', using little
-- endian UTF-16 encoding.
streamUtf16LE :: OnDecodeError -> ShortByteString -> [Char]
streamUtf16LE :: OnDecodeError -> ShortByteString -> [Char]
streamUtf16LE OnDecodeError
onErr ShortByteString
bs = Int -> [Char]
go Int
0
    where
      l :: Int
l = ShortByteString -> Int
BS.length ShortByteString
bs
      {-# INLINE go #-}
      go :: Int -> [Char]
go Int
i
          | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l                         = []
          | Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l Bool -> Bool -> Bool
&& Word16 -> Bool
validate1_16 Word16
x1    = (Word16 -> Char
unsafeChr16 Word16
x1) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2)
          | Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l Bool -> Bool -> Bool
&& Word16 -> Word16 -> Bool
validate2_16 Word16
x1 Word16
x2 = (Word16 -> Word16 -> Char
chr2_16 Word16
x1 Word16
x2) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4)
          | Bool
otherwise = [Char] -> [Char] -> OnDecodeError -> Maybe Word8 -> [Char]
decodeError [Char]
"streamUtf16LE" [Char]
"UTF-16LE" OnDecodeError
onErr Maybe Word8
forall a. Maybe a
Nothing [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
          where
            x1 :: Word16
x1    = Int -> Word16
idx Int
i       Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ (Int -> Word16
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
            x2 :: Word16
x2    = Int -> Word16
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ (Int -> Word16
idx (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
            idx :: Int -> Word16
idx = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16) -> (Int -> Word8) -> Int -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Int -> Word8
BS.index ShortByteString
bs :: Int -> Word16
{-# INLINE [0] streamUtf16LE #-}

-- | Decode text from little endian UTF-16 encoding.
decodeUtf16LEWith :: OnDecodeError -> ShortByteString -> String
decodeUtf16LEWith :: OnDecodeError -> ShortByteString -> [Char]
decodeUtf16LEWith OnDecodeError
onErr ShortByteString
bs = OnDecodeError -> ShortByteString -> [Char]
streamUtf16LE OnDecodeError
onErr ShortByteString
bs
{-# INLINE decodeUtf16LEWith #-}

-- | Decode text from little endian UTF-16 encoding.
--
-- If the input contains any invalid little endian UTF-16 data, an
-- exception will be thrown.  For more control over the handling of
-- invalid data, use 'decodeUtf16LEWith'.
decodeUtf16LE :: ShortByteString -> String
decodeUtf16LE :: ShortByteString -> [Char]
decodeUtf16LE = OnDecodeError -> ShortByteString -> [Char]
decodeUtf16LEWith OnDecodeError
strictDecode
{-# INLINE decodeUtf16LE #-}

-- | Decode text from little endian UTF-16 encoding.
decodeUtf8With :: OnDecodeError -> ShortByteString -> String
decodeUtf8With :: OnDecodeError -> ShortByteString -> [Char]
decodeUtf8With OnDecodeError
onErr ShortByteString
bs = OnDecodeError -> ShortByteString -> [Char]
streamUtf8 OnDecodeError
onErr ShortByteString
bs
{-# INLINE decodeUtf8With #-}

-- | Decode text from little endian UTF-16 encoding.
--
-- If the input contains any invalid little endian UTF-16 data, an
-- exception will be thrown.  For more control over the handling of
-- invalid data, use 'decodeUtf16LEWith'.
decodeUtf8 :: ShortByteString -> String
decodeUtf8 :: ShortByteString -> [Char]
decodeUtf8 = OnDecodeError -> ShortByteString -> [Char]
decodeUtf8With OnDecodeError
strictDecode
{-# INLINE decodeUtf8 #-}


decodeError :: String -> String -> OnDecodeError -> Maybe Word8 -> String
decodeError :: [Char] -> [Char] -> OnDecodeError -> Maybe Word8 -> [Char]
decodeError [Char]
func [Char]
kind OnDecodeError
onErr Maybe Word8
mb =
    case OnDecodeError
onErr [Char]
desc Maybe Word8
mb of
      Maybe Char
Nothing -> []
      Just Char
c  -> [Char
c]
    where desc :: [Char]
desc = [Char]
"System.AbstractFilePath.Data.ByteString.Short.Decode." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
func [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": Invalid " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                 [Char]
kind [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" stream"


-- | Decode a 'ShortByteString' containing UTF-8 encoded text.
--
-- If the input contains any invalid UTF-8 data, the relevant
-- exception will be returned, otherwise the decoded text.
decodeUtf8' :: ShortByteString -> Either UnicodeException String
decodeUtf8' :: ShortByteString -> Either UnicodeException [Char]
decodeUtf8' = IO (Either UnicodeException [Char])
-> Either UnicodeException [Char]
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either UnicodeException [Char])
 -> Either UnicodeException [Char])
-> (ShortByteString -> IO (Either UnicodeException [Char]))
-> ShortByteString
-> Either UnicodeException [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO [Char] -> IO (Either UnicodeException [Char])
forall e a. Exception e => IO a -> IO (Either e a)
try (IO [Char] -> IO (Either UnicodeException [Char]))
-> (ShortByteString -> IO [Char])
-> ShortByteString
-> IO (Either UnicodeException [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
forall a. a -> IO a
evaluate ([Char] -> IO [Char])
-> (ShortByteString -> [Char]) -> ShortByteString -> IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ShortByteString -> [Char]
decodeUtf8With OnDecodeError
strictDecode
{-# INLINE decodeUtf8' #-}


-- | Decode a 'ShortByteString' containing UTF-16 encoded text.
--
-- If the input contains any invalid UTF-16 data, the relevant
-- exception will be returned, otherwise the decoded text.
decodeUtf16LE' :: ShortByteString -> Either UnicodeException String
decodeUtf16LE' :: ShortByteString -> Either UnicodeException [Char]
decodeUtf16LE' = IO (Either UnicodeException [Char])
-> Either UnicodeException [Char]
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either UnicodeException [Char])
 -> Either UnicodeException [Char])
-> (ShortByteString -> IO (Either UnicodeException [Char]))
-> ShortByteString
-> Either UnicodeException [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO [Char] -> IO (Either UnicodeException [Char])
forall e a. Exception e => IO a -> IO (Either e a)
try (IO [Char] -> IO (Either UnicodeException [Char]))
-> (ShortByteString -> IO [Char])
-> ShortByteString
-> IO (Either UnicodeException [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
forall a. a -> IO a
evaluate ([Char] -> IO [Char])
-> (ShortByteString -> [Char]) -> ShortByteString -> IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ShortByteString -> [Char]
decodeUtf16LEWith OnDecodeError
strictDecode
{-# INLINE decodeUtf16LE' #-}


-- | Decode a 'ByteString' containing UTF-16 encoded text.
--
-- If the input contains any invalid UTF-16 data, the relevant
-- exception will be returned, otherwise the decoded text.
decodeUtf16LE'' :: ByteString -> Either UnicodeException String
decodeUtf16LE'' :: ByteString -> Either UnicodeException [Char]
decodeUtf16LE'' = IO (Either UnicodeException [Char])
-> Either UnicodeException [Char]
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either UnicodeException [Char])
 -> Either UnicodeException [Char])
-> (ByteString -> IO (Either UnicodeException [Char]))
-> ByteString
-> Either UnicodeException [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO [Char] -> IO (Either UnicodeException [Char])
forall e a. Exception e => IO a -> IO (Either e a)
try (IO [Char] -> IO (Either UnicodeException [Char]))
-> (ByteString -> IO [Char])
-> ByteString
-> IO (Either UnicodeException [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
forall a. a -> IO a
evaluate ([Char] -> IO [Char])
-> (ByteString -> [Char]) -> ByteString -> IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ShortByteString -> [Char]
decodeUtf16LEWith OnDecodeError
strictDecode (ShortByteString -> [Char])
-> (ByteString -> ShortByteString) -> ByteString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
toShort
{-# INLINE decodeUtf16LE'' #-}

-- | Throw a 'UnicodeException' if decoding fails.
strictDecode :: OnDecodeError
strictDecode :: OnDecodeError
strictDecode [Char]
desc Maybe Word8
c = UnicodeException -> Maybe Char
forall a e. Exception e => e -> a
throw ([Char] -> Maybe Word8 -> UnicodeException
DecodeError [Char]
desc Maybe Word8
c)

-- | Replace an invalid input byte with the Unicode replacement
-- character U+FFFD.
lenientDecode :: OnDecodeError
lenientDecode :: OnDecodeError
lenientDecode [Char]
_ Maybe Word8
_ = Char -> Maybe Char
forall a. a -> Maybe a
Just Char
'\xfffd'


type OnError a b = String -> Maybe a -> Maybe b
type OnDecodeError = OnError Word8 Char
-- | An exception type for representing Unicode encoding errors.
data UnicodeException =
    DecodeError String (Maybe Word8)
    -- ^ Could not decode a byte sequence because it was invalid under
    -- the given encoding, or ran out of input in mid-decode.
    deriving (UnicodeException -> UnicodeException -> Bool
(UnicodeException -> UnicodeException -> Bool)
-> (UnicodeException -> UnicodeException -> Bool)
-> Eq UnicodeException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnicodeException -> UnicodeException -> Bool
$c/= :: UnicodeException -> UnicodeException -> Bool
== :: UnicodeException -> UnicodeException -> Bool
$c== :: UnicodeException -> UnicodeException -> Bool
Eq, Typeable)

-------------------------------
-- Internal


between :: Word8                -- ^ byte to check
        -> Word8                -- ^ lower bound
        -> Word8                -- ^ upper bound
        -> Bool
between :: Word8 -> Word8 -> Word8 -> Bool
between Word8
x Word8
y Word8
z = Word8
x Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
y Bool -> Bool -> Bool
&& Word8
x Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
z
{-# INLINE between #-}


validate1_8 :: Word8 -> Bool
validate1_8 :: Word8 -> Bool
validate1_8 Word8
x1 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x7F
{-# INLINE validate1_8 #-}

validate2_8 :: Word8 -> Word8 -> Bool
validate2_8 :: Word8 -> Word8 -> Bool
validate2_8 Word8
x1 Word8
x2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xC2 Word8
0xDF Bool -> Bool -> Bool
&& Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF
{-# INLINE validate2_8 #-}

validate3_8 :: Word8 -> Word8 -> Word8 -> Bool
{-# INLINE validate3_8 #-}
validate3_8 :: Word8 -> Word8 -> Word8 -> Bool
validate3_8 Word8
x1 Word8
x2 Word8
x3 = Bool
validate3_1 Bool -> Bool -> Bool
|| Bool
validate3_2 Bool -> Bool -> Bool
|| Bool
validate3_3 Bool -> Bool -> Bool
|| Bool
validate3_4
  where
    validate3_1 :: Bool
validate3_1 = (Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xE0) Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0xA0 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
    validate3_2 :: Bool
validate3_2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xE1 Word8
0xEC Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
    validate3_3 :: Bool
validate3_3 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xED Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0x9F Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
    validate3_4 :: Bool
validate3_4 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xEE Word8
0xEF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF

validate4_8 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
{-# INLINE validate4_8 #-}
validate4_8 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
validate4_8 Word8
x1 Word8
x2 Word8
x3 Word8
x4 = Bool
validate4_1 Bool -> Bool -> Bool
|| Bool
validate4_2 Bool -> Bool -> Bool
|| Bool
validate4_3
  where
    validate4_1 :: Bool
validate4_1 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xF0 Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x90 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF
    validate4_2 :: Bool
validate4_2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xF1 Word8
0xF3 Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF
    validate4_3 :: Bool
validate4_3 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xF4 Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0x8F Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
                  Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF

chr2 :: Word8 -> Word8 -> Char
chr2 :: Word8 -> Word8 -> Char
chr2 (W8# Word#
x1#) (W8# Word#
x2#) = Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2#))
    where
      !y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x1#)
      !y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x2#)
      !z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xC0#) Int#
6#
      !z2# :: Int#
z2# = Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr2 #-}

chr3 :: Word8 -> Word8 -> Word8 -> Char
chr3 :: Word8 -> Word8 -> Word8 -> Char
chr3 (W8# Word#
x1#) (W8# Word#
x2#) (W8# Word#
x3#) = Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2# Int# -> Int# -> Int#
+# Int#
z3#))
    where
      !y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x1#)
      !y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x2#)
      !y3# :: Int#
y3# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x3#)
      !z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xE0#) Int#
12#
      !z2# :: Int#
z2# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
6#
      !z3# :: Int#
z3# = Int#
y3# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr3 #-}

chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
chr4 (W8# Word#
x1#) (W8# Word#
x2#) (W8# Word#
x3#) (W8# Word#
x4#) =
    Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2# Int# -> Int# -> Int#
+# Int#
z3# Int# -> Int# -> Int#
+# Int#
z4#))
    where
      !y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x1#)
      !y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x2#)
      !y3# :: Int#
y3# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x3#)
      !y4# :: Int#
y4# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWord# Word#
x4#)
      !z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xF0#) Int#
18#
      !z2# :: Int#
z2# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
12#
      !z3# :: Int#
z3# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y3# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
6#
      !z4# :: Int#
z4# = Int#
y4# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr4 #-}

validate1_16 :: Word16 -> Bool
validate1_16 :: Word16 -> Bool
validate1_16 Word16
x1 = Word16
x1 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xD800 Bool -> Bool -> Bool
|| Word16
x1 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDFFF
{-# INLINE validate1_16 #-}

validate2_16 ::  Word16 -> Word16 -> Bool
validate2_16 :: Word16 -> Word16 -> Bool
validate2_16 Word16
x1 Word16
x2 = Word16
x1 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word16
0xD800 Bool -> Bool -> Bool
&& Word16
x1 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word16
0xDBFF Bool -> Bool -> Bool
&&
                  Word16
x2 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word16
0xDC00 Bool -> Bool -> Bool
&& Word16
x2 Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word16
0xDFFF
{-# INLINE validate2_16 #-}

chr2_16 :: Word16 -> Word16 -> Char
chr2_16 :: Word16 -> Word16 -> Char
chr2_16 (W16# Word#
a#) (W16# Word#
b#) = Char# -> Char
C# (Int# -> Char#
chr# (Int#
upper# Int# -> Int# -> Int#
+# Int#
lower# Int# -> Int# -> Int#
+# Int#
0x10000#))
    where
      !x# :: Int#
x# = Word# -> Int#
word2Int# (Word# -> Word#
word16ToWord# Word#
a#)
      !y# :: Int#
y# = Word# -> Int#
word2Int# (Word# -> Word#
word16ToWord# Word#
b#)
      !upper# :: Int#
upper# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
x# Int# -> Int# -> Int#
-# Int#
0xD800#) Int#
10#
      !lower# :: Int#
lower# = Int#
y# Int# -> Int# -> Int#
-# Int#
0xDC00#
{-# INLINE chr2_16 #-}


showUnicodeException :: UnicodeException -> String
showUnicodeException :: UnicodeException -> [Char]
showUnicodeException (DecodeError [Char]
desc (Just Word8
w))
    = [Char]
"Cannot decode byte '\\x" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word8 -> [Char] -> [Char]
forall a. (Integral a, Show a) => a -> [Char] -> [Char]
showHex Word8
w ([Char]
"': " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
desc)
showUnicodeException (DecodeError [Char]
desc Maybe Word8
Nothing)
    = [Char]
"Cannot decode input: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
desc

instance Show UnicodeException where
    show :: UnicodeException -> [Char]
show = UnicodeException -> [Char]
showUnicodeException

instance Exception UnicodeException

instance NFData UnicodeException where
    rnf :: UnicodeException -> ()
rnf (DecodeError [Char]
desc Maybe Word8
w) = [Char] -> ()
forall a. NFData a => a -> ()
rnf [Char]
desc () -> () -> ()
`seq` Maybe Word8 -> ()
forall a. NFData a => a -> ()
rnf Maybe Word8
w () -> () -> ()
`seq` ()