You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.2 KiB

14 years ago
module Network.XMPP.Monad where
14 years ago
import Control.Applicative((<$>))
14 years ago
import Control.Monad.Trans
import Control.Monad.Trans.State
import Data.Conduit
14 years ago
import Data.Conduit.Text as CT
import Data.Conduit.Binary as CB
14 years ago
import Data.Conduit.List as CL
import Data.XML.Types
import Data.Default
import Data.Text
14 years ago
import Network.XMPP.Types
import Network.XMPP.Marshal
14 years ago
import System.IO
import Text.XML.Stream.Elements
14 years ago
import Text.XML.Stream.Render as XR
import Text.XML.Stream.Parse
14 years ago
type XMPPMonad a = StateT XMPPState (ResourceT IO) a
data XMPPState = XMPPState
14 years ago
{ sConSrc :: BufferedSource IO Event
, sConSink :: Sink Event IO ()
, sConHandle :: Maybe Handle
14 years ago
, sFeatures :: ServerFeatures
14 years ago
, sHaveTLS :: Bool
14 years ago
, sHostname :: Text
14 years ago
, sUsername :: Text
, sResource :: Maybe Text
14 years ago
}
data ServerFeatures = SF
{ stls :: Bool
, stlsRequired :: Bool
, saslMechanisms :: [Text]
, other :: [Element]
} deriving Show
instance Default ServerFeatures where
def = SF
{ stls = False
, stlsRequired = False
, saslMechanisms = []
, other = []
}
14 years ago
pushE :: Element -> XMPPMonad ()
pushE x = do
sink <- gets sConSink
14 years ago
lift $ CL.sourceList (elementToEvents x) $$ sink
14 years ago
push :: Stanza -> XMPPMonad ()
push = pushE . stanzaToElement
14 years ago
pushOpen :: Element -> XMPPMonad ()
pushOpen x = do
14 years ago
sink <- gets sConSink
14 years ago
lift $ CL.sourceList (elementToEvents' x) $$ sink
pulls :: Sink Event IO a -> XMPPMonad a
pulls snk = do
14 years ago
source <- gets sConSrc
14 years ago
lift $ source $$ snk
14 years ago
pullE :: XMPPMonad Element
pullE = do
source <- gets sConSrc
14 years ago
pulls elementFromEvents
14 years ago
14 years ago
pull :: XMPPMonad Stanza
pull = elementToStanza <$> pullE
14 years ago
xmppFromHandle handle hostname username resource f = runResourceT $ do
liftIO $ hSetBuffering handle NoBuffering
src <- bufferSource $ CB.sourceHandle handle $= CT.decode CT.utf8 $= parseText def
let st = XMPPState
src
(XR.renderBytes def =$ CB.sinkHandle handle)
(Just handle)
def
False
hostname
username
resource
runStateT f st