on master help sign in
Merge
commitc93192a9ddc6617cbddb7e1eab978cb0c4ff299a authorBryan O'Sullivan <bos@serpentine.com> dateSat 29 Sep 2012, 19:52 (14 years ago) parent2d8284f24fd53e
2 files changed+31−13
Data/Text.hs+4−4 Data/Text/IO.hs+27−9
Data/Text.hs+4−4
@@ -370,7 +370,7 @@ compareText ta@(Text _arrA _offA lenA) tb@(Text _arrB _offB lenB)
370370-- | /O(n)/ Convert a 'String' into a 'Text'. Subject to
371371-- fusion. Performs replacement on invalid scalar values.
372372pack :: String -> Text
373−pack = unstream . S.streamList . L.map safe
373+pack = unstream . S.map safe . S.streamList
374374{-# INLINE [1] pack #-}
375375
376376-- | /O(n)/ Convert a Text into a String. Subject to fusion.
@@ -378,17 +378,17 @@ unpack :: Text -> String
378378unpack = S.unstreamList . stream
379379{-# INLINE [1] unpack #-}
380380
381−-- | /O(n)/ Convert a literal string into a Text.
381+-- | /O(n)/ Convert a literal string into a Text. Subject to fusion.
382382unpackCString# :: Addr# -> Text
383383unpackCString# addr# = unstream (S.streamCString# addr#)
384384{-# NOINLINE unpackCString# #-}
385385
386386{-# 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)))
388388 = unpackCString# a #-}
389389
390390{-# 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)))
392392 = unpackCString# a #-}
393393
394394-- | /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
2626 , appendFile
2727 -- * Operations on handles
2828 , hGetContents
29+ , hGetChunk
2930 , hGetLine
3031 , hPutStr
3132 , hPutStrLn
@@ -97,6 +98,30 @@ writeFile p = withFile p WriteMode . flip hPutStr
9798appendFile :: FilePath -> Text -> IO ()
9899appendFile p = withFile p AppendMode . flip hPutStr
99100
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+
100125-- | Read the remaining contents of a 'Handle' as a string. The
101126-- 'Handle' is closed once the contents have been read, or if an
102127-- exception is thrown.
@@ -117,16 +142,9 @@ hGetContents h = do
117142 wantReadableHandle "hGetContents" h readAll
118143 where
119144 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
128146 buf <- readIORef haCharBuffer
129− t <- readChunk hh buf `E.catch` catchError
147+ t <- readChunk hh buf `E.catch` catchError "hGetContents" h hh
130148 if T.null t
131149 then return [t]
132150 else (t:) `fmap` readChunks