Files
AndroidXML/Sources/AndroidXML/XmlElement.swift
2025-11-25 22:46:14 +01:00

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()
}
}