@@ -72,6 +72,9 @@ module Streamly.Internal.Unicode.Stream
7272 , decodeUtf8ArraysD'
7373 , decodeUtf8ArraysD_
7474
75+ -- * Decoding String Literals
76+ , fromStr#
77+
7578 -- * Deprecations
7679 , decodeUtf8Lax
7780 , encodeLatin1Lax
@@ -94,6 +97,7 @@ import Foreign.Marshal.Alloc (mallocBytes)
9497import Foreign.Storable (Storable(..))
9598import Fusion.Plugin.Types (Fuse(..))
9699import GHC.Base (assert, unsafeChr)
100+import GHC.Exts (Addr#)
97101import GHC.IO.Encoding.Failure (isSurrogate)
98102import GHC.Ptr (Ptr (..), plusPtr)
99103import System.IO.Unsafe (unsafePerformIO)
@@ -114,6 +118,7 @@ import qualified Streamly.Internal.Data.Fold as Fold
114118import qualified Streamly.Internal.Data.Unfold as Unfold
115119import qualified Streamly.Internal.Data.Parser as Parser
116120import qualified Streamly.Internal.Data.Parser.ParserD as ParserD
121+import qualified Streamly.Internal.Data.Stream as Stream
117122import qualified Streamly.Internal.Data.Stream.Serial as Serial
118123import qualified Streamly.Internal.Data.Array.Unboxed as Array
119124import qualified Streamly.Internal.Data.Array.Unboxed.Type as A
@@ -124,9 +129,11 @@ import Prelude hiding (lines, words, unlines, unwords)
124129
125130-- $setup
126131-- >>> :m
132+-- >>> :set -XMagicHash
127133-- >>> import Prelude hiding (lines, words, unlines, unwords)
128134-- >>> import qualified Streamly.Prelude as Stream
129135-- >>> import qualified Streamly.Data.Fold as Fold
136+-- >>> import qualified Streamly.Internal.Unicode.Stream as Unicode
130137-- >>> import Streamly.Internal.Unicode.Stream
131138
132139-------------------------------------------------------------------------------
@@ -980,6 +987,25 @@ encodeUtf8_ = fromStreamD . encodeUtf8D_ . toStreamD
980987encodeUtf8Lax :: (IsStream t, Monad m) => t m Char -> t m Word8
981988encodeUtf8Lax = encodeUtf8
982989
990+-------------------------------------------------------------------------------
991+-- Decoding string literals
992+-------------------------------------------------------------------------------
993+
994+-- | Read UTF-8 encoded bytes as chars from an 'Addr#' until a 0 byte is
995+-- encountered, the 0 byte is not included in the stream.
996+--
997+-- /Unsafe:/ The caller is responsible for safe addressing.
998+--
999+-- Note that this is completely safe when reading from Haskell string
1000+-- literals because they are guaranteed to be NULL terminated:
1001+--
1002+-- >>> Stream.fold Fold.toList (Unicode.fromStr# "Haskell"#)
1003+-- "Haskell"
1004+--
1005+{-# INLINE fromStr# #-}
1006+fromStr# :: MonadIO m => Addr# -> SerialT m Char
1007+fromStr# addr = decodeUtf8 $ Stream.fromByteStr# addr
1008+
9831009-------------------------------------------------------------------------------
9841010-- Encode streams of containers
9851011-------------------------------------------------------------------------------