NetNewsWire/Modules/Parser/Sources/SAX/HTMLEntityDecoder.swift

92 lines
1.7 KiB
Swift
Raw Normal View History

2024-09-15 00:40:27 +02:00
//
// HTMLEntityDecoder.swift
//
//
// Created by Brent Simmons on 9/14/24.
//
import Foundation
public final class HTMLEntityDecoder {
static func decodedString(withEncodedString encodedString: String) -> String {
let scanner = Scanner(string: encodedString)
scanner.charactersToBeSkipped = nil
var result = ""
var didDecodeAtLeastOneEntity = false
while true {
2024-09-15 23:26:01 +02:00
var scannedString: NSString? = nil
if scanner.scanUpTo("&", into: &scannedString) {
2024-09-15 00:40:27 +02:00
result.append(scannedString)
}
if scanner.isAtEnd {
break
}
let savedScanLocation = scanner.scanLocation
var decodedEntity: String? = nil
if scanner.scanEntityValue(&decodedEntity) {
result.append(decodedEntity)
didDecodeAtLeastOneEntity = true
}
else {
result.append("&")
scanner.scanLocation = savedScanLocation + 1
}
2024-09-15 23:26:01 +02:00
2024-09-15 00:40:27 +02:00
if scanner.isAtEnd {
break
}
}
if !didDecodeAtLeastOneEntity { // No changes made?
return encodedString
}
return result
}
}
2024-09-15 23:26:01 +02:00
/// Purpose-built version of NSScanner, which has deprecated the parts we want to use.
final class RSScanner {
let string: String
let count: Int
var scanLocation = 0
var isAtEnd {
scanLocation >= count - 1
}
init(string: String) {
self.string = string
self.count = string.count
}
/// Scans up to `characterToFind` and returns the characters up to (and not including) `characterToFind`.
/// - Returns: nil when there were no characters accumulated (next character was `characterToFind` or already at end of string)
func scanUpTo(_ characterToFind: Character) -> String? {
if isAtEnd {
return nil
}
while true {
}
}
private func currentCharacter() -> Character? {
}
private func
}