PureXML/Sources/Parsing/StreamingDecoderEUCTW.swift
Mihaela Mihaljevic 56e889f790 feat(parsing): EUC-TW (CNS 11643) decoding, closing #108
Add EUC-TW for the whole-buffer and streaming decoders: ASCII, a two-byte
plane-1 pair, and a 0x8E four-byte plane selector plus a pair. CNS planes 1
and 2, which carry essentially all real-world EUC-TW text, are vendored from
the ICU euc-tw-2014 mapping (private-use fallbacks dropped); planes 3-15 are a
documented follow-up. Tested for plane 1 (two-byte and four-byte forms), plane
2, and streaming. The streaming method moved to its own file to stay under the
type-body cap.

Closes #108
2026-06-09 17:44:22 +02:00

26 lines
1.1 KiB
Swift

extension PureXML.Parsing.StreamingDecoder {
/// Streams one EUC-TW character: ASCII, a two-byte plane-1 pair, or a `0x8E`
/// four-byte plane selector plus a pair.
mutating func nextEUCTW() -> Character? {
guard let lead = nextByte() else {
finished = true
return nil
}
if lead <= 0x7F { return Character(Unicode.Scalar(lead)) }
if lead == 0x8E {
guard let plane = nextByte(), let byte1 = nextByte(), let byte2 = nextByte() else {
finished = true
return Self.replacement
}
return PureXML.Parsing.ByteDecoder.EUCTW.fourByteScalar(plane, byte1, byte2).map(Character.init) ?? Self.replacement
}
guard (0xA1 ... 0xFE).contains(lead) else { return Self.replacement }
guard let trail = nextByte() else {
finished = true
return Self.replacement
}
let table = PureXML.Parsing.ByteDecoder.eucTWPlane1
return PureXML.Parsing.ByteDecoder.EUCTW.planeScalar(table, lead, trail).map(Character.init) ?? Self.replacement
}
}