@@ -1,4 +1,4 @@
1−{-# LANGUAGE CPP, BangPatterns #-}
1+{-# LANGUAGE CPP, BangPatterns, ScopedTypeVariables #-}
22-- |
33-- Module : Data.Attoparsec.Internal
44-- Copyright : Bryan O'Sullivan 2007-2014
@@ -15,8 +15,12 @@ module Data.Attoparsec.Internal
1515 ( compareResults
1616 , prompt
1717 , demandInput
18+ , wantInput
19+ , endOfInput
20+ , atEnd
1821 ) where
1922
23+import Control.Applicative ((<$>))
2024#if __GLASGOW_HASKELL__ >= 700
2125import Data.ByteString (ByteString)
2226import Data.Text (Text)
@@ -74,3 +78,37 @@ demandInput = Parser $ \t pos more lose succ ->
7478{-# SPECIALIZE demandInput :: Parser ByteString () #-}
7579{-# SPECIALIZE demandInput :: Parser Text () #-}
7680#endif
81+
82+-- | This parser always succeeds. It returns 'True' if any input is
83+-- available either immediately or on demand, and 'False' if the end
84+-- of all input has been reached.
85+wantInput :: forall t . Chunk t => Parser t Bool
86+wantInput = Parser $ \t pos more _lose succ ->
87+ case () of
88+ _ | pos < atBufferEnd (undefined :: t) t -> succ t pos more True
89+ | more == Complete -> succ t pos more False
90+ | otherwise -> let lose' t' pos' more' = succ t' pos' more' False
91+ succ' t' pos' more' = succ t' pos' more' True
92+ in prompt t pos more lose' succ'
93+{-# INLINE wantInput #-}
94+
95+-- | Match only if all input has been consumed.
96+endOfInput :: forall t . Chunk t => Parser t ()
97+endOfInput = Parser $ \t pos more lose succ ->
98+ case () of
99+ _| pos < atBufferEnd (undefined :: t) t -> lose t pos more [] "endOfInput"
100+ | more == Complete -> succ t pos more ()
101+ | otherwise ->
102+ let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()
103+ succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"
104+ in runParser demandInput t pos more lose' succ'
105+#if __GLASGOW_HASKELL__ >= 700
106+{-# SPECIALIZE endOfInput :: Parser ByteString () #-}
107+{-# SPECIALIZE endOfInput :: Parser Text () #-}
108+#endif
109+
110+-- | Return an indication of whether the end of input has been
111+-- reached.
112+atEnd :: Chunk t => Parser t Bool
113+atEnd = not <$> wantInput
114+{-# INLINE atEnd #-}