@@ -29,6 +29,7 @@ module Streamly.Internal.Data.Unicode.Stream
29 , encodeLatin1
29 , encodeLatin1
30 , encodeLatin1Lax
30 , encodeLatin1Lax
31 , encodeUtf8
31 , encodeUtf8
33 -- * Operations on character strings
34 -- * Operations on character strings
34 , strip -- (dropAround isSpace)
35 , strip -- (dropAround isSpace)
@@ -675,6 +676,45 @@ decodeUtf8ArraysLenient =
675encodeUtf8 :: (Monad m, IsStream t) => t m Char -> t m Word8
676encodeUtf8 :: (Monad m, IsStream t) => t m Char -> t m Word8
676encodeUtf8 = D.fromStreamD . encodeUtf8D . D.toStreamD
677encodeUtf8 = D.fromStreamD . encodeUtf8D . D.toStreamD
679+-- | See section "3.9 Unicode Encoding Forms" in
680+-- https://www.unicode.org/versions/Unicode13.0.0/UnicodeStandard-13.0.pdf
682+{-# INLINE_NORMAL encodeUtf8LaxD #-}
683+encodeUtf8LaxD :: Monad m => Stream m Char -> Stream m Word8
684+encodeUtf8LaxD (Stream step state) = Stream step' (EncodeState state WNil)
686+ {-# INLINE_LATE step' #-}
687+ step' gst (EncodeState st WNil) = do
688+ r <- step (adaptState gst) st
694+ Yield (fromIntegral x) (EncodeState s WNil)
695+ | x <= 0x7FF -> Skip (EncodeState s (ord2 c))
701+ (WCons 239 (WCons 191 (WCons 189 WNil)))
702+ else Skip (EncodeState s (ord3 c))
703+ | otherwise -> Skip (EncodeState s (ord4 c))
704+ Skip s -> Skip (EncodeState s WNil)
706+ step' _ (EncodeState s (WCons x xs)) = return $ Yield x (EncodeState s xs)
709+-- | Encode a stream of Unicode characters to a UTF-8 encoded bytestream. Any
710+-- Invalid characters (U+D800-U+D8FF) in the input stream are replaced by the
711+-- Unicode replacement character U+FFFD.
714+{-# INLINE encodeUtf8Lax #-}
715+encodeUtf8Lax :: (Monad m, IsStream t) => t m Char -> t m Word8
716+encodeUtf8Lax = D.fromStreamD . encodeUtf8LaxD . D.toStreamD
679-------------------------------------------------------------------------------
719-------------------------------------------------------------------------------
680-- Utility operations on strings
720-- Utility operations on strings