packages feed

bytestring 0.10.8.1 → 0.10.8.2

raw patch · 13 files changed

+223/−165 lines, 13 filesdep ~dlistnew-uploaderPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependency ranges changed: dlist

API changes (from Hackage documentation)

+ Data.ByteString: infixl 5 `snoc`
+ Data.ByteString: infixr 5 `cons`
+ Data.ByteString.Builder.Prim: infixl 4 >$<
+ Data.ByteString.Builder.Prim: infixr 5 >*<
+ Data.ByteString.Char8: infixl 5 `snoc`
+ Data.ByteString.Char8: infixr 5 `cons`
+ Data.ByteString.Lazy: infixl 5 `snoc`
+ Data.ByteString.Lazy: infixr 5 `cons'`
+ Data.ByteString.Lazy.Char8: infixl 5 `snoc`
+ Data.ByteString.Lazy.Char8: infixr 5 `cons'`

Files

Changelog.md view
@@ -1,3 +1,11 @@+0.10.8.2 Duncan Coutts <duncan@community.haskell.org> Feb 2017++ * Make readFile work for files with no size like /dev/null+ * Extend the cases in which concat and toStrict can avoid copying data+ * Fix building with ghc-7.0+ * Minor documentation improvements+ * Internal code cleanups+ 0.10.8.1 Duncan Coutts <duncan@community.haskell.org> May 2016   * Fix Builder output on big-endian architectures
Data/ByteString.hs view
@@ -217,7 +217,11 @@                                 ,scanl,scanl1,scanr,scanr1                                 ,readFile,writeFile,appendFile,replicate                                 ,getContents,getLine,putStr,putStrLn,interact-                                ,zip,zipWith,unzip,notElem)+                                ,zip,zipWith,unzip,notElem+#if !MIN_VERSION_base(4,6,0)+                                ,catch+#endif+                                )  #if MIN_VERSION_base(4,7,0) import Data.Bits                (finiteBitSize, shiftL, (.|.), (.&.))@@ -233,7 +237,7 @@ import Data.Word                (Word8) import Data.Maybe               (isJust) -import Control.Exception        (finally, bracket, assert, throwIO)+import Control.Exception        (IOException, catch, finally, assert, throwIO) import Control.Monad            (when)  import Foreign.C.String         (CString, CStringLen)@@ -251,7 +255,8 @@  -- hGetBuf and hPutBuf not available in yhc or nhc import System.IO                (stdin,stdout,hClose,hFileSize-                                ,hGetBuf,hPutBuf,openBinaryFile+                                ,hGetBuf,hPutBuf,hGetBufNonBlocking+                                ,hPutBufNonBlocking,withBinaryFile                                 ,IOMode(..)) import System.IO.Error          (mkIOError, illegalOperationErrorType) @@ -259,9 +264,6 @@ import Data.Monoid              (Monoid(..)) #endif --import System.IO                (hGetBufNonBlocking, hPutBufNonBlocking)- #if MIN_VERSION_base(4,3,0) import System.IO                (hGetBufSome) #else@@ -318,14 +320,14 @@ -- -- --- | /O(n)/ Convert a '[Word8]' into a 'ByteString'.+-- | /O(n)/ Convert a @['Word8']@ into a 'ByteString'. -- -- For applications with large numbers of string literals, pack can be a -- bottleneck. In such cases, consider using packAddress (GHC only). pack :: [Word8] -> ByteString pack = packBytes --- | /O(n)/ Converts a 'ByteString' to a '[Word8]'.+-- | /O(n)/ Converts a 'ByteString' to a @['Word8']@. unpack :: ByteString -> [Word8] unpack bs = build (unpackFoldr bs) {-# INLINE unpack #-}@@ -353,7 +355,7 @@ -- --------------------------------------------------------------------- -- | /O(1)/ 'length' returns the length of a ByteString as an 'Int'. length :: ByteString -> Int-length (PS _ _ l) = assert (l >= 0) $ l+length (PS _ _ l) = assert (l >= 0) l {-# INLINE length #-}  ------------------------------------------------------------------------@@ -472,7 +474,7 @@ -- | The 'transpose' function transposes the rows and columns of its -- 'ByteString' argument. transpose :: [ByteString] -> [ByteString]-transpose ps = P.map pack (List.transpose (P.map unpack ps))+transpose ps = P.map pack . List.transpose . P.map unpack $ ps  -- --------------------------------------------------------------------- -- Reducing 'ByteString's@@ -645,7 +647,7 @@ mapAccumL f acc (PS fp o len) = unsafeDupablePerformIO $ withForeignPtr fp $ \a -> do     gp   <- mallocByteString len     acc' <- withForeignPtr gp $ \p -> mapAccumL_ acc 0 (a `plusPtr` o) p-    return $! (acc', PS gp 0 len)+    return (acc', PS gp 0 len)   where     mapAccumL_ !s !n !p1 !p2        | n >= len = return s@@ -1042,12 +1044,12 @@ -- 'ByteString's and concatenates the list after interspersing the first -- argument between each element of the list. intercalate :: ByteString -> [ByteString] -> ByteString-intercalate s = concat . (List.intersperse s)+intercalate s = concat . List.intersperse s {-# INLINE [1] intercalate #-}  {-# RULES "ByteString specialise intercalate c -> intercalateByte" forall c s1 s2 .-    intercalate (singleton c) (s1 : s2 : []) = intercalateWithByte c s1 s2+    intercalate (singleton c) [s1, s2] = intercalateWithByte c s1 s2   #-}  -- | /O(n)/ intercalateWithByte. An efficient way to join to two ByteStrings@@ -1275,6 +1277,8 @@ -- | /O(n)/ The 'stripPrefix' function takes two ByteStrings and returns 'Just' -- the remainder of the second iff the first is its prefix, and otherwise -- 'Nothing'.+--+-- @since 0.10.8.0 stripPrefix :: ByteString -> ByteString -> Maybe ByteString stripPrefix bs1@(PS _ _ l1) bs2    | bs1 `isPrefixOf` bs2 = Just (unsafeDrop l1 bs2)@@ -1514,7 +1518,7 @@     let go 256 !_   = return ()         go i   !ptr = do n <- peekElemOff arr i                          when (n /= 0) $ memset ptr (fromIntegral i) n >> return ()-                         go (i + 1) (ptr `plusPtr` (fromIntegral n))+                         go (i + 1) (ptr `plusPtr` fromIntegral n)     go 0 p   where     -- | Count the number of occurrences of each byte.@@ -1535,9 +1539,10 @@  -- | /O(n) construction/ Use a @ByteString@ with a function requiring a -- null-terminated @CString@.  The @CString@ is a copy and will be freed--- automatically.+-- automatically; it must not be stored or used after the+-- subcomputation finishes. useAsCString :: ByteString -> (CString -> IO a) -> IO a-useAsCString (PS fp o l) action = do+useAsCString (PS fp o l) action =  allocaBytes (l+1) $ \buf ->    withForeignPtr fp $ \p -> do      memcpy buf (p `plusPtr` o) (fromIntegral l)@@ -1546,6 +1551,7 @@  -- | /O(n) construction/ Use a @ByteString@ with a function requiring a @CStringLen@. -- As for @useAsCString@ this function makes a copy of the original @ByteString@.+-- It must not be stored or used after the subcomputation finishes. useAsCStringLen :: ByteString -> (CStringLen -> IO a) -> IO a useAsCStringLen p@(PS _ _ l) f = useAsCString p $ \cstr -> f (cstr,l) @@ -1622,12 +1628,11 @@       -- if eol == True, then off is the offset of the '\n'       -- otherwise off == w and the buffer is now empty.         if off /= w-            then do if (w == off + 1)+            then do if w == off + 1                             then writeIORef haByteBuffer buf{ bufL=0, bufR=0 }                             else writeIORef haByteBuffer buf{ bufL = off + 1 }                     mkBigPS new_len (xs:xss)-            else do-                 fill h_ buf{ bufL=0, bufR=0 } new_len (xs:xss)+            else fill h_ buf{ bufL=0, bufR=0 } new_len (xs:xss)    -- find the end-of-line character, if there is one   findEOL r w raw@@ -1641,8 +1646,7 @@ mkPS :: RawBuffer Word8 -> Int -> Int -> IO ByteString mkPS buf start end =  create len $ \p ->-   withRawBuffer buf $ \pbuf -> do-   copyBytes p (pbuf `plusPtr` start) len+   withRawBuffer buf $ \pbuf -> copyBytes p (pbuf `plusPtr` start) len  where    len = end - start @@ -1820,24 +1824,30 @@ -- readFile :: FilePath -> IO ByteString readFile f =-    bracket (openBinaryFile f ReadMode) hClose $ \h -> do-      filesz <- hFileSize h+    withBinaryFile f ReadMode $ \h -> do+      -- hFileSize fails if file is not regular file (like+      -- /dev/null). Catch exception and try reading anyway.+      filesz <- catch (hFileSize h) useZeroIfNotRegularFile       let readsz = (fromIntegral filesz `max` 0) + 1       hGetContentsSizeHint h readsz (readsz `max` 255)       -- Our initial size is one bigger than the file size so that in the       -- typical case we will read the whole file in one go and not have       -- to allocate any more chunks. We'll still do the right thing if the       -- file size is 0 or is changed before we do the read.+  where+    useZeroIfNotRegularFile :: IOException -> IO Integer+    useZeroIfNotRegularFile _ = return 0 +modifyFile :: IOMode -> FilePath -> ByteString -> IO ()+modifyFile mode f txt = withBinaryFile f mode (`hPut` txt)+ -- | Write a 'ByteString' to a file. writeFile :: FilePath -> ByteString -> IO ()-writeFile f txt = bracket (openBinaryFile f WriteMode) hClose-    (\h -> hPut h txt)+writeFile = modifyFile WriteMode  -- | Append a 'ByteString' to a file. appendFile :: FilePath -> ByteString -> IO ()-appendFile f txt = bracket (openBinaryFile f AppendMode) hClose-    (\h -> hPut h txt)+appendFile = modifyFile AppendMode  -- --------------------------------------------------------------------- -- Internal utilities@@ -1876,7 +1886,7 @@  -- Find from the end of the string using predicate findFromEndUntil :: (Word8 -> Bool) -> ByteString -> Int-findFromEndUntil f ps@(PS x s l) =-    if null ps then 0-    else if f (unsafeLast ps) then l-         else findFromEndUntil f (PS x s (l-1))+findFromEndUntil f ps@(PS x s l)+  | null ps = 0+  | f (unsafeLast ps) = l+  | otherwise = findFromEndUntil f (PS x s (l - 1))
Data/ByteString/Builder/Internal.hs view
@@ -1,4 +1,8 @@ {-# LANGUAGE ScopedTypeVariables, CPP, BangPatterns, RankNTypes #-}+#if __GLASGOW_HASKELL__ == 700+-- This is needed as a workaround for an old bug in GHC 7.0.1 (Trac #4498)+{-# LANGUAGE MonoPatBinds #-}+#endif #if __GLASGOW_HASKELL__ >= 703 {-# LANGUAGE Unsafe #-} #endif@@ -92,7 +96,7 @@   , lazyByteStringCopy   , lazyByteStringInsert   , lazyByteStringThreshold-  +   , shortByteString    , maximalCopySize@@ -201,8 +205,8 @@ byteStringFromBuffer (Buffer fpbuf (BufferRange op _)) =     S.PS fpbuf 0 (op `minusPtr` unsafeForeignPtrToPtr fpbuf) ---- | Prepend the filled part of a 'Buffer' to a lazy 'L.ByteString'---- trimming it if necessary.+-- | Prepend the filled part of a 'Buffer' to a lazy 'L.ByteString'+-- trimming it if necessary. {-# INLINE trimmedChunkFromBuffer #-} trimmedChunkFromBuffer :: AllocationStrategy -> Buffer                        -> L.ByteString -> L.ByteString
Data/ByteString/Builder/Prim.hs view
@@ -1,5 +1,9 @@ {-# LANGUAGE CPP, BangPatterns, ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-}+#if __GLASGOW_HASKELL__ == 700+-- This is needed as a workaround for an old bug in GHC 7.0.1 (Trac #4498)+{-# LANGUAGE MonoPatBinds #-}+#endif #if __GLASGOW_HASKELL__ >= 701 {-# LANGUAGE Trustworthy #-} #endif
Data/ByteString/Char8.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP, BangPatterns #-}-{-# LANGUAGE MagicHash, UnboxedTuples #-}+{-# LANGUAGE MagicHash #-} {-# OPTIONS_HADDOCK prune #-} #if __GLASGOW_HASKELL__ >= 701 {-# LANGUAGE Trustworthy #-}@@ -248,6 +248,7 @@                        ,findSubstring,findSubstrings,breakSubstring,copy,group                         ,getLine, getContents, putStr, interact+                       ,readFile, writeFile, appendFile                        ,hGetContents, hGet, hGetSome, hPut, hPutStr                        ,hGetLine, hGetNonBlocking, hPutNonBlocking                        ,packCString,packCStringLen@@ -263,8 +264,7 @@ #endif import qualified Data.List as List (intersperse) -import System.IO    (Handle,stdout,openBinaryFile,hClose,hFileSize,IOMode(..))-import Control.Exception        (bracket)+import System.IO    (Handle,stdout) import Foreign  @@ -460,7 +460,7 @@ -- -- This implemenation uses @memset(3)@ replicate :: Int -> Char -> ByteString-replicate w = B.replicate w . c2w+replicate n = B.replicate n . c2w {-# INLINE replicate #-}  -- | /O(n)/, where /n/ is the length of the result.  The 'unfoldr'@@ -474,7 +474,7 @@ -- -- > unfoldr (\x -> if x <= '9' then Just (x, succ x) else Nothing) '0' == "0123456789" unfoldr :: (a -> Maybe (Char, a)) -> a -> ByteString-unfoldr f x0 = B.unfoldr (fmap k . f) x0+unfoldr f x = B.unfoldr (fmap k . f) x     where k (i, j) = (c2w i, j)  -- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a ByteString from a seed@@ -486,7 +486,7 @@ -- -- > unfoldrN n f s == take n (unfoldr f s) unfoldrN :: Int -> (a -> Maybe (Char, a)) -> a -> (ByteString, Maybe a)-unfoldrN n f w = B.unfoldrN n ((k `fmap`) . f) w+unfoldrN n f = B.unfoldrN n ((k `fmap`) . f)     where k (i,j) = (c2w i, j) {-# INLINE unfoldrN #-} @@ -877,7 +877,7 @@ -- after appending a terminating newline to each. unlines :: [ByteString] -> ByteString unlines [] = empty-unlines ss = (concat $ List.intersperse nl ss) `append` nl -- half as much space+unlines ss = concat (List.intersperse nl ss) `append` nl -- half as much space     where nl = singleton '\n'  -- | 'words' breaks a ByteString up into a list of words, which@@ -957,7 +957,7 @@            combine _ acc [] ps = (toInteger acc, ps)           combine d acc ns ps =-              ((10^d * combine1 1000000000 ns + toInteger acc), ps)+              (10^d * combine1 1000000000 ns + toInteger acc, ps)            combine1 _ [n] = n           combine1 b ns  = combine1 (b*b) $ combine2 b ns@@ -968,30 +968,11 @@ ------------------------------------------------------------------------ -- For non-binary text processing: --- | Read an entire file strictly into a 'ByteString'.  This is far more--- efficient than reading the characters into a 'String' and then using--- 'pack'.  It also may be more efficient than opening the file and--- reading it using hGet.-readFile :: FilePath -> IO ByteString-readFile f = bracket (openBinaryFile f ReadMode) hClose-    (\h -> hFileSize h >>= hGet h . fromIntegral)---- | Write a 'ByteString' to a file.-writeFile :: FilePath -> ByteString -> IO ()-writeFile f txt = bracket (openBinaryFile f WriteMode) hClose-    (\h -> hPut h txt)---- | Append a 'ByteString' to a file.-appendFile :: FilePath -> ByteString -> IO ()-appendFile f txt = bracket (openBinaryFile f AppendMode) hClose-    (\h -> hPut h txt)-- -- | Write a ByteString to a handle, appending a newline byte hPutStrLn :: Handle -> ByteString -> IO () hPutStrLn h ps     | length ps < 1024 = hPut h (ps `B.snoc` 0x0a)-    | otherwise        = hPut h ps >> hPut h (B.singleton (0x0a)) -- don't copy+    | otherwise        = hPut h ps >> hPut h (B.singleton 0x0a) -- don't copy  -- | Write a ByteString to stdout, appending a newline byte putStrLn :: ByteString -> IO ()
Data/ByteString/Internal.hs view
@@ -34,7 +34,6 @@         unpackBytes, unpackAppendBytesLazy, unpackAppendBytesStrict,         unpackChars, unpackAppendCharsLazy, unpackAppendCharsStrict,         unsafePackAddress,-        checkedSum,          -- * Low level imperative construction         create,                 -- :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString@@ -51,6 +50,7 @@          -- * Utilities         nullForeignPtr,         -- :: ForeignPtr Word8+        checkedAdd,             -- :: String -> Int -> Int -> Int          -- * Standard C Functions         c_strlen,               -- :: CString -> IO CInt@@ -76,17 +76,19 @@         inlinePerformIO               -- :: IO a -> a   ) where -import Prelude hiding (concat)+import Prelude hiding (concat, null) import qualified Data.List as List  import Foreign.ForeignPtr       (ForeignPtr, withForeignPtr) import Foreign.Ptr              (Ptr, FunPtr, plusPtr) import Foreign.Storable         (Storable(..))+ #if MIN_VERSION_base(4,5,0) || __GLASGOW_HASKELL__ >= 703 import Foreign.C.Types          (CInt(..), CSize(..), CULong(..)) #else import Foreign.C.Types          (CInt, CSize, CULong) #endif+ import Foreign.C.String         (CString)  #if MIN_VERSION_base(4,9,0)@@ -95,6 +97,7 @@ #if !(MIN_VERSION_base(4,8,0)) import Data.Monoid              (Monoid(..)) #endif+ import Control.DeepSeq          (NFData(rnf))  import Data.String              (IsString(..))@@ -107,25 +110,22 @@ import Data.Typeable            (Typeable) import Data.Data                (Data(..), mkNoRepType) -import GHC.Base                 (realWorld#,unsafeChr)+import GHC.Base                 (nullAddr#,realWorld#,unsafeChr)+ #if MIN_VERSION_base(4,4,0) import GHC.CString              (unpackCString#) #else import GHC.Base                 (unpackCString#) #endif+ import GHC.Prim                 (Addr#)-#if __GLASGOW_HASKELL__ >= 611-import GHC.IO                   (IO(IO))-#else-import GHC.IOBase               (IO(IO),RawBuffer)-#endif+ #if __GLASGOW_HASKELL__ >= 611-import GHC.IO                   (unsafeDupablePerformIO)+import GHC.IO                   (IO(IO),unsafeDupablePerformIO) #else-import GHC.IOBase               (unsafeDupablePerformIO)+import GHC.IOBase               (IO(IO),RawBuffer,unsafeDupablePerformIO) #endif -import GHC.Base                 (nullAddr#) import GHC.ForeignPtr           (ForeignPtr(ForeignPtr)                                 ,newForeignPtr_, mallocPlainForeignPtrBytes) import GHC.Ptr                  (Ptr(..), castPtr)@@ -168,7 +168,7 @@     mconcat = concat  instance NFData ByteString where-    rnf (PS _ _ _) = ()+    rnf PS{} = ()  instance Show ByteString where     showsPrec p ps r = showsPrec p (unpackChars ps) r@@ -180,7 +180,7 @@     fromString = packChars  instance Data ByteString where-  gfoldl f z txt = z packBytes `f` (unpackBytes txt)+  gfoldl f z txt = z packBytes `f` unpackBytes txt   toConstr _     = error "Data.ByteString.ByteString.toConstr"   gunfold _ _    = error "Data.ByteString.ByteString.gunfold"   dataTypeOf _   = mkNoRepType "Data.ByteString.ByteString"@@ -306,7 +306,7 @@  unpackAppendBytesStrict :: ByteString -> [Word8] -> [Word8] unpackAppendBytesStrict (PS fp off len) xs =-    accursedUnutterablePerformIO $ withForeignPtr fp $ \base -> do+    accursedUnutterablePerformIO $ withForeignPtr fp $ \base ->       loop (base `plusPtr` (off-1)) (base `plusPtr` (off-1+len)) xs   where     loop !sentinal !p acc@@ -343,7 +343,7 @@                -> Int -- ^ Offset                -> Int -- ^ Length                -> ByteString-fromForeignPtr fp s l = PS fp s l+fromForeignPtr = PS {-# INLINE fromForeignPtr #-}  -- | /O(1)/ Deconstruct a ForeignPtr from a ByteString@@ -418,15 +418,15 @@     withForeignPtr fp $ \p -> do         (off, l', res) <- f p         if assert (l' <= l) $ l' >= l-            then return $! (PS fp 0 l, res)+            then return (PS fp 0 l, res)             else do ps <- create l' $ \p' ->                             memcpy p' (p `plusPtr` off) l'-                    return $! (ps, res)+                    return (ps, res)  -- | Wrapper of 'mallocForeignPtrBytes' with faster implementation for GHC -- mallocByteString :: Int -> IO (ForeignPtr a)-mallocByteString l = mallocPlainForeignPtrBytes l+mallocByteString = mallocPlainForeignPtrBytes {-# INLINE mallocByteString #-}  ------------------------------------------------------------------------@@ -461,24 +461,63 @@       withForeignPtr fp2 $ \p2 -> memcpy destptr2 (p2 `plusPtr` off2) len2  concat :: [ByteString] -> ByteString-concat []     = mempty-concat [bs]   = bs-concat bss0   = unsafeCreate totalLen $ \ptr -> go bss0 ptr+concat = \bss0 -> goLen0 bss0 bss0+    -- The idea here is we first do a pass over the input list to determine:+    --+    --  1. is a copy necessary? e.g. @concat []@, @concat [mempty, "hello"]@,+    --     and @concat ["hello", mempty, mempty]@ can all be handled without+    --     copying.+    --  2. if a copy is necessary, how large is the result going to be?+    --+    -- If a copy is necessary then we create a buffer of the appropriate size+    -- and do another pass over the input list, copying the chunks into the+    -- buffer. Also, since foreign calls aren't entirely free we skip over+    -- empty chunks while copying.+    --+    -- We pass the original [ByteString] (bss0) through as an argument through+    -- goLen0, goLen1, and goLen since we will need it again in goCopy. Passing+    -- it as an explicit argument avoids capturing it in these functions'+    -- closures which would result in unnecessary closure allocation.   where-    totalLen = checkedSum "concat" [ len | (PS _ _ len) <- bss0 ]-    go []                  !_   = return ()-    go (PS fp off len:bss) !ptr = do+    -- It's still possible that the result is empty+    goLen0 _    []                     = mempty+    goLen0 bss0 (PS _ _ 0     :bss)    = goLen0 bss0 bss+    goLen0 bss0 (bs           :bss)    = goLen1 bss0 bs bss++    -- It's still possible that the result is a single chunk+    goLen1 _    bs []                  = bs+    goLen1 bss0 bs (PS _ _ 0  :bss)    = goLen1 bss0 bs bss+    goLen1 bss0 bs (PS _ _ len:bss)    = goLen bss0 (checkedAdd "concat" len' len) bss+      where PS _ _ len' = bs++    -- General case, just find the total length we'll need+    goLen bss0 !total (PS _ _ len:bss) = goLen bss0 total' bss+      where total' = checkedAdd "concat" total len+    goLen bss0 total [] =+      unsafeCreate total $ \ptr -> goCopy bss0 ptr++    -- Copy the data+    goCopy []                  !_   = return ()+    goCopy (PS _  _   0  :bss) !ptr = goCopy bss ptr+    goCopy (PS fp off len:bss) !ptr = do       withForeignPtr fp $ \p -> memcpy ptr (p `plusPtr` off) len-      go bss (ptr `plusPtr` len)+      goCopy bss (ptr `plusPtr` len)+{-# NOINLINE concat #-} --- | Add a list of non-negative numbers.  Errors out on overflow.-checkedSum :: String -> [Int] -> Int-checkedSum fun = go 0-  where go !a (x:xs)-            | ax >= 0   = go ax xs-            | otherwise = overflowError fun-          where ax = a + x-        go a  _         = a+{-# RULES+"ByteString concat [] -> mempty"+   concat [] = mempty+"ByteString concat [bs] -> bs" forall x.+   concat [x] = x+ #-}++-- | Add two non-negative numbers. Errors out on overflow.+checkedAdd :: String -> Int -> Int -> Int+checkedAdd fun x y+  | r >= 0    = r+  | otherwise = overflowError fun+  where r = x + y+{-# INLINE checkedAdd #-}  ------------------------------------------------------------------------ 
Data/ByteString/Lazy.hs view
@@ -229,14 +229,12 @@ import Data.Monoid              (Monoid(..)) #endif import Control.Monad            (mplus)- import Data.Word                (Word8) import Data.Int                 (Int64)-import System.IO                (Handle,stdin,stdout,openBinaryFile,IOMode(..)+import System.IO                (Handle,openBinaryFile,stdin,stdout,withBinaryFile,IOMode(..)                                 ,hClose) import System.IO.Error          (mkIOError, illegalOperationErrorType) import System.IO.Unsafe-import Control.Exception        (bracket)  import Foreign.ForeignPtr       (withForeignPtr) import Foreign.Ptr@@ -284,17 +282,40 @@ -- avoid converting back and forth between strict and lazy bytestrings. -- toStrict :: ByteString -> S.ByteString-toStrict Empty           = S.empty-toStrict (Chunk c Empty) = c-toStrict cs0 = S.unsafeCreate totalLen $ \ptr -> go cs0 ptr+toStrict = \cs -> goLen0 cs cs+    -- We pass the original [ByteString] (bss0) through as an argument through+    -- goLen0, goLen1, and goLen since we will need it again in goCopy. Passing+    -- it as an explicit argument avoids capturing it in these functions'+    -- closures which would result in unnecessary closure allocation.   where-    totalLen = S.checkedSum "Lazy.toStrict" . L.map S.length . toChunks $ cs0+    -- It's still possible that the result is empty+    goLen0 _   Empty                   = S.empty+    goLen0 cs0 (Chunk c cs) | S.null c = goLen0 cs0 cs+    goLen0 cs0 (Chunk c cs)            = goLen1 cs0 c cs -    go Empty                        !_       = return ()-    go (Chunk (S.PS fp off len) cs) !destptr =+    -- It's still possible that the result is a single chunk+    goLen1 _   bs Empty                = bs+    goLen1 cs0 bs (Chunk c cs)+      | S.null c                   = goLen1 cs0 bs cs+      | otherwise                  =+        goLen cs0 (S.checkedAdd "Lazy.concat" (S.length bs) (S.length c)) cs++    -- General case, just find the total length we'll need+    goLen cs0 !total (Chunk c cs)      = goLen cs0 total' cs+      where+        total' = S.checkedAdd "Lazy.concat" total (S.length c)+    goLen cs0 total Empty =+      S.unsafeCreate total $ \ptr -> goCopy cs0 ptr++    -- Copy the data+    goCopy Empty                        !_   = return ()+    goCopy (Chunk (S.PS _  _   0  ) cs) !ptr = goCopy cs ptr+    goCopy (Chunk (S.PS fp off len) cs) !ptr = do       withForeignPtr fp $ \p -> do-        S.memcpy destptr (p `plusPtr` off) len-        go cs (destptr `plusPtr` len)+        S.memcpy ptr (p `plusPtr` off) len+        goCopy cs (ptr `plusPtr` len)+-- See the comment on Data.ByteString.Internal.concat for some background on+-- this implementation.  ------------------------------------------------------------------------ @@ -478,7 +499,7 @@ -- (typically the right-identity of the operator), and a ByteString, -- reduces the ByteString using the binary operator, from right to left. foldr :: (Word8 -> a -> a) -> a -> ByteString -> a-foldr k z cs = foldrChunks (flip (S.foldr k)) z cs+foldr k z = foldrChunks (flip (S.foldr k)) z {-# INLINE foldr #-}  -- | 'foldl1' is a variant of 'foldl' that has no starting value@@ -555,7 +576,7 @@ -- passing an accumulating parameter from left to right, and returning a -- final value of this accumulator together with the new ByteString. mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)-mapAccumL f s0 cs0 = go s0 cs0+mapAccumL f s0 = go s0   where     go s Empty        = (s, Empty)     go s (Chunk c cs) = (s'', Chunk c' cs')@@ -567,7 +588,7 @@ -- passing an accumulating parameter from right to left, and returning a -- final value of this accumulator together with the new ByteString. mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)-mapAccumR f s0 cs0 = go s0 cs0+mapAccumR f s0 = go s0   where     go s Empty        = (s, Empty)     go s (Chunk c cs) = (s'', Chunk c' cs')@@ -638,13 +659,13 @@ -- prepending to the ByteString and @b@ is used as the next element in a -- recursive call. unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString-unfoldr f s0 = unfoldChunk 32 s0-  where unfoldChunk n s =-          case S.unfoldrN n f s of+unfoldr f z = unfoldChunk 32 z+  where unfoldChunk n x =+          case S.unfoldrN n f x of             (c, Nothing)               | S.null c  -> Empty               | otherwise -> Chunk c Empty-            (c, Just s')  -> Chunk c (unfoldChunk (n*2) s')+            (c, Just x')  -> Chunk c (unfoldChunk (n*2) x')  -- --------------------------------------------------------------------- -- Substrings@@ -781,7 +802,6 @@         comb acc (s:[]) Empty        = revChunks (s:acc) : []         comb acc (s:[]) (Chunk c cs) = comb (s:acc) (S.splitWith p c) cs         comb acc (s:ss) cs           = revChunks (s:acc) : comb [] ss cs- {-# INLINE splitWith #-}  -- | /O(n)/ Break a 'ByteString' into pieces separated by the byte@@ -807,7 +827,7 @@   where comb :: [P.ByteString] -> [P.ByteString] -> ByteString -> [ByteString]         comb acc (s:[]) Empty        = revChunks (s:acc) : []         comb acc (s:[]) (Chunk c cs) = comb (s:acc) (S.split w c) cs-        comb acc (s:ss) cs           = revChunks (s:acc) : comb [] ss cs+        comb acc (s:ss) cs        = revChunks (s:acc) : comb [] ss cs {-# INLINE split #-}  -- | The 'group' function takes a ByteString and returns a list of@@ -859,7 +879,7 @@ -- 'ByteString's and concatenates the list after interspersing the first -- argument between each element of the list. intercalate :: ByteString -> [ByteString] -> ByteString-intercalate s = concat . (L.intersperse s)+intercalate s = concat . L.intersperse s  -- --------------------------------------------------------------------- -- Indexing ByteStrings@@ -893,7 +913,8 @@ -- -- > elemIndexEnd c xs == -- > (-) (length xs - 1) `fmap` elemIndex c (reverse xs)-+--+-- @since 0.10.6.0 elemIndexEnd :: Word8 -> ByteString -> Maybe Int64 elemIndexEnd w = elemIndexEnd' 0   where@@ -1040,6 +1061,8 @@ -- | /O(n)/ The 'stripPrefix' function takes two ByteStrings and returns 'Just' -- the remainder of the second iff the first is its prefix, and otherwise -- 'Nothing'.+--+-- @since 0.10.8.0 stripPrefix :: ByteString -> ByteString -> Maybe ByteString stripPrefix Empty bs  = Just bs stripPrefix _ Empty  = Nothing@@ -1111,7 +1134,7 @@ inits :: ByteString -> [ByteString] inits = (Empty :) . inits'   where inits' Empty        = []-        inits' (Chunk c cs) = L.map (\c' -> Chunk c' Empty) (L.tail (S.inits c))+        inits' (Chunk c cs) = L.map (`Chunk` Empty) (L.tail (S.inits c))                            ++ L.map (Chunk c) (inits' cs)  -- | /O(n)/ Return all final segments of the given 'ByteString', longest first.@@ -1166,7 +1189,7 @@     loop = do         c <- S.hGetSome h k -- only blocks if there is no data available         if S.null c-          then do hClose h >> return Empty+          then hClose h >> return Empty           else do cs <- lazyRead                   return (Chunk c cs) @@ -1244,24 +1267,27 @@ readFile :: FilePath -> IO ByteString readFile f = openBinaryFile f ReadMode >>= hGetContents +modifyFile :: IOMode -> FilePath -> ByteString -> IO ()+modifyFile mode f txt = withBinaryFile f mode (`hPut` txt)+ -- | Write a 'ByteString' to a file. -- writeFile :: FilePath -> ByteString -> IO ()-writeFile f txt = bracket (openBinaryFile f WriteMode) hClose-    (\hdl -> hPut hdl txt)+writeFile = modifyFile WriteMode  -- | Append a 'ByteString' to a file. -- appendFile :: FilePath -> ByteString -> IO ()-appendFile f txt = bracket (openBinaryFile f AppendMode) hClose-    (\hdl -> hPut hdl txt)+appendFile = modifyFile AppendMode  -- | getContents. Equivalent to hGetContents stdin. Will read /lazily/ -- getContents :: IO ByteString getContents = hGetContents stdin --- | Outputs a 'ByteString' to the specified 'Handle'.+-- | Outputs a 'ByteString' to the specified 'Handle'. The chunks will be+-- written one at a time. Other threads might write to the 'Handle' between the+-- writes, and hence 'hPut' alone might not be suitable for concurrent writes. -- hPut :: Handle -> ByteString -> IO () hPut h cs = foldrChunks (\c rest -> S.hPut h c >> rest) (return ()) cs
Data/ByteString/Lazy/Char8.hs view
@@ -204,7 +204,8 @@         ,stripPrefix,stripSuffix         ,hGetContents, hGet, hPut, getContents         ,hGetNonBlocking, hPutNonBlocking-        ,putStr, hPutStr, interact)+        ,putStr, hPutStr, interact+        ,readFile,writeFile,appendFile)  -- Functions we need to wrap. import qualified Data.ByteString.Lazy as L@@ -225,8 +226,7 @@         ,readFile,writeFile,appendFile,replicate,getContents,getLine,putStr,putStrLn         ,zip,zipWith,unzip,notElem,repeat,iterate,interact,cycle) -import System.IO            (Handle,stdout,hClose,openBinaryFile,IOMode(..))-import Control.Exception    (bracket)+import System.IO            (Handle, stdout)  ------------------------------------------------------------------------ @@ -735,7 +735,7 @@ -- after appending a terminating newline to each. unlines :: [ByteString] -> ByteString unlines [] = empty-unlines ss = (concat $ List.intersperse nl ss) `append` nl -- half as much space+unlines ss = concat (List.intersperse nl ss) `append` nl -- half as much space     where nl = singleton '\n'  -- | 'words' breaks a ByteString up into a list of words, which@@ -781,10 +781,10 @@            {-# INLINE end #-}           end _   0 _ _  _ = Nothing-          end neg _ n c cs = e `seq` e+          end neg _ n c cs = e                 where n' = if neg then negate n else n                       c' = chunk c cs-                      e  = n' `seq` c' `seq` Just $! (n',c')+                      e  = n' `seq` c' `seq` Just (n',c')          --                  in n' `seq` c' `seq` JustS n' c'  @@ -840,30 +840,16 @@           end n c cs = let c' = chunk c cs                         in c' `seq` (n, c') --- | Read an entire file /lazily/ into a 'ByteString'.-readFile :: FilePath -> IO ByteString-readFile f = openBinaryFile f ReadMode >>= hGetContents --- | Write a 'ByteString' to a file.-writeFile :: FilePath -> ByteString -> IO ()-writeFile f txt = bracket (openBinaryFile f WriteMode) hClose-    (\hdl -> hPut hdl txt)---- | Append a 'ByteString' to a file.-appendFile :: FilePath -> ByteString -> IO ()-appendFile f txt = bracket (openBinaryFile f AppendMode) hClose-    (\hdl -> hPut hdl txt)-- -- | Write a ByteString to a handle, appending a newline byte -- hPutStrLn :: Handle -> ByteString -> IO () hPutStrLn h ps = hPut h ps >> hPut h (L.singleton 0x0a)  -- | Write a ByteString to stdout, appending a newline byte+-- putStrLn :: ByteString -> IO () putStrLn = hPutStrLn stdout-  -- --------------------------------------------------------------------- -- Internal utilities
Data/ByteString/Lazy/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} #if __GLASGOW_HASKELL__ >= 703 {-# LANGUAGE Unsafe #-}@@ -73,6 +73,7 @@ -- data ByteString = Empty | Chunk {-# UNPACK #-} !S.ByteString ByteString     deriving (Typeable)+-- See 'invariant' function later in this module for internal invariants.  instance Eq  ByteString where     (==)    = eq@@ -125,8 +126,7 @@       (bs, cs') -> Chunk bs (packChunks (min (n * 2) smallChunkSize) cs')  packChars :: [Char] -> ByteString-packChars cs0 =-    packChunks 32 cs0+packChars cs0 = packChunks 32 cs0   where     packChunks n cs = case S.packUptoLenChars n cs of       (bs, [])  -> chunk bs Empty@@ -218,9 +218,9 @@ eq _     Empty = False eq (Chunk a as) (Chunk b bs) =   case compare (S.length a) (S.length b) of-    LT -> a == (S.take (S.length a) b) && eq as (Chunk (S.drop (S.length a) b) bs)-    EQ -> a == b                       && eq as bs-    GT -> (S.take (S.length b) a) == b && eq (Chunk (S.drop (S.length b) a) as) bs+    LT -> a == S.take (S.length a) b && eq as (Chunk (S.drop (S.length a) b) bs)+    EQ -> a == b                     && eq as bs+    GT -> S.take (S.length b) a == b && eq (Chunk (S.drop (S.length b) a) as) bs  cmp :: ByteString -> ByteString -> Ordering cmp Empty Empty = EQ
Data/ByteString/Short/Internal.hs view
@@ -149,7 +149,7 @@     mconcat = concat  instance NFData ShortByteString where-    rnf (SBS {}) = ()+    rnf SBS{} = ()  instance Show ShortByteString where     showsPrec p ps r = showsPrec p (unpackChars ps) r@@ -161,7 +161,7 @@     fromString = packChars  instance Data ShortByteString where-  gfoldl f z txt = z packBytes `f` (unpackBytes txt)+  gfoldl f z txt = z packBytes `f` unpackBytes txt   toConstr _     = error "Data.ByteString.Short.ShortByteString.toConstr"   gunfold _ _    = error "Data.ByteString.Short.ShortByteString.gunfold"   dataTypeOf _   = mkNoRepType "Data.ByteString.Short.ShortByteString"@@ -320,8 +320,7 @@ -- (5 words per list element, 8 bytes per word, 100 elements = 4000 bytes)  unpackAppendCharsLazy :: ShortByteString -> [Char] -> [Char]-unpackAppendCharsLazy sbs cs0 =-    go 0 (length sbs) cs0+unpackAppendCharsLazy sbs cs0 = go 0 (length sbs) cs0   where     sz = 100 @@ -331,8 +330,7 @@                       where remainder = go (off+sz) (len-sz) cs  unpackAppendBytesLazy :: ShortByteString -> [Word8] -> [Word8]-unpackAppendBytesLazy sbs ws0 =-    go 0 (length sbs) ws0+unpackAppendBytesLazy sbs ws0 = go 0 (length sbs) ws0   where     sz = 100 @@ -347,8 +345,7 @@ -- buffer and loops down until we hit the sentinal:  unpackAppendCharsStrict :: ShortByteString -> Int -> Int -> [Char] -> [Char]-unpackAppendCharsStrict !sbs off len cs =-    go (off-1) (off-1 + len) cs+unpackAppendCharsStrict !sbs off len cs = go (off-1) (off-1 + len) cs   where     go !sentinal !i !acc       | i == sentinal = acc@@ -356,8 +353,7 @@                         in go sentinal (i-1) (c:acc)  unpackAppendBytesStrict :: ShortByteString -> Int -> Int -> [Word8] -> [Word8]-unpackAppendBytesStrict !sbs off len ws =-    go (off-1) (off-1 + len) ws+unpackAppendBytesStrict !sbs off len ws = go (off-1) (off-1 + len) ws   where     go !sentinal !i !acc       | i == sentinal = acc
Data/ByteString/Unsafe.hs view
@@ -260,6 +260,10 @@ -- to guarantee that the @ByteString@ is indeed null terminated. If in -- doubt, use @useAsCString@. --+-- * The memory may freed at any point after the subcomputation+-- terminates, so the pointer to the storage must *not* be used+-- after this.+-- unsafeUseAsCString :: ByteString -> (CString -> IO a) -> IO a unsafeUseAsCString (PS ps s _) ac = withForeignPtr ps $ \p -> ac (castPtr p `plusPtr` s) 
bytestring.cabal view
@@ -1,5 +1,5 @@ Name:                bytestring-Version:             0.10.8.1+Version:             0.10.8.2 Synopsis:            Fast, compact, strict and lazy byte strings with a list interface Description:     An efficient compact, immutable byte string type (both strict and lazy)@@ -200,7 +200,7 @@                     deepseq,                     QuickCheck                 >= 2.4,                     byteorder                  == 1.0.*,-                    dlist                      >= 0.5 && < 0.8,+                    dlist                      >= 0.5 && < 0.9,                     directory,                     mtl                        >= 2.0 && < 2.3,                     HUnit,
tests/Properties.hs view
@@ -2313,7 +2313,7 @@     , testProperty "reverse"            prop_reverse     , testProperty "reverse1"           prop_reverse1     , testProperty "reverse2"           prop_reverse2-    --, testProperty "transpose"          prop_transpose+--  , testProperty "transpose"          prop_transpose     , testProperty "foldl"              prop_foldl     , testProperty "foldl/reverse"      prop_foldl_1     , testProperty "foldr"              prop_foldr@@ -2331,7 +2331,7 @@     , testProperty "all"                prop_all     , testProperty "maximum"            prop_maximum     , testProperty "minimum"            prop_minimum-    , testProperty "replicate 1"        prop_replicate1+--  , testProperty "replicate 1"        prop_replicate1     , testProperty "replicate 2"        prop_replicate2     , testProperty "take"               prop_take1     , testProperty "drop"               prop_drop1