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