-- | 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 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"

-- | 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 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