Permalink
Browse files

Data.Conduit.Binary.lines

  • Loading branch information...
1 parent a0e499f commit ca4ae25bf8266e7306b9f7015af1818a4a2e11e2 @snoyberg committed Jan 31, 2012
Showing with 36 additions and 0 deletions.
  1. +27 −0 conduit/Data/Conduit/Binary.hs
  2. +9 −0 conduit/test/main.hs
@@ -16,6 +16,7 @@ module Data.Conduit.Binary
, takeWhile
, dropWhile
, take
+ , Data.Conduit.Binary.lines
) where
import Prelude hiding (head, take, takeWhile, dropWhile)
@@ -273,3 +274,29 @@ dropWhile p =
-- Since 0.2.0
take :: Resource m => Int -> Sink S.ByteString m L.ByteString
take n = L.fromChunks `liftM` (isolate n =$ CL.consume)
+
+-- | Split the input bytes into lines. In other words, split on the LF byte
+-- (10), and strip it from the output.
+--
+-- Since 0.2.0
+lines :: Resource m => Conduit S.ByteString m S.ByteString
+lines =
+ conduitState id push close
+ where
+ push front bs' = return $ StateProducing leftover ls
+ where
+ bs = front bs'
+ (leftover, ls) = getLines id bs
+
+ getLines front bs
+ | S.null bs = (id, front [])
+ | S.null y = (S.append x, front [])
+ | otherwise = getLines (front . (x:)) (S.drop 1 y)
+ where
+ (x, y) = S.breakByte 10 bs
+
+ close front
+ | S.null bs = return []
+ | otherwise = return [bs]
+ where
+ bs = front S.empty
View
@@ -15,6 +15,7 @@ import qualified Data.List as DL
import Control.Monad.ST (runST)
import Data.Monoid
import qualified Data.ByteString as S
+import qualified Data.ByteString.Char8 as S8
import qualified Data.IORef as I
import qualified Data.ByteString.Lazy as L
import Data.ByteString.Lazy.Char8 ()
@@ -399,5 +400,13 @@ main = hspecX $ do
bsrc C.$= CB.isolate 10 C.$$ CL.head
x @?= Just "foobarbazb"
+ describe "binary" $ do
+ prop "lines" $ \bss' -> runST $ runResourceT $ do
+ let bss = map S.pack bss'
+ bs = S.concat bss
+ src = CL.sourceList bss
+ res <- src C.$$ CB.lines C.=$ CL.consume
+ return $ S8.lines bs == res
+
it' :: String -> IO () -> Specs
it' = it

0 comments on commit ca4ae25

Please sign in to comment.