    {-# LANGUAGE BangPatterns               #-}
    {-# LANGUAGE DeriveAnyClass             #-}
    {-# LANGUAGE DeriveDataTypeable         #-}
    {-# LANGUAGE DeriveGeneric              #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    -- | Efficient DOM data structure
    module Xeno.DOM.Internal
      ( Node(..)
      , Content(..)
      , name
      , attributes
      , contents
      , children
      ) where

    import           Control.DeepSeq
    import           Data.ByteString          (ByteString)
    import qualified Data.ByteString as S
    import           Data.Data                (Data, Typeable)
    import           Data.Vector.Unboxed      ((!))
    import qualified Data.Vector.Unboxed as UV

    --import Debug.Trace
    --trace _ a = a

    -- | Some XML nodes.
    data Node = Node !ByteString !Int !(UV.Vector Int)
      deriving (Node -> Node -> Bool
    (Node -> Node -> Bool) -> (Node -> Node -> Bool) -> Eq Node
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Node -> Node -> Bool
    == :: Node -> Node -> Bool
    $c/= :: Node -> Node -> Bool
    /= :: Node -> Node -> Bool
    Eq, Typeable Node
    Typeable Node =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Node -> c Node)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Node)
    -> (Node -> Constr)
    -> (Node -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Node))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Node))
    -> ((forall b. Data b => b -> b) -> Node -> Node)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Node -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Node -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Node -> m Node)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Node -> m Node)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Node -> m Node)
    -> Data Node
    Node -> Constr
    Node -> DataType
    (forall b. Data b => b -> b) -> Node -> Node
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Node -> u
    forall u. (forall d. Data d => d -> u) -> Node -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Node
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Node -> c Node
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Node)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Node)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Node -> c Node
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Node -> c Node
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Node
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Node
    $ctoConstr :: Node -> Constr
    toConstr :: Node -> Constr
    $cdataTypeOf :: Node -> DataType
    dataTypeOf :: Node -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Node)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Node)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Node)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Node)
    $cgmapT :: (forall b. Data b => b -> b) -> Node -> Node
    gmapT :: (forall b. Data b => b -> b) -> Node -> Node
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Node -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Node -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Node -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Node -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Node -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Node -> m Node
    Data, Typeable)

    instance NFData Node where
      rnf :: Node -> ()
    rnf !Node
    _ = ()

    instance Show Node where
      show :: Node -> String
    show Node
    n =
        String
    "(Node " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
        ByteString -> String
    forall a. Show a => a -> String
    show (Node -> ByteString
    name Node
    n) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
        String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [(ByteString, ByteString)] -> String
    forall a. Show a => a -> String
    show (Node -> [(ByteString, ByteString)]
    attributes Node
    n) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Content] -> String
    forall a. Show a => a -> String
    show (Node -> [Content]
    contents Node
    n) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ")"

    -- | Content of a node.
    data Content
      = Element {-# UNPACK #-}!Node
      | Text {-# UNPACK #-}!ByteString
      | CData {-# UNPACK #-}!ByteString
      deriving (Content -> Content -> Bool
    (Content -> Content -> Bool)
    -> (Content -> Content -> Bool) -> Eq Content
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Content -> Content -> Bool
    == :: Content -> Content -> Bool
    $c/= :: Content -> Content -> Bool
    /= :: Content -> Content -> Bool
    Eq, Int -> Content -> ShowS
    [Content] -> ShowS
    Content -> String
    (Int -> Content -> ShowS)
    -> (Content -> String) -> ([Content] -> ShowS) -> Show Content
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Content -> ShowS
    showsPrec :: Int -> Content -> ShowS
    $cshow :: Content -> String
    show :: Content -> String
    $cshowList :: [Content] -> ShowS
    showList :: [Content] -> ShowS
    Show, Typeable Content
    Typeable Content =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Content -> c Content)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Content)
    -> (Content -> Constr)
    -> (Content -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Content))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Content))
    -> ((forall b. Data b => b -> b) -> Content -> Content)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Content -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Content -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Content -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Content -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Content -> m Content)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Content -> m Content)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Content -> m Content)
    -> Data Content
    Content -> Constr
    Content -> DataType
    (forall b. Data b => b -> b) -> Content -> Content
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Content -> u
    forall u. (forall d. Data d => d -> u) -> Content -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Content
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Content -> c Content
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Content)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Content)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Content -> c Content
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Content -> c Content
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Content
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Content
    $ctoConstr :: Content -> Constr
    toConstr :: Content -> Constr
    $cdataTypeOf :: Content -> DataType
    dataTypeOf :: Content -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Content)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Content)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Content)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Content)
    $cgmapT :: (forall b. Data b => b -> b) -> Content -> Content
    gmapT :: (forall b. Data b => b -> b) -> Content -> Content
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Content -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Content -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Content -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Content -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Content -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Content -> m Content
    Data, Typeable)

    instance NFData Content where
      rnf :: Content -> ()
    rnf !Content
    _ = ()

    -- | Get just element children of the node (no text).
    children :: Node -> [Node]
    children :: Node -> [Node]
    children (Node ByteString
    str Int
    start Vector Int
    offsets) = Int -> [Node]
    collect Int
    firstChild
      where
        collect :: Int -> [Node]
    collect Int
    i
          | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    endBoundary =
            case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    i of
              Int
    0x00 -> ByteString -> Int -> Vector Int -> Node
    Node ByteString
    str Int
    i Vector Int
    offsets Node -> [Node] -> [Node]
    forall a. a -> [a] -> [a]
    : Int -> [Node]
    collect (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4))
              Int
    0x01 -> Int -> [Node]
    collect (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3)
              Int
    _off -> [] -- trace ("Offsets " <> show i <> " is " <> show off) []
          | Bool
    otherwise = []
        firstChild :: Int
    firstChild = Int -> Int
    go (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
          where
            go :: Int -> Int
    go Int
    i
              | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    endBoundary =
                case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    i of
                  Int
    0x02 -> Int -> Int
    go (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
                  Int
    _ -> Int
    i
              | Bool
    otherwise = Int
    i
        endBoundary :: Int
    endBoundary = Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4)

    -- | Contents of a node.
    contents :: Node -> [Content]
    contents :: Node -> [Content]
    contents (Node ByteString
    str Int
    start Vector Int
    offsets) = Int -> [Content]
    collect Int
    firstChild
      where
        collect :: Int -> [Content]
    collect Int
    i
          | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    endBoundary =
            case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    i of
              Int
    0x00 ->
                Node -> Content
    Element
                  (ByteString -> Int -> Vector Int -> Node
    Node ByteString
    str Int
    i Vector Int
    offsets) Content -> [Content] -> [Content]
    forall a. a -> [a] -> [a]
    :
                Int -> [Content]
    collect (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4))
              Int
    0x01 ->
                ByteString -> Content
    Text (ByteString -> Int -> Int -> ByteString
    substring ByteString
    str (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)) (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2))) Content -> [Content] -> [Content]
    forall a. a -> [a] -> [a]
    :
                Int -> [Content]
    collect (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3)
              Int
    0x03 ->
                ByteString -> Content
    CData (ByteString -> Int -> Int -> ByteString
    substring ByteString
    str (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)) (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2))) Content -> [Content] -> [Content]
    forall a. a -> [a] -> [a]
    :
                Int -> [Content]
    collect (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3)
              Int
    _ -> []
          | Bool
    otherwise = []
        firstChild :: Int
    firstChild = Int -> Int
    go (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
          where
            go :: Int -> Int
    go Int
    i | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    endBoundary =
              case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    i of
                Int
    0x02 -> Int -> Int
    go (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
                Int
    _ -> Int
    i
              | Bool
    otherwise = Int
    i
        endBoundary :: Int
    endBoundary = Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4)

    -- | Attributes of a node.
    attributes :: Node -> [(ByteString,ByteString)]
    attributes :: Node -> [(ByteString, ByteString)]
    attributes (Node ByteString
    str Int
    start Vector Int
    offsets) = Int -> [(ByteString, ByteString)]
    collect (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
      where
        collect :: Int -> [(ByteString, ByteString)]
    collect Int
    i
          | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    endBoundary =
            case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    i of
              Int
    0x02 ->
                ( ByteString -> Int -> Int -> ByteString
    substring ByteString
    str (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)) (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2))
                , ByteString -> Int -> Int -> ByteString
    substring ByteString
    str (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3)) (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4))) (ByteString, ByteString)
    -> [(ByteString, ByteString)] -> [(ByteString, ByteString)]
    forall a. a -> [a] -> [a]
    :
                Int -> [(ByteString, ByteString)]
    collect (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    5)
              Int
    _ -> []
          | Bool
    otherwise = []
        endBoundary :: Int
    endBoundary = Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    4)

    -- | Name of the element.
    name :: Node -> ByteString
    name :: Node -> ByteString
    name (Node ByteString
    str Int
    start Vector Int
    offsets) =
      case Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! Int
    start of
        Int
    0x00 -> ByteString -> Int -> Int -> ByteString
    substring ByteString
    str (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2)) (Vector Int
    offsets Vector Int -> Int -> Int
    forall a. Unbox a => Vector a -> Int -> a
    ! (Int
    start Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3))
        Int
    _ -> String -> ByteString
    forall a. HasCallStack => String -> a
    error String
    "Node cannot have empty name" -- mempty

    -- | Get a substring of the BS.
    substring :: ByteString -> Int -> Int -> ByteString
    substring :: ByteString -> Int -> Int -> ByteString
    substring ByteString
    s' Int
    start Int
    len = Int -> ByteString -> ByteString
    S.take Int
    len (Int -> ByteString -> ByteString
    S.drop Int
    start ByteString
    s')
    {-# INLINE substring #-}