pub struct SniffResult {
pub byte_order_guess: Option<ByteOrderGuess>,
pub bom_len: usize,
pub declared_label: Option<String>,
pub declared_encoding: Option<Encoding>,
}Expand description
The result of sniff_xml_encoding: everything the Appendix F heuristic could determine
about an entity’s encoding from its leading bytes and (if reachable) its XML declaration.
Fields§
§byte_order_guess: Option<ByteOrderGuess>The coarse family implied by the entity’s first bytes, or None if none of the
Appendix F patterns matched (which, per the spec, itself implies UTF-8 or an
ASCII-compatible encoding: see SniffResult::best_effort_encoding).
bom_len: usizeThe number of leading bytes identified as a byte-order mark; 0 if none was present.
These bytes are not included in declared_label
scanning and should be skipped before decoding the entity itself.
declared_label: Option<String>The raw label text captured from an encoding="..." (or encoding='...') pseudo-attribute
in the XML declaration, if the prologue could be scanned and one was found.
declared_encoding: Option<Encoding>declared_label resolved through Encoding::for_label,
if it was present and recognized.
Implementations§
Source§impl SniffResult
impl SniffResult
Sourcepub fn best_effort_encoding(&self) -> Encoding
pub fn best_effort_encoding(&self) -> Encoding
A reasonable single Encoding to start decoding with, combining everything this
SniffResult discovered: the declared label wins if present and recognized, otherwise
the byte-order guess if it maps to a supported encoding, otherwise the XML 1.0 default of
UTF-8.
§UTF-16
One case is deliberately not decided by the declaration: a UTF-16 byte order. The label
UTF-16 carries no endianness of its own (XML 1.0 Appendix F and RFC 2781 both say the
byte-order mark, or the Appendix F.1 four-byte pattern, is what determines it), while
WHATWG’s label table — which Encoding::for_label implements — resolves the bare label
to Encoding::Utf16Le as an arbitrary default. Taking that default literally would
decode every big-endian <?xml ... encoding="UTF-16"?> document as little-endian
mojibake, even though the declaration could only be read in the first place by decoding
the prologue big-endian. So whenever the leading bytes say UTF-16 — a BOM, or the exact
00 3C 00 3F / 3C 00 3F 00 pattern that no ASCII-compatible encoding can produce —
that byte order wins outright over whatever the declaration claims. See
SniffResult::has_conflicting_declaration for detecting the contradictory case that
XML 1.0 §4.3.3 makes a fatal error.
§Examples
use oxixml_encoding::{sniff_xml_encoding, Encoding};
let bare = sniff_xml_encoding(b"<root/>");
assert_eq!(bare.best_effort_encoding(), Encoding::Utf8);
let declared = sniff_xml_encoding(b"<?xml version=\"1.0\" encoding=\"windows-1252\"?><r/>");
assert_eq!(declared.best_effort_encoding(), Encoding::Windows1252);
// A big-endian document whose declaration says only the endianness-free "UTF-16"
// still decodes big-endian.
let mut big_endian = vec![0xFE, 0xFF];
for unit in "<?xml version=\"1.0\" encoding=\"UTF-16\"?><r/>".encode_utf16() {
big_endian.extend_from_slice(&unit.to_be_bytes());
}
assert_eq!(
sniff_xml_encoding(&big_endian).best_effort_encoding(),
Encoding::Utf16Be
);Sourcepub fn has_conflicting_declaration(&self) -> bool
pub fn has_conflicting_declaration(&self) -> bool
Whether the declared label contradicts the byte-order evidence in a way XML 1.0 §4.3.3 makes a fatal error (“it is a fatal error for an entity … to be presented to the XML processor in an encoding other than that named in the declaration”).
This is true only when both signals are present, both are decodable by this crate, and
they disagree — including the endianness-only disagreement that
best_effort_encoding silently resolves in favour of
the bytes, e.g. a big-endian entity declaring encoding="UTF-16LE". An entity carrying no
declaration, or one whose declaration merely refines the coarse ASCII-compatible guess
(windows-1252, Shift_JIS, …), is not a conflict.
§Examples
use oxixml_encoding::sniff_xml_encoding;
// A big-endian BOM with a matching-family, endianness-free label: no conflict.
let mut agreeing = vec![0xFE, 0xFF];
for unit in "<?xml version=\"1.0\" encoding=\"UTF-16\"?><r/>".encode_utf16() {
agreeing.extend_from_slice(&unit.to_be_bytes());
}
assert!(!sniff_xml_encoding(&agreeing).has_conflicting_declaration());
// The same bytes explicitly declaring the *other* byte order: a conflict.
let mut disagreeing = vec![0xFE, 0xFF];
for unit in "<?xml version=\"1.0\" encoding=\"UTF-16LE\"?><r/>".encode_utf16() {
disagreeing.extend_from_slice(&unit.to_be_bytes());
}
assert!(sniff_xml_encoding(&disagreeing).has_conflicting_declaration());Trait Implementations§
Source§impl Clone for SniffResult
impl Clone for SniffResult
Source§fn clone(&self) -> SniffResult
fn clone(&self) -> SniffResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more