Create separate SAX target.

This commit is contained in:
Brent Simmons
2024-08-26 20:53:57 -07:00
parent e7a82376b0
commit d13014787a
10 changed files with 78 additions and 776 deletions

View File

@@ -12,6 +12,10 @@ let package = Package(
name: "Parser",
type: .dynamic,
targets: ["Parser"]),
.library(
name: "SAX",
type: .dynamic,
targets: ["SAX"])
],
dependencies: [
],
@@ -20,6 +24,14 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "Parser",
dependencies: [
"SAX"
],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")
]),
.target(
name: "SAX",
dependencies: [],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")

View File

@@ -76,7 +76,7 @@ private extension OPMLParser {
extension OPMLParser: SAXParserDelegate {
func saxParser(_ saxParser: SAXParser, xmlStartElement localName: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafeMutablePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafeMutablePointer<XMLPointer?>?) {
func saxParser(_ saxParser: SAXParser, xmlStartElement localName: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafePointer<XMLPointer?>?) {
if SAXEqualStrings(localName, XMLKey.title) {
saxParser.beginStoringCharacters()

View File

@@ -0,0 +1,54 @@
////
//// SAXHTMLParser.swift
////
////
//// Created by Brent Simmons on 8/26/24.
////
//
//import Foundation
//import libxml2
//
//protocol SAXHTMLParserDelegate: AnyObject {
//
// func saxParser(_: SAXHTMLParser, XMLStartElement localName: XMLPointer, attributes: UnsafePointer<XMLPointer?>?)
//
// func saxParser(_: SAXHTMLParser, XMLEndElement localName: XMLPointer?)
//
// // Length is guaranteed to be greater than 0.
// func saxParser(_: SAXHTMLParser, XMLCharactersFound characters: XMLPointer?, length: Int)
//}
//
//final class SAXHTMLParser {
//
// fileprivate let delegate: SAXHTMLParserDelegate
// private var data: Data
//
// init(delegate: SAXHTMLParserDelegate, data: Data) {
//
// self.delegate = delegate
// self.data = data
// }
//
// func parse() {
//
// guard !data.isEmpty else {
// return
// }
//
// data.withUnsafeBytes { bufferPointer in
//
// guard let bytes = bufferPointer.bindMemory(to: xmlChar.self).baseAddress else {
// return
// }
//
// let characterEncoding = xmlDetectCharEncoding(bytes, Int32(data.count))
// let context = htmlCreatePushParserCtxt(&saxHandlerStruct, Unmanaged.passUnretained(self).toOpaque(), nil, 0, nil, characterEncoding)
// htmlCtxtUseOptions(context, Int32(XML_PARSE_RECOVER | XML_PARSE_NONET | HTML_PARSE_COMPACT))
//
// htmlParseChunk(context, bytes, Int32(data.count), 0)
//
// htmlParseChunk(context, nil, 0, 1)
// htmlFreeParserCtxt(context)
// }
// }
//}

View File

@@ -12,7 +12,7 @@ typealias XMLPointer = UnsafePointer<xmlChar>
protocol SAXParserDelegate {
func saxParser(_: SAXParser, xmlStartElement: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafeMutablePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafeMutablePointer<XMLPointer?>?)
func saxParser(_: SAXParser, xmlStartElement: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafePointer<XMLPointer?>?)
func saxParser(_: SAXParser, xmlEndElement: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?)
@@ -69,8 +69,8 @@ final class SAXParser {
xmlCtxtUseOptions(context, Int32(XML_PARSE_RECOVER.rawValue | XML_PARSE_NOENT.rawValue))
data.withUnsafeBytes { bufferPointer in
if let bytes = bufferPointer.bindMemory(to: CChar.self).baseAddress {
xmlParseChunk(context, bytes, CInt(data.count), 0)
if let bytes = bufferPointer.bindMemory(to: xmlChar.self).baseAddress {
xmlParseChunk(context, bytes, Int32(data.count), 0)
}
}
@@ -110,16 +110,16 @@ final class SAXParser {
var attributeName = String(cString: attribute)
if let prefix {
let attributePrefix = String(cString: prefix)
attributeName = "\(attributePrefix):\(attributeName!)"
attributeName = "\(attributePrefix):\(attributeName)"
}
guard let valueStart = attributes[j + 3], let valueEnd = attributes[j + 4] else {
continue
}
let valueCount = valueEnd - valueStart
var value = String(bytes: UnsafeRawBufferPointer(start: valueStart, count: Int(valueCount)), encoding: .utf8)
let value = String(bytes: UnsafeRawBufferPointer(start: valueStart, count: Int(valueCount)), encoding: .utf8)
if let value, let attributeName {
if let value {
dictionary[attributeName] = value
}
@@ -129,12 +129,6 @@ final class SAXParser {
return dictionary
}
func stringNoCopy(_ bytes: XMLPointer) -> String {
let length = strlen(bytes)
return NSString(bytesNoCopy: bytes, length: length, encoding: .utf8, freeWhenDone: false) as String
}
}
private extension SAXParser {
@@ -148,7 +142,7 @@ private extension SAXParser {
delegate.saxParser(self, xmlCharactersFound: xmlCharacters, count: count)
}
func startElement(_ name: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafeMutablePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafeMutablePointer<XMLPointer?>?) {
func startElement(_ name: XMLPointer, prefix: XMLPointer?, uri: XMLPointer?, namespaceCount: Int, namespaces: UnsafePointer<XMLPointer?>?, attributeCount: Int, attributesDefaultedCount: Int, attributes: UnsafePointer<XMLPointer?>?) {
delegate.saxParser(self, xmlStartElement: name, prefix: prefix, uri: uri, namespaceCount: namespaceCount, namespaces: namespaces, attributeCount: attributeCount, attributesDefaultedCount: attributesDefaultedCount, attributes: attributes)
}
@@ -160,7 +154,7 @@ private extension SAXParser {
}
}
private func startElement(_ context: UnsafeMutableRawPointer?, name: XMLPointer?, prefix: XMLPointer?, URI: XMLPointer?, nb_namespaces: CInt, namespaces: UnsafeMutablePointer<XMLPointer?>?, nb_attributes: CInt, nb_defaulted: CInt, attributes: UnsafeMutablePointer<XMLPointer?>?) {
private func startElement(_ context: UnsafeMutableRawPointer?, name: XMLPointer?, prefix: XMLPointer?, URI: XMLPointer?, nb_namespaces: CInt, namespaces: UnsafePointer<XMLPointer?>?, nb_attributes: CInt, nb_defaulted: CInt, attributes: UnsafeMutablePointer<XMLPointer?>?) {
guard let context, let name else {
return

View File

@@ -10,9 +10,9 @@ import libxml2
func SAXEqualStrings(_ s1: XMLPointer, _ s2: XMLPointer, length: Int? = nil) -> Bool {
if length == nil {
return Bool(xmlStrEqual(s1, s2))
if let length {
return xmlStrncmp(s1, s2, Int32(length)) == 0
}
return xmlStrncmp(s1, s2, length) == 0
return xmlStrEqual(s1, s2) != 0
}