80 lines
2.5 KiB
Swift
80 lines
2.5 KiB
Swift
|
|
// MARK: - Start
|
|
|
|
/**
|
|
* Extended XML tree node for start tags -- includes attribute information.
|
|
* Appears `header.headerSize` bytes after a `XmlNode`.
|
|
*/
|
|
/// Header size: `ChunkHeader` (8B) + `XmlNode` (8B) + `20 Bytes`
|
|
public struct XmlStartElement: XmlNode {
|
|
let header: ChunkHeader
|
|
|
|
/// String of the full namespace of this element.
|
|
public let ns: StringPoolRef // UInt32
|
|
/// String name of this node if it is an `ELEMENT`; the raw character data if this is a `CDATA` node.
|
|
public let name: StringPoolRef // UInt32
|
|
/// Byte offset from the start of this structure where the attributes start.
|
|
let attributeStart: UInt16
|
|
/// Size of the `XmlAttribute` structures that follow.
|
|
let attributeSize: UInt16
|
|
/// Number of attributes associated with an `ELEMENT`.
|
|
/// These are available as an array of `XmlAttribute` structures immediately following this node.
|
|
public let attributeCount: UInt16
|
|
/// Index (1-based) of the "id" attribute. `0` if none.
|
|
public let idIndex: UInt16
|
|
/// Index (1-based) of the "class" attribute. `0` if none.
|
|
public let classIndex: UInt16
|
|
/// Index (1-based) of the "style" attribute. `0` if none.
|
|
public let styleIndex: UInt16
|
|
|
|
init(_ chunk: ChunkHeader) {
|
|
header = chunk
|
|
var br = header.byteReader(at: .startOfData) // skips XmlNode header
|
|
ns = br.read32()
|
|
name = br.read32()
|
|
attributeStart = br.read16()
|
|
attributeSize = br.read16()
|
|
attributeCount = br.read16()
|
|
idIndex = br.read16()
|
|
classIndex = br.read16()
|
|
styleIndex = br.read16()
|
|
}
|
|
|
|
// MARK: - Public methods
|
|
|
|
/// Generate and populate all attributes on the fly
|
|
public func attributes() throws -> [XmlAttribute] {
|
|
var br = header.byteReader(at: .startOfData)
|
|
let offset = br.index + Index(attributeStart)
|
|
let size = Index(attributeSize)
|
|
return try (0 ..< Index(attributeCount)).map {
|
|
br.index = offset + $0 * size
|
|
return try XmlAttribute(&br)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// MARK: - End
|
|
|
|
/**
|
|
* Extended XML tree node for element start/end nodes.
|
|
* Appears `header.headerSize` bytes after a `XmlNode`.
|
|
*/
|
|
/// Header size: `ChunkHeader` (8B) + `XmlNode` (8B) + `8 Bytes`
|
|
public struct XmlEndElement: XmlNode {
|
|
let header: ChunkHeader
|
|
|
|
/// String of the full namespace of this element.
|
|
public let ns: StringPoolRef // UInt32
|
|
/// String name of this node if it is an `ELEMENT`; the raw character data if this is a `CDATA` node.
|
|
public let name: StringPoolRef // UInt32
|
|
|
|
init(_ chunk: ChunkHeader) {
|
|
header = chunk
|
|
var br = header.byteReader(at: .startOfData) // skips XmlNode header
|
|
ns = br.read32()
|
|
name = br.read32()
|
|
}
|
|
}
|