module Text.XML.LibXML.Tree ( addChild , newChild , addSibling , newNode , newProperty , newText , newTextChild , newDocument , newDocumentPI , documentDumpMemory , newDocumentNode , setDocumentRootElement , getDocumentRootElement ) where import Foreign.C import Foreign import Control.Monad import Control.Monad.Trans import qualified Data.ByteString as BS import qualified Data.ByteString.Internal as BS import Data.ByteString (ByteString) import Text.XML.LibXML.Types import Text.XML.LibXML.Internals -- xmlNodePtr xmlAddChild (xmlNodePtr parent, xmlNodePtr cur) foreign import ccall unsafe xmlAddChild :: Ptr Node -> Ptr Node -> IO (Ptr Node) addChild :: MonadIO m => Node -> Node -> m () addChild parent cur = liftIO $ withNode parent $ \parentPtr -> withNode cur $ \curPtr -> do ret <- xmlAddChild parentPtr curPtr when (ret == nullPtr) $ error "Text.XML.LibXML.Tree.addChild: failed" return () --xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns, const xmlChar * name, const xmlChar * content) foreign import ccall unsafe xmlNewChild :: Ptr Node -> Ptr Namespace -> CString -> CString -> IO (Ptr Node) newChild :: MonadIO m => Node -> Maybe Namespace -> String -> Maybe String -> m Node newChild parent mbNs tag content = liftIO $ withNode parent $ \parentPtr -> maybeWith withNamespace mbNs $ \nsPtr -> withCString tag $ \ctag -> maybeWith withCString content $ \ccontent -> mkFinalizedNode =<< xmlNewChild parentPtr nsPtr ctag ccontent -- xmlNodePtr xmlAddNextSibling (xmlNodePtr parent, xmlNodePtr cur) -- xmlNodePtr xmlAddPrevSibling (xmlNodePtr parent, xmlNodePtr cur) -- xmlNodePtr xmlAddSibling (xmlNodePtr parent, xmlNodePtr cur) foreign import ccall unsafe xmlAddSibling :: Ptr Node -> Ptr Node -> IO (Ptr Node) addSibling :: MonadIO m => Node -> Node -> m () addSibling parent cur = liftIO $ withNode parent $ \parentPtr -> withNode cur $ \curPtr -> do xmlAddSibling parentPtr curPtr return () -- xmlNodePtr xmlNewNode (xmlNsPtr ns, const xmlChar * name) foreign import ccall unsafe xmlNewNode :: Ptr Namespace -> CString -> IO (Ptr Node) newNode :: MonadIO m => Maybe Namespace -> String -> m Node newNode mbNs tag = liftIO $ maybeWith withNamespace mbNs $ \nsPtr -> withCString tag $ \cstr -> do nodePtr <- xmlNewNode nsPtr cstr mkFinalizedNode nodePtr -- xmlNodePtr xmlNewNodeEatName (xmlNsPtr ns, const xmlChar * name) -- xmlAttrPtr xmlNewProp (xmlNodePtr node, const xmlChar * name, const xmlChar * value) foreign import ccall unsafe xmlNewProp :: Ptr Node -> CString -> CString -> IO (Ptr Property) newProperty :: MonadIO m => Node -> String -> String -> m () newProperty node name value = liftIO $ withNode node $ \nodePtr -> withCString name $ \namePtr -> withCString value $ \valuePtr -> do xmlNewProp nodePtr namePtr valuePtr return () -- xmlNodePtr xmlNewText (const xmlChar * content) foreign import ccall unsafe xmlNewText :: CString -> IO (Ptr Node) newText :: MonadIO m => String -> m Node newText str = liftIO $ do cstr <- newCString str nodePtr <- xmlNewText cstr mkFinalizedNode nodePtr -- xmlNodePtr xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns, const xmlChar * name, const xmlChar * content) foreign import ccall unsafe xmlNewTextChild :: Ptr Node -> Ptr Namespace -> CString -> CString -> IO (Ptr Node) newTextChild :: MonadIO m => Node -> Maybe Namespace -> String -> String -> m Node newTextChild parent mbNs name content = liftIO $ withNode parent $ \parentPtr -> maybeWith withNamespace mbNs $ \nsPtr -> withCString name $ \cname -> withCString content $ \ccontent -> mkFinalizedNode =<< xmlNewTextChild parentPtr nsPtr cname ccontent --xmlDocPtr xmlNewDoc(const xmlChar * version) foreign import ccall unsafe xmlNewDoc :: CString -> IO (Ptr Document) newDocument :: MonadIO m => String -- ^ Version -> m Document newDocument version = liftIO $ withCString version $ \cstr -> do docPtr <- xmlNewDoc cstr mkFinalizedDocument docPtr -- xmlNodePtr xmlNewDocPI(xmlDocPtr doc, const xmlChar * name, const xmlChar * content) foreign import ccall unsafe xmlNewDocPI :: Ptr Document -> CString -> CString -> IO (Ptr Node) newDocumentPI :: MonadIO m => Document -> String -> String -> m Node newDocumentPI doc name content = liftIO $ withDocument doc $ \docPtr -> withCString name $ \namePtr -> withCString content $ \contentPtr -> do nodePtr <- xmlNewDocPI docPtr namePtr contentPtr mkFinalizedNode nodePtr --void xmlDocDumpMemory(xmlDocPtr cur, xmlChar ** mem, int * size) foreign import ccall unsafe xmlDocDumpMemory :: Ptr Document -> Ptr CString -> Ptr CInt -> IO () documentDumpMemory :: MonadIO m => Document -> m ByteString documentDumpMemory doc = liftIO $ withDocument doc $ \docPtr -> alloca $ \strPtr -> alloca $ \lenPtr -> do xmlDocDumpMemory docPtr strPtr lenPtr cstr <- peek strPtr len <- peek lenPtr fp <- newForeignPtr finalizerFree (castPtr cstr) return $! BS.PS fp 0 (fromIntegral len) -- xmlNodePtr xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar * name, const xmlChar * content) foreign import ccall unsafe xmlNewDocNode :: Ptr Document -> Ptr Namespace -> CString -> CString -> IO (Ptr Node) newDocumentNode :: MonadIO m => Document -> Maybe Namespace -> String -> Maybe String -> m Node newDocumentNode doc mbNs tag mbContents = liftIO $ withDocument doc $ \docPtr -> maybeWith withNamespace mbNs $ \nsPtr -> withCString tag $ \ctag -> maybeWith withCString mbContents $ \ccontents -> do nodePtr <- xmlNewDocNode docPtr nsPtr ctag ccontents mkFinalizedNode nodePtr -- xmlNodePtr xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) foreign import ccall unsafe xmlDocSetRootElement :: Ptr Document -> Ptr Node -> IO (Ptr Node) setDocumentRootElement :: MonadIO m => Document -> Node -> m () setDocumentRootElement doc node = liftIO $ withDocument doc $ \docPtr -> withNode node $ \nodePtr -> do xmlDocSetRootElement docPtr nodePtr return () --xmlNodePtr xmlDocGetRootElement(xmlDocPtr doc) foreign import ccall unsafe xmlDocGetRootElement :: Ptr Document -> IO (Ptr Node) getDocumentRootElement :: MonadIO m => Document -> m Node getDocumentRootElement doc = liftIO $ withDocument doc $ \docPtr -> mkFinalizedNode =<< xmlDocGetRootElement docPtr