module FudUTF8 where
decodeUTF8 :: String -> String
decodeUTF8 :: String -> String
decodeUTF8 String
"" = String
""
decodeUTF8 (Char
c:String
cs) | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\x80' = Char
c forall a. a -> [a] -> [a]
: String -> String
decodeUTF8 String
cs
decodeUTF8 (Char
c:Char
c':String
cs) | Char
'\xc0' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xdf' Bool -> Bool -> Bool
&&
Char
'\x80' forall a. Ord a => a -> a -> Bool
<= Char
c' Bool -> Bool -> Bool
&& Char
c' forall a. Ord a => a -> a -> Bool
<= Char
'\xbf' =
forall a. Enum a => Int -> a
toEnum ((forall a. Enum a => a -> Int
fromEnum Char
c forall a. Integral a => a -> a -> a
`mod` Int
0x20) forall a. Num a => a -> a -> a
* Int
0x40 forall a. Num a => a -> a -> a
+ forall a. Enum a => a -> Int
fromEnum Char
c' forall a. Integral a => a -> a -> a
`mod` Int
0x40) forall a. a -> [a] -> [a]
: String -> String
decodeUTF8 String
cs
decodeUTF8 (Char
c:Char
c':Char
c'':String
cs) | Char
'\xe0' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xef' Bool -> Bool -> Bool
&&
Char
'\x80' forall a. Ord a => a -> a -> Bool
<= Char
c' Bool -> Bool -> Bool
&& Char
c' forall a. Ord a => a -> a -> Bool
<= Char
'\xbf' Bool -> Bool -> Bool
&&
Char
'\x80' forall a. Ord a => a -> a -> Bool
<= Char
c'' Bool -> Bool -> Bool
&& Char
c'' forall a. Ord a => a -> a -> Bool
<= Char
'\xbf' =
forall a. Enum a => Int -> a
toEnum ((forall a. Enum a => a -> Int
fromEnum Char
c forall a. Integral a => a -> a -> a
`mod` Int
0x10 forall a. Num a => a -> a -> a
* Int
0x1000) forall a. Num a => a -> a -> a
+ (forall a. Enum a => a -> Int
fromEnum Char
c' forall a. Integral a => a -> a -> a
`mod` Int
0x40) forall a. Num a => a -> a -> a
* Int
0x40 forall a. Num a => a -> a -> a
+ forall a. Enum a => a -> Int
fromEnum Char
c'' forall a. Integral a => a -> a -> a
`mod` Int
0x40) forall a. a -> [a] -> [a]
: String -> String
decodeUTF8 String
cs
decodeUTF8 String
_ = forall a. HasCallStack => String -> a
error String
"UniChar.decodeUTF8: bad data"
encodeUTF8 :: String -> String
encodeUTF8 :: String -> String
encodeUTF8 String
"" = String
""
encodeUTF8 (Char
c:String
cs) =
if Char
c forall a. Ord a => a -> a -> Bool
> Char
'\x0000' Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
< Char
'\x0080' then
Char
c forall a. a -> [a] -> [a]
: String -> String
encodeUTF8 String
cs
else if Char
c forall a. Ord a => a -> a -> Bool
< forall a. Enum a => Int -> a
toEnum Int
0x0800 then
let i :: Int
i = forall a. Enum a => a -> Int
fromEnum Char
c
in forall a. Enum a => Int -> a
toEnum (Int
0xc0 forall a. Num a => a -> a -> a
+ Int
i forall a. Integral a => a -> a -> a
`div` Int
0x40) forall a. a -> [a] -> [a]
:
forall a. Enum a => Int -> a
toEnum (Int
0x80 forall a. Num a => a -> a -> a
+ Int
i forall a. Integral a => a -> a -> a
`mod` Int
0x40) forall a. a -> [a] -> [a]
:
String -> String
encodeUTF8 String
cs
else
let i :: Int
i = forall a. Enum a => a -> Int
fromEnum Char
c
in forall a. Enum a => Int -> a
toEnum (Int
0xe0 forall a. Num a => a -> a -> a
+ Int
i forall a. Integral a => a -> a -> a
`div` Int
0x1000) forall a. a -> [a] -> [a]
:
forall a. Enum a => Int -> a
toEnum (Int
0x80 forall a. Num a => a -> a -> a
+ (Int
i forall a. Integral a => a -> a -> a
`mod` Int
0x1000) forall a. Integral a => a -> a -> a
`div` Int
0x40) forall a. a -> [a] -> [a]
:
forall a. Enum a => Int -> a
toEnum (Int
0x80 forall a. Num a => a -> a -> a
+ Int
i forall a. Integral a => a -> a -> a
`mod` Int
0x40) forall a. a -> [a] -> [a]
:
String -> String
encodeUTF8 String
cs