1 // Copyright Mozilla Foundation. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 use super::*;
11 use crate::variant::*;
12 
13 pub struct ReplacementDecoder {
14     emitted: bool,
15 }
16 
17 impl ReplacementDecoder {
new() -> VariantDecoder18     pub fn new() -> VariantDecoder {
19         VariantDecoder::Replacement(ReplacementDecoder { emitted: false })
20     }
21 
max_utf16_buffer_length(&self, _u16_length: usize) -> Option<usize>22     pub fn max_utf16_buffer_length(&self, _u16_length: usize) -> Option<usize> {
23         Some(1)
24     }
25 
max_utf8_buffer_length_without_replacement(&self, _byte_length: usize) -> Option<usize>26     pub fn max_utf8_buffer_length_without_replacement(&self, _byte_length: usize) -> Option<usize> {
27         Some(3)
28     }
29 
max_utf8_buffer_length(&self, _byte_length: usize) -> Option<usize>30     pub fn max_utf8_buffer_length(&self, _byte_length: usize) -> Option<usize> {
31         Some(3)
32     }
33 
decode_to_utf16_raw( &mut self, src: &[u8], dst: &mut [u16], _last: bool, ) -> (DecoderResult, usize, usize)34     pub fn decode_to_utf16_raw(
35         &mut self,
36         src: &[u8],
37         dst: &mut [u16],
38         _last: bool,
39     ) -> (DecoderResult, usize, usize) {
40         // Don't err if the input stream is empty. See
41         // https://github.com/whatwg/encoding/issues/33
42         if self.emitted || src.is_empty() {
43             (DecoderResult::InputEmpty, src.len(), 0)
44         } else if dst.is_empty() {
45             // Make sure there's room for the replacement character.
46             (DecoderResult::OutputFull, 0, 0)
47         } else {
48             self.emitted = true;
49             (DecoderResult::Malformed(1, 0), 1, 0)
50         }
51     }
52 
decode_to_utf8_raw( &mut self, src: &[u8], dst: &mut [u8], _last: bool, ) -> (DecoderResult, usize, usize)53     pub fn decode_to_utf8_raw(
54         &mut self,
55         src: &[u8],
56         dst: &mut [u8],
57         _last: bool,
58     ) -> (DecoderResult, usize, usize) {
59         // Don't err if the input stream is empty. See
60         // https://github.com/whatwg/encoding/issues/33
61         if self.emitted || src.is_empty() {
62             (DecoderResult::InputEmpty, src.len(), 0)
63         } else if dst.len() < 3 {
64             // Make sure there's room for the replacement character.
65             (DecoderResult::OutputFull, 0, 0)
66         } else {
67             self.emitted = true;
68             (DecoderResult::Malformed(1, 0), 1, 0)
69         }
70     }
71 }
72 
73 // Any copyright to the test code below this comment is dedicated to the
74 // Public Domain. http://creativecommons.org/publicdomain/zero/1.0/
75 
76 #[cfg(test)]
77 mod tests {
78     use super::super::testing::*;
79     use super::super::*;
80 
decode_replacement(bytes: &[u8], expect: &str)81     fn decode_replacement(bytes: &[u8], expect: &str) {
82         decode_without_padding(REPLACEMENT, bytes, expect);
83     }
84 
encode_replacement(string: &str, expect: &[u8])85     fn encode_replacement(string: &str, expect: &[u8]) {
86         encode(REPLACEMENT, string, expect);
87     }
88 
89     #[test]
test_replacement_decode()90     fn test_replacement_decode() {
91         decode_replacement(b"", "");
92         decode_replacement(b"A", "\u{FFFD}");
93         decode_replacement(b"AB", "\u{FFFD}");
94     }
95 
96     #[test]
test_replacement_encode()97     fn test_replacement_encode() {
98         // Empty
99         encode_replacement("", b"");
100 
101         assert_eq!(REPLACEMENT.new_encoder().encoding(), UTF_8);
102         encode_replacement("\u{1F4A9}\u{2603}", "\u{1F4A9}\u{2603}".as_bytes());
103     }
104 }
105