6 -- |This is an auxiliary parser utilities. You usually don't have to
7 -- use this module directly.
8 module Network.HTTP.Lucu.Parser
13 import Blaze.ByteString.Builder (Builder, Write)
14 import qualified Blaze.ByteString.Builder as BB
15 import qualified Blaze.ByteString.Builder.Internal as BI
16 import Control.Applicative
17 import Control.Applicative.Unicode hiding ((∅))
18 import Control.Monad.Unicode
19 import qualified Data.ByteString as BS
20 import qualified Data.ByteString.Lazy as LS
22 import Data.Monoid.Unicode
24 import Prelude.Unicode
26 -- |@'atMost' n v@ is like @'P.many' v@ but accumulates @v@ at most
28 atMost ∷ Alternative f ⇒ Int → f a → f [a]
31 atMost n v = ( (:) <$> v ⊛ atMost (n-1) v )
38 , casLastChunk ∷ !Write
41 instance Monoid OctetAccumState where
48 {-# INLINEABLE mappend #-}
51 casChunks = casChunks a ⊕ lastChunk a ⊕ casChunks b
54 lastChunk ∷ OctetAccumState → Builder
55 {-# INLINEABLE lastChunk #-}
56 lastChunk !s = case toChunk s of
57 c → BB.insertByteString c
59 toChunk ∷ OctetAccumState → BS.ByteString
60 {-# INLINE toChunk #-}
61 toChunk = BB.toByteString ∘ BB.fromWrite ∘ casLastChunk
63 snoc ∷ OctetAccumState → Word8 → OctetAccumState
64 {-# INLINEABLE snoc #-}
66 | BI.getBound (casLastChunk s) ≥ BI.defaultBufferSize
68 casChunks = casChunks s ⊕ lastChunk s
69 , casLastChunk = BB.writeWord8 o
73 casLastChunk = casLastChunk s ⊕ BB.writeWord8 o
76 finish ∷ OctetAccumState → LS.ByteString
77 {-# INLINEABLE finish #-}
78 finish = BB.toLazyByteString ∘ toChunks
80 toChunks ∷ OctetAccumState → Builder
81 {-# INLINE toChunks #-}
82 toChunks !s = casChunks s ⊕ lastChunk s
84 -- |@'manyOctetsTill' p end@ takes as many octets untill @p@ succeeds.
85 manyOctetsTill ∷ ∀m b. (Monad m, Alternative m)
89 {-# INLINEABLE manyOctetsTill #-}
90 manyOctetsTill p end = scan (∅)
92 scan ∷ OctetAccumState → m LS.ByteString
95 = (end *> pure (finish s))
97 (scan =≪ (snoc s <$> p))