Skip to content

Commit 8ba4da2

Browse files
kornelskiorium
authored andcommitted
Tell OutputSink what encoding is used
1 parent e0b3f24 commit 8ba4da2

2 files changed

Lines changed: 44 additions & 5 deletions

File tree

src/rewriter/mod.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ mod tests {
343343
use crate::html::TextType;
344344
use crate::html_content::ContentType;
345345
use crate::test_utils::{ASCII_COMPATIBLE_ENCODINGS, NON_ASCII_COMPATIBLE_ENCODINGS, Output};
346-
use encoding_rs::Encoding;
346+
use encoding_rs::{Encoding, WINDOWS_1252};
347347
use itertools::Itertools;
348348
use static_assertions::assert_impl_all;
349349
use std::convert::TryInto;
@@ -835,8 +835,28 @@ mod tests {
835835
#[test]
836836
fn test_charset_switch_latency() {
837837
let html = b"<title>\xC3\xB0</title>\xC3\xB0<meta charset=latin1 attr='\xC3\xB0'>\xF0<meta attr='\xF0'>\xF0";
838-
let rewritten = rewrite_html_bytes(
839-
html,
838+
839+
struct Sink {
840+
out: Vec<u8>,
841+
charsets: Vec<(usize, AsciiCompatibleEncoding)>,
842+
}
843+
844+
impl OutputSink for &mut Sink {
845+
fn handle_chunk(&mut self, chunk: &[u8]) {
846+
self.out.extend_from_slice(chunk);
847+
}
848+
849+
fn set_encoding(&mut self, enc: AsciiCompatibleEncoding) {
850+
self.charsets.push((self.out.len(), enc));
851+
}
852+
}
853+
854+
let mut sink = Sink {
855+
out: Vec::with_capacity(html.len()),
856+
charsets: vec![],
857+
};
858+
859+
let mut rewriter = HtmlRewriter::new(
840860
Settings {
841861
element_content_handlers: vec![element!("[attr]", |el| {
842862
assert_eq!(el.get_attribute("attr").unwrap(), "ð");
@@ -850,8 +870,20 @@ mod tests {
850870
adjust_charset_on_meta_tag: true,
851871
..Default::default()
852872
},
873+
&mut sink,
874+
);
875+
876+
rewriter.write(html).unwrap();
877+
rewriter.end().unwrap();
878+
879+
assert_eq!(html, sink.out.as_slice());
880+
assert_eq!(
881+
&[
882+
(0, AsciiCompatibleEncoding::utf_8()),
883+
(50, WINDOWS_1252.try_into().unwrap())
884+
],
885+
sink.charsets.as_slice()
853886
);
854-
assert_eq!(html, rewritten.as_slice());
855887
}
856888

857889
#[test]

src/transform_stream/dispatcher.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ pub trait OutputSink {
5959
/// # Note
6060
/// The last chunk of the output has zero length.
6161
fn handle_chunk(&mut self, chunk: &[u8]);
62+
63+
/// Called before the first `handle_chunk` and once when `<meta charset>` is applied.
64+
///
65+
/// Implementations for closures won't be able to access this method
66+
fn set_encoding(&mut self, _new_encoding: AsciiCompatibleEncoding) {}
6267
}
6368

6469
impl<F: FnMut(&[u8])> OutputSink for F {
@@ -188,11 +193,12 @@ where
188193
#[inline]
189194
pub fn new(
190195
transform_controller: C,
191-
output_sink: O,
196+
mut output_sink: O,
192197
encoding: AsciiCompatibleEncoding,
193198
next_encoding: SharedEncoding,
194199
) -> Self {
195200
let capture_flags = transform_controller.initial_capture_flags();
201+
output_sink.set_encoding(encoding);
196202

197203
Self {
198204
delegate: DispatcherDelegate {
@@ -217,6 +223,7 @@ where
217223
{
218224
self.encoding = next_encoding;
219225
self.text_decoder.set_encoding(next_encoding);
226+
self.delegate.output_sink.set_encoding(next_encoding);
220227
}
221228
}
222229

0 commit comments

Comments
 (0)