Browse files

First commit

  • Loading branch information...
0 parents commit 3adce71f79dc76202e64df53eda1beefab081445 @gregorycollins committed Mar 13, 2010
Showing with 148 additions and 0 deletions.
  1. +13 −0 .gitignore
  2. +27 −0 LICENSE
  3. +35 −0 attoparsec-iteratee.cabal
  4. +73 −0 src/Data/Attoparsec/Iteratee.hs
13 .gitignore
@@ -0,0 +1,13 @@
+*~
+dist/
+*.tix
+.hpc
+*.prof
+*.hi
+*.o
+*.swp
+#*#
+.#*
+.DS_Store
+**/.DS_Store
+docs/templates/out
27 LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2010, Gregory Collins
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Gregory Collins nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 attoparsec-iteratee.cabal
@@ -0,0 +1,35 @@
+name: attoparsec-iteratee
+version: 0.1
+synopsis: An adapter to convert attoparsec Parsers into blazing-fast Iteratees
+description:
+ An adapter to convert attoparsec Parsers into blazing-fast Iteratees
+license: BSD3
+license-file: LICENSE
+author: Gregory Collins
+maintainer: greg@gregorycollins.net
+build-type: Simple
+cabal-version: >= 1.6
+homepage: http://github.com/gregorycollins
+category: Data
+
+
+Library
+ hs-source-dirs: src
+
+ exposed-modules:
+ Data.Attoparsec.Iteratee
+
+ build-depends:
+ attoparsec >= 0.8 && < 0.9,
+ base >= 4 && < 5,
+ bytestring,
+ iteratee >= 0.3.1 && <0.4,
+ monads-fd,
+ transformers
+
+ ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2
+
+
+source-repository head
+ type: git
+ location: git://github.com/gregorycollins/attoparsec-iteratee.git
73 src/Data/Attoparsec/Iteratee.hs
@@ -0,0 +1,73 @@
+module Data.Attoparsec.Iteratee
+ ( parserToIteratee ) where
+
+
+------------------------------------------------------------------------------
+import qualified Data.Attoparsec as Atto
+import Data.Attoparsec hiding (many, Result(..))
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import Data.Iteratee
+import Data.Iteratee.WrappedByteString
+import Data.Word
+------------------------------------------------------------------------------
+
+type Stream = StreamG WrappedByteString Word8
+type IterV m = IterGV WrappedByteString Word8 m
+
+
+parserToIteratee :: (Monad m) =>
+ Parser a
+ -> IterateeG WrappedByteString Word8 m a
+parserToIteratee p = IterateeG $ f (\s -> parse p s)
+ where
+ f :: (Monad m) =>
+ (ByteString -> Atto.Result a)
+ -> Stream
+ -> m (IterV m a)
+ f k (EOF Nothing) = finalChunk $ k S.empty
+ f _ (EOF (Just e)) = reportError e
+ f k (Chunk s) = let s' = S.concat $ L.toChunks $ fromWrap s
+ in if S.null s'
+ then return $ Cont (IterateeG $ f k) Nothing
+ else chunk s' k
+
+
+ finalChunk :: (Monad m) => Atto.Result a -> m (IterV m a)
+ finalChunk (Atto.Fail _ _ m) =
+ return $ Cont (error $ show m)
+ (Just $ Err m)
+
+ finalChunk (Atto.Done rest r) =
+ return $ Done r (Chunk $ toWrap $ L.fromChunks [rest])
+
+ finalChunk (Atto.Partial _) =
+ return $ Cont (error "parser did not produce a value")
+ (Just $ Err "parser did not produce a value")
+
+ reportError e = return $ Cont (error $ show e) (Just e)
+
+ chunk :: (Monad m) =>
+ ByteString
+ -> (ByteString -> Atto.Result a)
+ -> m (IterV m a)
+ chunk s k = do
+ let r = k s
+ case r of
+ (Atto.Fail _ _ m) -> return $
+ Cont (throwErr (Err m)) (Just $ Err m)
+ (Atto.Done rest x) -> return $ Done x (Chunk $ toWrap $ L.fromChunks [rest])
+ (Atto.Partial z) -> return $
+ Cont (IterateeG $ f z) Nothing
+
+
+-- | lazy bytestring -> wrapped bytestring
+toWrap :: L.ByteString -> WrappedByteString Word8
+toWrap = WrapBS . S.concat . L.toChunks
+{-# INLINE toWrap #-}
+
+-- | wrapped bytestring -> lazy bytestring
+fromWrap :: WrappedByteString Word8 -> L.ByteString
+fromWrap = L.fromChunks . (:[]) . unWrap
+{-# INLINE fromWrap #-}

0 comments on commit 3adce71

Please sign in to comment.