1 // Copyright 2016 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 
decode(encoding: &'static Encoding, bytes: &[u8], expect: &str)12 pub fn decode(encoding: &'static Encoding, bytes: &[u8], expect: &str) {
13     let mut vec = Vec::with_capacity(bytes.len() + 32);
14     let mut string = String::with_capacity(expect.len() + 32);
15     for i in 0usize..32usize {
16         vec.clear();
17         string.clear();
18         for j in 0usize..i {
19             let c = 0x40u8 + (j as u8);
20             vec.push(c);
21             string.push(c as char);
22         }
23         vec.extend_from_slice(bytes);
24         string.push_str(expect);
25         decode_without_padding_impl(encoding, &vec[..], &string[..], i);
26     }
27 }
28 
decode_without_padding(encoding: &'static Encoding, bytes: &[u8], expect: &str)29 pub fn decode_without_padding(encoding: &'static Encoding, bytes: &[u8], expect: &str) {
30     decode_without_padding_impl(encoding, bytes, expect, 0);
31 }
32 
decode_without_padding_impl( encoding: &'static Encoding, bytes: &[u8], expect: &str, padding: usize, )33 fn decode_without_padding_impl(
34     encoding: &'static Encoding,
35     bytes: &[u8],
36     expect: &str,
37     padding: usize,
38 ) {
39     decode_to_utf8_impl(encoding, bytes, expect, padding);
40     decode_to_utf16_impl(encoding, bytes, &utf16_from_utf8(expect)[..], padding);
41     decode_to_string(encoding, bytes, expect);
42 }
43 
encode(encoding: &'static Encoding, str: &str, expect: &[u8])44 pub fn encode(encoding: &'static Encoding, str: &str, expect: &[u8]) {
45     let mut vec = Vec::with_capacity(expect.len() + 32);
46     let mut string = String::with_capacity(str.len() + 32);
47     for i in 0usize..32usize {
48         vec.clear();
49         string.clear();
50         for j in 0usize..i {
51             let c = 0x40u8 + (j as u8);
52             vec.push(c);
53             string.push(c as char);
54         }
55         vec.extend_from_slice(expect);
56         string.push_str(str);
57         encode_without_padding(encoding, &string[..], &vec[..]);
58     }
59 }
60 
encode_without_padding(encoding: &'static Encoding, string: &str, expect: &[u8])61 pub fn encode_without_padding(encoding: &'static Encoding, string: &str, expect: &[u8]) {
62     encode_from_utf8(encoding, string, expect);
63     encode_from_utf16(encoding, &utf16_from_utf8(string)[..], expect);
64     encode_to_vec(encoding, string, expect);
65 }
66 
decode_to_utf16(encoding: &'static Encoding, bytes: &[u8], expect: &[u16])67 pub fn decode_to_utf16(encoding: &'static Encoding, bytes: &[u8], expect: &[u16]) {
68     decode_to_utf16_impl(encoding, bytes, expect, 0);
69 }
70 
decode_to_utf16_impl( encoding: &'static Encoding, bytes: &[u8], expect: &[u16], padding: usize, )71 pub fn decode_to_utf16_impl(
72     encoding: &'static Encoding,
73     bytes: &[u8],
74     expect: &[u16],
75     padding: usize,
76 ) {
77     for i in padding..bytes.len() {
78         let (head, tail) = bytes.split_at(i);
79         decode_to_utf16_with_boundary(encoding, head, tail, expect);
80     }
81 }
82 
decode_to_utf16_with_boundary( encoding: &'static Encoding, head: &[u8], tail: &[u8], expect: &[u16], )83 pub fn decode_to_utf16_with_boundary(
84     encoding: &'static Encoding,
85     head: &[u8],
86     tail: &[u8],
87     expect: &[u16],
88 ) {
89     let mut decoder = encoding.new_decoder();
90     let mut dest: Vec<u16> = Vec::with_capacity(
91         decoder
92             .max_utf16_buffer_length(head.len() + tail.len())
93             .unwrap(),
94     );
95     let capacity = dest.capacity();
96     dest.resize(capacity, 0u16);
97     let mut total_read = 0;
98     let mut total_written = 0;
99     {
100         let (complete, read, written, _) = decoder.decode_to_utf16(head, &mut dest, false);
101         match complete {
102             CoderResult::InputEmpty => {}
103             CoderResult::OutputFull => {
104                 unreachable!();
105             }
106         }
107         total_read += read;
108         total_written += written;
109     }
110     {
111         let (complete, read, written, _) =
112             decoder.decode_to_utf16(tail, &mut dest[total_written..], true);
113         match complete {
114             CoderResult::InputEmpty => {}
115             CoderResult::OutputFull => {
116                 unreachable!();
117             }
118         }
119         total_read += read;
120         total_written += written;
121     }
122     assert_eq!(total_read, head.len() + tail.len());
123     assert_eq!(total_written, expect.len());
124     dest.truncate(total_written);
125     assert_eq!(&dest[..], expect);
126 }
127 
decode_to_utf8(encoding: &'static Encoding, bytes: &[u8], expect: &str)128 pub fn decode_to_utf8(encoding: &'static Encoding, bytes: &[u8], expect: &str) {
129     decode_to_utf8_impl(encoding, bytes, expect, 0);
130 }
131 
decode_to_utf8_impl( encoding: &'static Encoding, bytes: &[u8], expect: &str, padding: usize, )132 pub fn decode_to_utf8_impl(
133     encoding: &'static Encoding,
134     bytes: &[u8],
135     expect: &str,
136     padding: usize,
137 ) {
138     for i in padding..bytes.len() {
139         let (head, tail) = bytes.split_at(i);
140         decode_to_utf8_with_boundary(encoding, head, tail, expect);
141     }
142 }
143 
decode_to_utf8_with_boundary( encoding: &'static Encoding, head: &[u8], tail: &[u8], expect: &str, )144 pub fn decode_to_utf8_with_boundary(
145     encoding: &'static Encoding,
146     head: &[u8],
147     tail: &[u8],
148     expect: &str,
149 ) {
150     let mut decoder = encoding.new_decoder();
151     let mut dest: Vec<u8> = Vec::with_capacity(
152         decoder
153             .max_utf8_buffer_length(head.len() + tail.len())
154             .unwrap(),
155     );
156     let capacity = dest.capacity();
157     dest.resize(capacity, 0u8);
158     let mut total_read = 0;
159     let mut total_written = 0;
160     {
161         let (complete, read, written, _) = decoder.decode_to_utf8(head, &mut dest, false);
162         match complete {
163             CoderResult::InputEmpty => {}
164             CoderResult::OutputFull => {
165                 unreachable!();
166             }
167         }
168         total_read += read;
169         total_written += written;
170     }
171     {
172         let (complete, read, written, _) =
173             decoder.decode_to_utf8(tail, &mut dest[total_written..], true);
174         match complete {
175             CoderResult::InputEmpty => {}
176             CoderResult::OutputFull => {
177                 unreachable!();
178             }
179         }
180         total_read += read;
181         total_written += written;
182     }
183     assert_eq!(total_read, head.len() + tail.len());
184     assert_eq!(total_written, expect.len());
185     dest.truncate(total_written);
186     assert_eq!(&dest[..], expect.as_bytes());
187 }
188 
decode_to_string(encoding: &'static Encoding, bytes: &[u8], expect: &str)189 pub fn decode_to_string(encoding: &'static Encoding, bytes: &[u8], expect: &str) {
190     let (cow, _, _) = encoding.decode(bytes);
191     assert_eq!(&cow[..], expect);
192 }
193 
encode_from_utf8(encoding: &'static Encoding, string: &str, expect: &[u8])194 pub fn encode_from_utf8(encoding: &'static Encoding, string: &str, expect: &[u8]) {
195     let mut encoder = encoding.new_encoder();
196     let mut dest: Vec<u8> = Vec::with_capacity(10 * (string.len() + 1)); // 10 is replacement worst case
197     let capacity = dest.capacity();
198     dest.resize(capacity, 0u8);
199     let (complete, read, written, _) = encoder.encode_from_utf8(string, &mut dest, true);
200     match complete {
201         CoderResult::InputEmpty => {}
202         CoderResult::OutputFull => {
203             unreachable!();
204         }
205     }
206     assert_eq!(read, string.len());
207     assert_eq!(written, expect.len());
208     dest.truncate(written);
209     assert_eq!(&dest[..], expect);
210 }
211 
encode_from_utf16(encoding: &'static Encoding, string: &[u16], expect: &[u8])212 pub fn encode_from_utf16(encoding: &'static Encoding, string: &[u16], expect: &[u8]) {
213     let mut encoder = encoding.new_encoder();
214     let mut dest: Vec<u8> = Vec::with_capacity(10 * (string.len() + 1)); // 10 is replacement worst case
215     let capacity = dest.capacity();
216     dest.resize(capacity, 0u8);
217     let (complete, read, written, _) = encoder.encode_from_utf16(string, &mut dest, true);
218     match complete {
219         CoderResult::InputEmpty => {}
220         CoderResult::OutputFull => {
221             unreachable!();
222         }
223     }
224     assert_eq!(read, string.len());
225     // assert_eq!(written, expect.len());
226     dest.truncate(written);
227     assert_eq!(&dest[..], expect);
228 }
229 
encode_to_vec(encoding: &'static Encoding, string: &str, expect: &[u8])230 pub fn encode_to_vec(encoding: &'static Encoding, string: &str, expect: &[u8]) {
231     let (cow, _, _) = encoding.encode(string);
232     assert_eq!(&cow[..], expect);
233 }
234 
utf16_from_utf8(string: &str) -> Vec<u16>235 pub fn utf16_from_utf8(string: &str) -> Vec<u16> {
236     let mut decoder = UTF_8.new_decoder_without_bom_handling();
237     let mut vec = Vec::with_capacity(decoder.max_utf16_buffer_length(string.len()).unwrap());
238     let capacity = vec.capacity();
239     vec.resize(capacity, 0);
240 
241     let (result, read, written) =
242         decoder.decode_to_utf16_without_replacement(string.as_bytes(), &mut vec[..], true);
243     match result {
244         DecoderResult::InputEmpty => {
245             debug_assert_eq!(read, string.len());
246             vec.resize(written, 0);
247             vec
248         }
249         DecoderResult::Malformed(_, _) => unreachable!("Malformed"),
250         DecoderResult::OutputFull => unreachable!("Output full"),
251     }
252 }
253