@@ -1,3 +1,4 @@
1+{-# LANGUAGE FlexibleContexts #-}
2-- Module : Streamly.String
3-- Module : Streamly.String
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -52,23 +53,25 @@ module Streamly.String
52 , foldLines
53 , foldLines
53 , foldWords
54 , foldWords
57− , unwords-}
58+ , unwords
61import Control.Monad.IO.Class (MonadIO)
62import Control.Monad.IO.Class (MonadIO)
62−import Data.Char (isSpace, ord)
63+import Data.Char (ord)
63import Data.Word (Word8)
64import Data.Word (Word8)
64import GHC.Base (unsafeChr)
65import GHC.Base (unsafeChr)
65−import Streamly (IsStream)
66+import Streamly (IsStream, MonadAsync)
66import Prelude hiding (String, lines, words, unlines, unwords)
67import Prelude hiding (String, lines, words, unlines, unwords)
67import Streamly.Fold (Fold)
68import Streamly.Fold (Fold)
68import Streamly.Mem.Array (Array, toArray)
69import Streamly.Mem.Array (Array, toArray)
70import qualified Streamly.Prelude as S
71import qualified Streamly.Prelude as S
71import qualified Streamly.Fold as FL
72import qualified Streamly.Fold as FL
73+import qualified Streamly.Mem.Array.Types as A (unlines)
74+import qualified Streamly.Mem.Array as A
72import qualified Streamly.Streams.StreamD as D
75import qualified Streamly.Streams.StreamD as D
74-- type String = List Char
77-- type String = List Char
@@ -112,12 +115,13 @@ encodeChar8Unchecked :: (IsStream t, Monad m) => t m Char -> t m Word8
112encodeChar8Unchecked = S.map (fromIntegral . ord)
115encodeChar8Unchecked = S.map (fromIntegral . ord)
114-- | Decode a UTF-8 encoded bytestream to a stream of Unicode characters.
117-- | Decode a UTF-8 encoded bytestream to a stream of Unicode characters.
118+-- The incoming stream is truncated if an invalid codepoint is encountered.
115{-# INLINE decodeUtf8 #-}
119{-# INLINE decodeUtf8 #-}
116decodeUtf8 :: (Monad m, IsStream t) => t m Word8 -> t m Char
120decodeUtf8 :: (Monad m, IsStream t) => t m Word8 -> t m Char
117decodeUtf8 = D.fromStreamD . D.decodeUtf8 . D.toStreamD
121decodeUtf8 = D.fromStreamD . D.decodeUtf8 . D.toStreamD
119−{-# INLINE encodeUtf8 #-}
120-- | Encode a stream of Unicode characters to a UTF-8 encoded bytestream.
123-- | Encode a stream of Unicode characters to a UTF-8 encoded bytestream.
124+{-# INLINE encodeUtf8 #-}
121encodeUtf8 :: (Monad m, IsStream t) => t m Char -> t m Word8
125encodeUtf8 :: (Monad m, IsStream t) => t m Char -> t m Word8
122encodeUtf8 = D.fromStreamD . D.encodeUtf8 . D.toStreamD
126encodeUtf8 = D.fromStreamD . D.encodeUtf8 . D.toStreamD
@@ -161,6 +165,18 @@ foldLines = flip (FL.splitSuffixBy (== '\n'))
161foldWords :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
165foldWords :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
162foldWords = flip (FL.wordsBy isSpace)
166foldWords = flip (FL.wordsBy isSpace)
168+foreign import ccall unsafe "u_iswspace"
169+ iswspace :: Int -> Int
171+-- Code copied from base/Data.Char to INLINE it
172+{-# INLINE isSpace #-}
173+isSpace :: Char -> Bool
175+ | uc <= 0x377 = uc == 32 || uc - 0x9 <= 4 || uc == 0xa0
176+ | otherwise = iswspace (ord c) /= 0
178+ uc = fromIntegral (ord c) :: Word
164{-# INLINE lines #-}
180{-# INLINE lines #-}
165lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
181lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
166lines = FL.splitSuffixBy (== '\n') toArray
182lines = FL.splitSuffixBy (== '\n') toArray
@@ -169,10 +185,10 @@ lines = FL.splitSuffixBy (== '\n') toArray
169words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
185words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
170words = FL.wordsBy isSpace toArray
186words = FL.wordsBy isSpace toArray
172−{-
188+{-# INLINE unlines #-}
173−unlines :: IsStream t => t m (Array Char) -> t m Char
189+unlines :: (MonadIO m, IsStream t) => t m (Array Char) -> t m Char
174−unlines = undefined
190+unlines = D.fromStreamD . A.unlines . D.toStreamD
192+{-# INLINE unwords #-}
176−unwords :: IsStream t => t m (Array Char) -> t m Char
193+unwords :: (MonadAsync m, IsStream t) => t m (Array Char) -> t m Char
177−unwords = undefined
194+unwords = A.flattenArrays . (S.intersperseM (return $ A.fromList " "))