diff options
Diffstat (limited to 'Presence/XMLToByteStrings.hs')
-rw-r--r-- | Presence/XMLToByteStrings.hs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/Presence/XMLToByteStrings.hs b/Presence/XMLToByteStrings.hs new file mode 100644 index 00000000..d8d2e965 --- /dev/null +++ b/Presence/XMLToByteStrings.hs | |||
@@ -0,0 +1,64 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | module XMLToByteStrings (xmlToByteStrings) where | ||
3 | |||
4 | import Control.Monad.IO.Class | ||
5 | import Control.Monad.Trans.Class | ||
6 | import Control.Monad.Trans.Maybe | ||
7 | import Control.Monad.Fix | ||
8 | import Control.Monad (when) | ||
9 | import Data.Conduit | ||
10 | import qualified Data.Conduit.List as CL | ||
11 | import Data.XML.Types as XML (Event) | ||
12 | import qualified Data.ByteString as S (ByteString) | ||
13 | #ifdef RENDERFLUSH | ||
14 | import Data.Conduit.Blaze (builderToByteStringFlush) | ||
15 | import Text.XML.Stream.Render (def,renderBuilderFlush) | ||
16 | #else | ||
17 | import Text.XML.Stream.Render (def,renderBytes) | ||
18 | #endif | ||
19 | |||
20 | fixMaybeT f = (>> return ()) . runMaybeT . fix $ f | ||
21 | mawait :: Monad m => MaybeT (ConduitM i o m) i | ||
22 | mawait = MaybeT await | ||
23 | |||
24 | |||
25 | xmlToByteStrings :: | ||
26 | ( MonadUnsafeIO m | ||
27 | , MonadIO m) => | ||
28 | Source m [XML.Event] -> Sink S.ByteString m b -> m b | ||
29 | xmlToByteStrings xmlSource snk | ||
30 | #ifdef RENDERFLUSH | ||
31 | = xmlSource | ||
32 | $$ flushList | ||
33 | =$= renderBuilderFlush def | ||
34 | =$= builderToByteStringFlush | ||
35 | =$= discardFlush | ||
36 | =$ snk | ||
37 | #else | ||
38 | = xmlSource $$ renderChunks =$ snk | ||
39 | #endif | ||
40 | |||
41 | #ifdef RENDERFLUSH | ||
42 | flushList :: Monad m => ConduitM [a] (Flush a) m () | ||
43 | flushList = fixMaybeT $ \loop -> do | ||
44 | xs <- mawait | ||
45 | lift ( CL.sourceList xs $$ CL.mapM_ (yield . Chunk) ) | ||
46 | lift ( yield Flush ) | ||
47 | loop | ||
48 | |||
49 | discardFlush :: Monad m => ConduitM (Flush a) a m () | ||
50 | discardFlush = fixMaybeT $ \loop -> do | ||
51 | x <- mawait | ||
52 | let unchunk (Chunk a) = a | ||
53 | ischunk (Chunk _) = True | ||
54 | ischunk _ = False | ||
55 | lift . when (ischunk x) $ yield (unchunk x) | ||
56 | loop | ||
57 | #else | ||
58 | renderChunks :: (MonadUnsafeIO m, MonadIO m) => ConduitM [Event] S.ByteString m () | ||
59 | renderChunks = fixMaybeT $ \loop -> do | ||
60 | xs <- mawait | ||
61 | lift . when (not . null $ xs) $ ( CL.sourceList xs $= renderBytes def $$ CL.mapM_ yield ) | ||
62 | loop | ||
63 | #endif | ||
64 | |||