packages feed

text 0.7 → 0.7.0.1

raw patch · 7 files changed

+93/−63 lines, 7 filesdep +extensible-exceptions

Dependencies added: extensible-exceptions

Files

Data/Text.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, Rank2Types #-}+{-# LANGUAGE BangPatterns, CPP, Rank2Types #-} {-# OPTIONS_GHC -fno-warn-orphans #-}  -- |@@ -167,7 +167,9 @@                 Read(..), Show(..),                 (&&), (||), (+), (-), (.), ($), (>>), (*),                 div, not, return, otherwise)+#if defined(HAVE_DEEPSEQ) import Control.DeepSeq (NFData)+#endif import Control.Exception (assert) import Data.Char (isSpace) import Control.Monad (foldM)@@ -215,7 +217,9 @@ instance IsString Text where     fromString = pack +#if defined(HAVE_DEEPSEQ) instance NFData Text+#endif  -- ----------------------------------------------------------------------------- -- * Conversion to/from 'Text'
Data/Text/Encoding/Error.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP, DeriveDataTypeable #-} -- | -- Module      : Data.Text.Encoding.Error -- Copyright   : (c) Bryan O'Sullivan 2009@@ -35,7 +35,11 @@     , replace     ) where +#if __GLASGOW_HASKELL__ >= 610 import Control.Exception (Exception, throw)+#else+import Control.Exception.Extensible (Exception, throw)+#endif import Data.Typeable (Typeable) import Data.Word (Word8) import Numeric (showHex)
Data/Text/Lazy.hs view
@@ -1,5 +1,5 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BangPatterns, CPP #-} -- | -- Module      : Data.Text.Lazy -- Copyright   : (c) Bryan O'Sullivan 2009@@ -169,7 +169,9 @@                 (&&), (+), (-), (.), ($), (++),                 div, flip, fromIntegral, not, otherwise) import qualified Prelude as P+#if defined(HAVE_DEEPSEQ) import Control.DeepSeq (NFData(..))+#endif import Data.Int (Int64) import qualified Data.List as L import Data.Char (isSpace)@@ -208,9 +210,11 @@ instance IsString Text where     fromString = pack +#if defined(HAVE_DEEPSEQ) instance NFData Text where     rnf Empty        = ()     rnf (Chunk _ ts) = rnf ts+#endif  -- | /O(n)/ Convert a 'String' into a 'Text'. --
Data/Text/Lazy/Encoding/Fusion.hs view
@@ -35,7 +35,6 @@ import Data.Text.Encoding.Fusion.Common import Data.Text.Encoding.Error import Data.Text.Fusion (Step(..), Stream(..))-import Data.Text.Fusion.Internal (M(..), PairS(..), S(..)) import Data.Text.Fusion.Size import Data.Text.UnsafeChar (unsafeChr8) import Data.Word (Word8)@@ -47,51 +46,54 @@ import Control.Exception (assert) import qualified Data.ByteString.Internal as B +data S = S0+       | S1 {-# UNPACK #-} !Word8+       | S2 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+       | S3 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+       | S4 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8++data T = T {-# UNPACK #-} !ByteString {-# UNPACK #-} !S {-# UNPACK #-} !Int+ -- | /O(n)/ Convert a lazy 'ByteString' into a 'Stream Char', using -- UTF-8 encoding. streamUtf8 :: OnDecodeError -> ByteString -> Stream Char-streamUtf8 onErr bs0 = Stream next (bs0 :*: empty :*: 0) unknownSize-    where-      empty = S N N N N-      next (bs@(Chunk ps _) :*: S N _ _ _ :*: i)-          | i < len && U8.validate1 a =-              Yield (unsafeChr8 a) (bs :*: empty :*: i+1)-          | i + 1 < len && U8.validate2 a b =-              Yield (U8.chr2 a b) (bs :*: empty :*: i+2)-          | i + 2 < len && U8.validate3 a b c =-              Yield (U8.chr3 a b c) (bs :*: empty :*: i+3)-          | i + 4 < len && U8.validate4 a b c d =-              Yield (U8.chr4 a b c d) (bs :*: empty :*: i+4)-          where len = B.length ps-                a = B.unsafeIndex ps i-                b = B.unsafeIndex ps (i+1)-                c = B.unsafeIndex ps (i+2)-                d = B.unsafeIndex ps (i+3)-      next st@(bs :*: s :*: i) =-        case s of-          S (J a) N _ _             | U8.validate1 a ->-            Yield (unsafeChr8 a) es-          S (J a) (J b) N _         | U8.validate2 a b ->-            Yield (U8.chr2 a b) es-          S (J a) (J b) (J c) N     | U8.validate3 a b c ->-            Yield (U8.chr3 a b c) es-          S (J a) (J b) (J c) (J d) | U8.validate4 a b c d ->-            Yield (U8.chr4 a b c d) es-          _ -> consume st-         where es = bs :*: empty :*: i-      consume (bs@(Chunk ps rest) :*: s :*: i)-          | i >= B.length ps = consume (rest :*: s  :*: 0)-          | otherwise =-        case s of-          S N _ _ _ -> next (bs :*: S x N N N :*: i+1)-          S a N _ _ -> next (bs :*: S a x N N :*: i+1)-          S a b N _ -> next (bs :*: S a b x N :*: i+1)-          S a b c N -> next (bs :*: S a b c x :*: i+1)-          S (J a) b c d -> decodeError "streamUtf8" "UTF-8" onErr (Just a)-                           (bs :*: S b c d N :*: i+1)-          where x = J (B.unsafeIndex ps i)-      consume (Empty :*: S N _ _ _ :*: _) = Done-      consume st = decodeError "streamUtf8" "UTF-8" onErr Nothing st+streamUtf8 onErr bs0 = Stream next (T bs0 S0 0) unknownSize+  where+    next (T bs@(Chunk ps _) S0 i)+      | i < len && U8.validate1 a =+          Yield (unsafeChr8 a)    (T bs S0 (i+1))+      | i + 1 < len && U8.validate2 a b =+          Yield (U8.chr2 a b)     (T bs S0 (i+2))+      | i + 2 < len && U8.validate3 a b c =+          Yield (U8.chr3 a b c)   (T bs S0 (i+3))+      | i + 4 < len && U8.validate4 a b c d =+          Yield (U8.chr4 a b c d) (T bs S0 (i+4))+      where len = B.length ps+            a = B.unsafeIndex ps i+            b = B.unsafeIndex ps (i+1)+            c = B.unsafeIndex ps (i+2)+            d = B.unsafeIndex ps (i+3)+    next st@(T bs s i) =+      case s of+        S1 a       | U8.validate1 a       -> Yield (unsafeChr8 a)    es+        S2 a b     | U8.validate2 a b     -> Yield (U8.chr2 a b)     es+        S3 a b c   | U8.validate3 a b c   -> Yield (U8.chr3 a b c)   es+        S4 a b c d | U8.validate4 a b c d -> Yield (U8.chr4 a b c d) es+        _ -> consume st+       where es = T bs S0 i+    consume (T bs@(Chunk ps rest) s i)+        | i >= B.length ps = consume (T rest s 0)+        | otherwise =+      case s of+        S0         -> next (T bs (S1 x)       (i+1))+        S1 a       -> next (T bs (S2 a x)     (i+1))+        S2 a b     -> next (T bs (S3 a b x)   (i+1))+        S3 a b c   -> next (T bs (S4 a b c x) (i+1))+        S4 a b c d -> decodeError "streamUtf8" "UTF-8" onErr (Just a)+                           (T bs (S3 b c d)   (i+1))+        where x = B.unsafeIndex ps i+    consume (T Empty S0 _) = Done+    consume st             = decodeError "streamUtf8" "UTF-8" onErr Nothing st {-# INLINE [0] streamUtf8 #-}  -- | /O(n)/ Convert a 'Stream' 'Word8' to a lazy 'ByteString'.
Data/Text/Lazy/IO.hs view
@@ -8,7 +8,7 @@ -- Stability   : experimental -- Portability : GHC ----- Efficient locale-sensitive support for text I\/O.+-- Efficient locale-sensitive support for lazy text I\/O.  module Data.Text.Lazy.IO     (@@ -31,7 +31,7 @@     , putStrLn     ) where -import Data.Text.Lazy.Internal (Text(..))+import Data.Text.Lazy (Text) import Prelude hiding (appendFile, getContents, getLine, interact, putStr,                        putStrLn, readFile, writeFile) import System.IO (Handle, IOMode(..), hPutChar, openFile, stdin, stdout,@@ -39,13 +39,14 @@ import qualified Data.Text.IO as T import qualified Data.Text.Lazy as L #if __GLASGOW_HASKELL__ <= 610-import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)+import Data.Text.Lazy.Encoding (decodeUtf8) import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Lazy.Char8 as L8 #else import Control.Exception (throw) import Data.IORef (readIORef) import Data.Text.IO.Internal (hGetLineWith, readChunk)+import Data.Text.Lazy.Internal (chunk, empty) import GHC.IO.Buffer (isEmptyBuffer) import GHC.IO.Exception (IOException(..), IOErrorType(..), ioException) import GHC.IO.Handle.Internals (augmentIOError, hClose_help,@@ -55,9 +56,8 @@ import System.IO.Unsafe (unsafeInterleaveIO) #endif --- | The 'readFile' function reads a file and returns the contents of--- the file as a string.  The entire file is read strictly, as with--- 'getContents'.+-- | Read a file and return its contents as a string.  The file is+-- read lazily, as with 'getContents'. readFile :: FilePath -> IO Text readFile name = openFile name ReadMode >>= hGetContents @@ -70,6 +70,8 @@ appendFile :: FilePath -> Text -> IO () appendFile p = withFile p AppendMode . flip hPutStr +-- | Lazily read the remaining contents of a 'Handle'.  The 'Handle'+-- will be closed after the read completes, or on error. hGetContents :: Handle -> IO Text #if __GLASGOW_HASKELL__ <= 610 hGetContents = fmap decodeUtf8 . L8.hGetContents@@ -94,11 +96,11 @@    buf <- readIORef haCharBuffer    (do t <- readChunk hh buf        ts <- lazyRead h-       return (hh, Chunk t ts)) `catch` \e -> do+       return (hh, chunk t ts)) `catch` \e -> do          (hh', _) <- hClose_help hh          if isEOFError e            then return $ if isEmptyBuffer buf-                         then (hh', Empty)+                         then (hh', empty)                          else (hh', L.singleton '\r')            else throw (augmentIOError e "hGetContents" h) #endif@@ -121,12 +123,12 @@  -- | The 'interact' function takes a function of type @Text -> Text@ -- as its argument. The entire input from the standard input device is--- passed to this function as its argument, and the resulting string--- is output on the standard output device.+-- passed (lazily) to this function as its argument, and the resulting+-- string is output on the standard output device. interact :: (Text -> Text) -> IO () interact f = putStr . f =<< getContents --- | Read all user input on 'stdin' as a single string.+-- | Lazily read all user input on 'stdin' as a single string. getContents :: IO Text getContents = hGetContents stdin 
tests/Benchmarks.hs view
@@ -9,11 +9,14 @@ import Data.Char import qualified Codec.Binary.UTF8.Generic as UTF8 import qualified Data.Text as TS+import qualified Data.Text.IO as TS import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as TL import qualified Data.List as L import qualified Data.Text.Encoding as TS import qualified Data.Text.Lazy.Encoding as TL import qualified Criterion.MultiMap as M+import Control.DeepSeq import Criterion.Config import GHC.Base @@ -38,7 +41,8 @@     rnf (B b) = rnf b  main = do-  bsa <- BS.readFile "text/test/russian.txt"+  let dataFile = "text/test/russian.txt"+  bsa <- BS.readFile dataFile   let tsa     = TS.decodeUtf8 bsa       tsb     = TS.toUpper tsa       tla     = TL.fromChunks (TS.chunksOf 16376 tsa)@@ -191,6 +195,13 @@       , bench "bs" $ nf (BS.map f . BS.map f) bsa       , bench "bl" $ nf (BL.map f . BL.map f) bla       , bench "l" $ nf (L.map f . L.map f) la+      ],+      bgroup "readFile" [+        bench "ts" $ TS.readFile dataFile+      , bench "tl" $ nfIO (TL.readFile dataFile)+      , bench "bs" $ BS.readFile dataFile+      , bench "bl" $ nfIO (BL.length `fmap` BL.readFile dataFile)+      , bench "l" $ nfIO (length `fmap` readFile dataFile)       ],       bgroup "replicate char" [         bench "ts" $ nf (TS.replicate bsa_len) (TS.singleton c)
text.cabal view
@@ -1,5 +1,5 @@ name:           text-version:        0.7+version:        0.7.0.1 synopsis:       An efficient packed Unicode text type description:    An efficient packed Unicode text type. license:        BSD3@@ -11,7 +11,7 @@ copyright:      2008-2009 Tom Harper, 2009 Bryan O'Sullivan category:       Data, Text build-type:     Simple-cabal-version:  >= 1.2+cabal-version:  >= 1.2.3 extra-source-files:     README     TODO@@ -67,11 +67,14 @@    build-depends:     base       < 5,-    bytestring >= 0.9 && < 1.0,-    deepseq    >= 1.1.0.0+    bytestring >= 0.9 && < 1.0   if impl(ghc >= 6.10)     build-depends:-      ghc-prim, base >= 4+      ghc-prim, base >= 4, deepseq >= 1.1.0.0+    cpp-options: -DHAVE_DEEPSEQ+  else+    build-depends: extensible-exceptions+    extensions: PatternSignatures    -- gather extensive profiling data for now   ghc-prof-options: -auto-all