@@ -26,7 +26,9 @@ module Codec.Binary.UTF8.String (
2626 , utf8Encode
2727 ) where
2828
29+ #if __GLASGOW_HASKELL__ > 710
2930import qualified Data.List.NonEmpty as NE
31+ #endif
3032import Data.Word (Word8 ,Word32 )
3133import Data.Bits ((.|.) ,(.&.) ,shiftL ,shiftR )
3234import Data.Char (chr ,ord )
@@ -47,6 +49,28 @@ replacement_character :: Char
4749replacement_character = ' \xfffd '
4850
4951-- | Encode a single Haskell 'Char' to a list of 'Word8' values, in UTF8 format.
52+ #if __GLASGOW_HASKELL__ < 802
53+ encodeChar :: Char -> (Word8 , [Word8 ])
54+ encodeChar = (\ (x, xs) -> (fromIntegral x, fmap fromIntegral xs)) . go . ord
55+ where
56+ go oc
57+ | oc <= 0x7f = ( oc
58+ , [] )
59+
60+ | oc <= 0x7ff = ( 0xc0 + (oc `shiftR` 6 )
61+ , [ 0x80 + oc .&. 0x3f ])
62+
63+ | oc <= 0xffff = ( 0xe0 + (oc `shiftR` 12 )
64+ , [ 0x80 + ((oc `shiftR` 6 ) .&. 0x3f )
65+ , 0x80 + oc .&. 0x3f
66+ ])
67+
68+ | otherwise = ( 0xf0 + (oc `shiftR` 18 )
69+ , [ 0x80 + ((oc `shiftR` 12 ) .&. 0x3f )
70+ , 0x80 + ((oc `shiftR` 6 ) .&. 0x3f )
71+ , 0x80 + oc .&. 0x3f
72+ ])
73+ #else
5074encodeChar :: Char -> NE. NonEmpty Word8
5175encodeChar = fmap fromIntegral . go . ord
5276 where
@@ -61,16 +85,21 @@ encodeChar = fmap fromIntegral . go . ord
6185 [ 0x80 + ((oc `shiftR` 6 ) .&. 0x3f )
6286 , 0x80 + oc .&. 0x3f
6387 ]
88+
6489 | otherwise = 0xf0 + (oc `shiftR` 18 ) NE. :|
6590 [ 0x80 + ((oc `shiftR` 12 ) .&. 0x3f )
6691 , 0x80 + ((oc `shiftR` 6 ) .&. 0x3f )
6792 , 0x80 + oc .&. 0x3f
6893 ]
69-
94+ #endif
7095
7196-- | Encode a Haskell 'String' to a list of 'Word8' values, in UTF8 format.
7297encode :: String -> [Word8 ]
98+ #if __GLASGOW_HASKELL__ < 802
99+ encode = concatMap ((\ (x, xs) -> x: xs) . encodeChar)
100+ #else
73101encode = concatMap (NE. toList . encodeChar)
102+ #endif
74103
75104--
76105-- | Decode a UTF8 string packed into a list of 'Word8' values, directly to 'String'
0 commit comments