@@ -1,9 +1,11 @@
1+{-# LANGUAGE RecordWildCards #-}
12
23module Text.XML.Hexml(
34 Document, Node, Attribute(..),
45 parse, render, rootNode,
5− nodeInner, nodeOuter, nodeContents, nodeChildren, nodeAttributes,
6− nodeChildrenBy, nodeAttributeBy
6+ nodeName, nodeInner, nodeOuter,
7+ nodeAttributes, nodeChildren, nodeContents,
8+ nodeAttributeBy, nodeChildrenBy
79 ) where
810
911import Control.Monad
@@ -11,6 +13,7 @@ import Data.Int
1113import Foreign.C
1214import Foreign.Ptr
1315import Foreign.ForeignPtr
16+import Foreign.Storable
1417import System.IO.Unsafe
1518import Data.Monoid
1619import qualified Data.ByteString as BS
@@ -23,6 +26,12 @@ data CAttr
2326
2427data Str = Str {start :: {-# UNPACK #-} !Int32, length :: {-# UNPACK #-} !Int32}
2528
29+instance Storable Str where
30+ sizeOf _ = 8
31+ alignment _ = alignment (0 :: Int64)
32+ peek p = Str <$> peekByteOff p 0 <*> peekByteOff p 4
33+ poke p Str{..} = pokeByteOff p 0 start >> pokeByteOff p 4 length
34+
2635foreign import ccall document_parse :: CString -> CInt -> IO (Ptr CDocument)
2736foreign import ccall document_free :: Ptr CDocument -> IO ()
2837foreign import ccall "&document_free" document_free_funptr :: FunPtr (Ptr CDocument -> IO ())
@@ -30,6 +39,9 @@ foreign import ccall document_render :: Ptr CDocument -> CString -> CInt -> IO C
3039foreign import ccall document_error :: Ptr CDocument -> IO CString
3140foreign import ccall document_node :: Ptr CDocument -> IO (Ptr CNode)
3241
42+foreign import ccall node_children :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> Ptr CNode
43+foreign import ccall node_attributes :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> Ptr CAttr
44+
3345foreign import ccall node_firstChildBy :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO (Ptr CNode)
3446foreign import ccall node_nextChildBy :: Ptr CDocument -> Ptr CNode -> Ptr CNode -> CString -> CInt -> IO (Ptr CNode)
3547foreign import ccall node_attributeBy :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO (Ptr CAttr)
@@ -62,23 +74,33 @@ rootNode :: Document -> Node
6274rootNode d@(Document src doc) = unsafePerformIO $ withForeignPtr doc $ \d -> do
6375 Node src doc <$> document_node d
6476
77+applyStr :: BS.ByteString -> Str -> BS.ByteString
78+applyStr bs Str{..} = BS.take (fromIntegral length) $ BS.drop (fromIntegral start) bs
79+
80+nodePeek :: Int -> Node -> BS.ByteString
81+nodePeek i (Node src doc n) = unsafePerformIO $ withForeignPtr doc $ \_ -> do
82+ applyStr src <$> peekElemOff (castPtr n) i
83+
84+nodeName :: Node -> BS.ByteString
85+nodeName = nodePeek 0
86+
6587nodeInner :: Node -> BS.ByteString
66−nodeInner (Node src doc i) = undefined
88+nodeInner = nodePeek 1
6789
6890nodeOuter :: Node -> BS.ByteString
69−nodeOuter = undefined
91+nodeOuter = nodePeek 2
7092
7193nodeContents :: Node -> [Either Node BS.ByteString]
7294nodeContents = undefined
7395
7496nodeChildren :: Node -> [Node]
75−nodeChildren = undefined
97+nodeChildren = node_children `seq` undefined
7698
7799nodeAttributes :: Node -> [Attribute]
78−nodeAttributes = undefined
100+nodeAttributes = node_attributes `seq` undefined
79101
80102nodeChildrenBy :: Node -> BS.ByteString -> [Node]
81−nodeChildrenBy = undefined
103+nodeChildrenBy = node_firstChildBy `seq` node_nextChildBy `seq` undefined
82104
83105nodeAttributeBy :: Node -> BS.ByteString -> Maybe Attribute
84−nodeAttributeBy = undefined
106+nodeAttributeBy = node_attributeBy `seq` undefined