-- | From the Char module supplied with HBC.
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"

-- | Take a Unicode string and encode it as a string
-- with the UTF8 method.
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