on master help sign in
Merge
c93192aBryan O'Sullivan
Data/Text.hs+4−4
@@ -370,7 +370,7 @@ compareText ta@(Text _arrA _offA lenA) tb@(Text _arrB _offB lenB)
370-- | /O(n)/ Convert a 'String' into a 'Text'. Subject to
370-- | /O(n)/ Convert a 'String' into a 'Text'. Subject to
371-- fusion. Performs replacement on invalid scalar values.
371-- fusion. Performs replacement on invalid scalar values.
372pack :: String -> Text
372pack :: String -> Text
373−pack = unstream . S.streamList . L.map safe
373+pack = unstream . S.map safe . S.streamList
374{-# INLINE [1] pack #-}
374{-# INLINE [1] pack #-}
375
375
376-- | /O(n)/ Convert a Text into a String. Subject to fusion.
376-- | /O(n)/ Convert a Text into a String. Subject to fusion.
@@ -378,17 +378,17 @@ unpack :: Text -> String
378unpack = S.unstreamList . stream
378unpack = S.unstreamList . stream
379{-# INLINE [1] unpack #-}
379{-# INLINE [1] unpack #-}
380
380
381−-- | /O(n)/ Convert a literal string into a Text.
381+-- | /O(n)/ Convert a literal string into a Text. Subject to fusion.
382unpackCString# :: Addr# -> Text
382unpackCString# :: Addr# -> Text
383unpackCString# addr# = unstream (S.streamCString# addr#)
383unpackCString# addr# = unstream (S.streamCString# addr#)
384{-# NOINLINE unpackCString# #-}
384{-# NOINLINE unpackCString# #-}
385
385
386{-# RULES "TEXT literal" forall a.
386{-# RULES "TEXT literal" forall a.
387− unstream (S.streamList (L.map safe (GHC.unpackCString# a)))
387+ unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
388 = unpackCString# a #-}
388 = unpackCString# a #-}
389
389
390{-# RULES "TEXT literal UTF8" forall a.
390{-# RULES "TEXT literal UTF8" forall a.
391− unstream (S.streamList (L.map safe (GHC.unpackCStringUtf8# a)))
391+ unstream (S.map safe (S.streamList (GHC.unpackCStringUtf8# a)))
392 = unpackCString# a #-}
392 = unpackCString# a #-}
393
393
394-- | /O(1)/ Convert a character into a Text. Subject to fusion.
394-- | /O(1)/ Convert a character into a Text. Subject to fusion.
Data/Text/IO.hs+27−9
@@ -26,6 +26,7 @@ module Data.Text.IO
26 , appendFile
26 , appendFile
27 -- * Operations on handles
27 -- * Operations on handles
28 , hGetContents
28 , hGetContents
29+ , hGetChunk
29 , hGetLine
30 , hGetLine
30 , hPutStr
31 , hPutStr
31 , hPutStrLn
32 , hPutStrLn
@@ -97,6 +98,30 @@ writeFile p = withFile p WriteMode . flip hPutStr
97appendFile :: FilePath -> Text -> IO ()
98appendFile :: FilePath -> Text -> IO ()
98appendFile p = withFile p AppendMode . flip hPutStr
99appendFile p = withFile p AppendMode . flip hPutStr
99
100
101+catchError :: String -> Handle -> Handle__ -> IOError -> IO Text
102+catchError caller h Handle__{..} err
103+ | isEOFError err = do
104+ buf <- readIORef haCharBuffer
105+ return $ if isEmptyBuffer buf
106+ then T.empty
107+ else T.singleton '\r'
108+ | otherwise = E.throwIO (augmentIOError err caller h)
109+
110+-- | /Experimental./ Read a single chunk of strict text from a
111+-- 'Handle'. The size of the chunk depends on the amount of input
112+-- currently buffered.
113+--
114+-- This function blocks only if there is no data available, and EOF
115+-- has not yet been reached. Once EOF is reached, this function
116+-- returns an empty string instead of throwing an exception.
117+hGetChunk :: Handle -> IO Text
118+hGetChunk h = wantReadableHandle "hGetChunk" h readSingleChunk
119+ where
120+ readSingleChunk hh@Handle__{..} = do
121+ buf <- readIORef haCharBuffer
122+ t <- readChunk hh buf `E.catch` catchError "hGetChunk" h hh
123+ return (hh, t)
124+
100-- | Read the remaining contents of a 'Handle' as a string. The
125-- | Read the remaining contents of a 'Handle' as a string. The
101-- 'Handle' is closed once the contents have been read, or if an
126-- 'Handle' is closed once the contents have been read, or if an
102-- exception is thrown.
127-- exception is thrown.
@@ -117,16 +142,9 @@ hGetContents h = do
117 wantReadableHandle "hGetContents" h readAll
142 wantReadableHandle "hGetContents" h readAll
118 where
143 where
119 readAll hh@Handle__{..} = do
144 readAll hh@Handle__{..} = do
120− let catchError e
121− | isEOFError e = do
122− buf <- readIORef haCharBuffer
123− return $ if isEmptyBuffer buf
124− then T.empty
125− else T.singleton '\r'
126− | otherwise = E.throwIO (augmentIOError e "hGetContents" h)
127− readChunks = do
145+ let readChunks = do
128 buf <- readIORef haCharBuffer
146 buf <- readIORef haCharBuffer
129− t <- readChunk hh buf `E.catch` catchError
147+ t <- readChunk hh buf `E.catch` catchError "hGetContents" h hh
130 if T.null t
148 if T.null t
131 then return [t]
149 then return [t]
132 else (t:) `fmap` readChunks
150 else (t:) `fmap` readChunks