1use super::*;
11use crate::data::*;
12use crate::gb18030_2022::*;
13use crate::handles::*;
14use crate::variant::*;
15use super::in_inclusive_range16;
17use super::in_range16;
18
19enum Gb18030Pending {
20 None,
21 One(u8),
22 Two(u8, u8),
23 Three(u8, u8, u8),
24}
25
26impl Gb18030Pending {
27 fn is_none(&self) -> bool {
28 matches!(*self, Gb18030Pending::None)
29 }
30
31 fn count(&self) -> usize {
32 match *self {
33 Gb18030Pending::None => 0,
34 Gb18030Pending::One(_) => 1,
35 Gb18030Pending::Two(_, _) => 2,
36 Gb18030Pending::Three(_, _, _) => 3,
37 }
38 }
39}
40
41pub struct Gb18030Decoder {
42 first: Option<u8>,
43 second: Option<u8>,
44 third: Option<u8>,
45 pending: Gb18030Pending,
46 pending_ascii: Option<u8>,
47}
48
49impl Gb18030Decoder {
50 pub fn new() -> VariantDecoder {
51 VariantDecoder::Gb18030(Gb18030Decoder {
52 first: None,
53 second: None,
54 third: None,
55 pending: Gb18030Pending::None,
56 pending_ascii: None,
57 })
58 }
59
60 pub fn in_neutral_state(&self) -> bool {
61 self.first.is_none()
62 && self.second.is_none()
63 && self.third.is_none()
64 && self.pending.is_none()
65 && self.pending_ascii.is_none()
66 }
67
68 fn extra_from_state(&self, byte_length: usize) -> Option<usize> {
69 byte_length.checked_add(
70 self.pending.count()
71 + match self.first {
72 None => 0,
73 Some(_) => 1,
74 }
75 + match self.second {
76 None => 0,
77 Some(_) => 1,
78 }
79 + match self.third {
80 None => 0,
81 Some(_) => 1,
82 }
83 + match self.pending_ascii {
84 None => 0,
85 Some(_) => 1,
86 },
87 )
88 }
89
90 pub fn max_utf16_buffer_length(&self, byte_length: usize) -> Option<usize> {
91 checked_add(1, self.extra_from_state(byte_length))
95 }
96
97 pub fn max_utf8_buffer_length_without_replacement(&self, byte_length: usize) -> Option<usize> {
98 self.max_utf8_buffer_length(byte_length)
103 }
104
105 pub fn max_utf8_buffer_length(&self, byte_length: usize) -> Option<usize> {
106 checked_add(1, checked_mul(3, self.extra_from_state(byte_length)))
107 }
108
109 gb18030_decoder_functions!(
110 {
111 let non_ascii_minus_offset = non_ascii.wrapping_sub(0x81);
114 if non_ascii_minus_offset > (0xFE - 0x81) {
115 if non_ascii == 0x80 {
116 handle.write_upper_bmp(0x20ACu16);
117 continue 'outermost;
118 }
119 return (DecoderResult::Malformed(1, 0),
120 source.consumed(),
121 handle.written());
122 }
123 non_ascii_minus_offset
124 },
125 {
126 if first_minus_offset >= 0x20 {
128 let trail_minus_offset = second.wrapping_sub(0xA1);
130 if trail_minus_offset <= (0xFE - 0xA1) {
131 let hanzi_lead = first_minus_offset.wrapping_sub(0x2F);
133 if hanzi_lead < (0x77 - 0x2F) {
134 let hanzi_pointer = mul_94(hanzi_lead) + trail_minus_offset as usize;
138 let upper_bmp = GB2312_HANZI[hanzi_pointer];
139 handle.write_upper_bmp(upper_bmp)
140 } else if first_minus_offset == 0x20 {
141 let bmp = GB2312_SYMBOLS[trail_minus_offset as usize];
143 handle.write_bmp_excl_ascii(bmp)
144 } else if first_minus_offset == 0x25 && ((trail_minus_offset.wrapping_sub(63) as usize) < GB2312_SYMBOLS_AFTER_GREEK.len()) {
145 handle.write_bmp_excl_ascii(GB2312_SYMBOLS_AFTER_GREEK[trail_minus_offset.wrapping_sub(63) as usize])
146 } else if first_minus_offset == 0x27 && (trail_minus_offset as usize) < GB2312_PINYIN.len() {
147 handle.write_bmp_excl_ascii(GB2312_PINYIN[trail_minus_offset as usize])
148 } else if first_minus_offset > 0x76 {
149 let pua = (0xE234 + mul_94(first_minus_offset - 0x77) + trail_minus_offset as usize) as u16;
151 handle.write_upper_bmp(pua)
152 } else {
153 let bmp = gb2312_other_decode((mul_94(first_minus_offset - 0x21) + (trail_minus_offset as usize)) as u16);
154 handle.write_bmp_excl_ascii(bmp)
155 }
156 } else {
157 let mut trail_minus_offset = second.wrapping_sub(0x40);
159 if trail_minus_offset > (0x7E - 0x40) {
160 let trail_minus_range_start = second.wrapping_sub(0x80);
161 if trail_minus_range_start > (0xA0 - 0x80) {
162 if second < 0x80 {
163 return (DecoderResult::Malformed(1, 0),
164 unread_handle_second.unread(),
165 handle.written());
166 }
167 return (DecoderResult::Malformed(2, 0),
168 unread_handle_second.consumed(),
169 handle.written());
170 }
171 trail_minus_offset = second - 0x41;
172 }
173 let left_lead = first_minus_offset - 0x20;
175 let left_pointer = left_lead as usize * (190 - 94) +
176 trail_minus_offset as usize;
177 let gbk_left_ideograph_pointer = left_pointer.wrapping_sub((0x29 - 0x20) * (190 - 94));
178 if gbk_left_ideograph_pointer < (((0x7D - 0x29) * (190 - 94)) - 5) {
179 let upper_bmp = gbk_left_ideograph_decode(gbk_left_ideograph_pointer as u16);
180 handle.write_upper_bmp(upper_bmp)
181 } else if left_pointer < ((0x29 - 0x20) * (190 - 94)) {
182 let bmp = gbk_other_decode(left_pointer as u16);
183 handle.write_bmp_excl_ascii(bmp)
184 } else {
185 let bottom_pointer = left_pointer - (((0x7D - 0x20) * (190 - 94)) - 5);
186 let upper_bmp = GBK_BOTTOM[bottom_pointer];
187 handle.write_upper_bmp(upper_bmp)
188 }
189 }
190 } else {
191 let mut trail_minus_offset = second.wrapping_sub(0x40);
193 if trail_minus_offset > (0x7E - 0x40) {
194 let trail_minus_range_start = second.wrapping_sub(0x80);
195 if trail_minus_range_start > (0xFE - 0x80) {
196 if second < 0x80 {
197 return (DecoderResult::Malformed(1, 0),
198 unread_handle_second.unread(),
199 handle.written());
200 }
201 return (DecoderResult::Malformed(2, 0),
202 unread_handle_second.consumed(),
203 handle.written());
204 }
205 trail_minus_offset = second - 0x41;
206 }
207 let pointer = first_minus_offset as usize * 190usize +
208 trail_minus_offset as usize;
209 let upper_bmp = gbk_top_ideograph_decode(pointer as u16);
210 handle.write_upper_bmp(upper_bmp)
211 }
212 },
213 {
214 let third_minus_offset = third.wrapping_sub(0x81);
217 if third_minus_offset > (0xFE - 0x81) {
218 self.pending_ascii = Some(second_minus_offset + 0x30);
225 return (DecoderResult::Malformed(1, 1),
228 unread_handle_third.unread(),
229 handle.written());
230 }
231 third_minus_offset
232 },
233 {
234 let fourth_minus_offset = fourth.wrapping_sub(0x30);
252 if fourth_minus_offset > (0x39 - 0x30) {
253 self.pending_ascii = Some(second_minus_offset + 0x30);
254 self.pending = Gb18030Pending::One(third_minus_offset);
255 return (DecoderResult::Malformed(1, 2),
256 unread_handle_fourth.unread(),
257 handle.written());
258 }
259 let pointer = (first_minus_offset as usize * (10 * 126 * 10)) +
260 (second_minus_offset as usize * (10 * 126)) +
261 (third_minus_offset as usize * 10) +
262 fourth_minus_offset as usize;
263 if pointer <= 39419 {
264 if pointer == 7457 {
266 handle.write_upper_bmp(0xE7C7)
267 } else {
268 handle.write_bmp_excl_ascii(gb18030_range_decode(pointer as u16))
269 }
270 } else if (189_000..=1_237_575).contains(&pointer) {
271 handle.write_astral((pointer - (189_000usize - 0x1_0000usize)) as u32)
273 } else {
274 return (DecoderResult::Malformed(4, 0),
275 unread_handle_fourth.consumed(),
276 handle.written());
277 }
278 },
279 self,
280 non_ascii,
281 first_minus_offset,
282 second,
283 second_minus_offset,
284 unread_handle_second,
285 third,
286 third_minus_offset,
287 unread_handle_third,
288 fourth,
289 fourth_minus_offset,
290 unread_handle_fourth,
291 source,
292 handle,
293 'outermost);
294}
295
296fn gbk_encode_non_unified(bmp: u16) -> Option<(usize, usize)> {
298 if (in_inclusive_range16(bmp, 0x2014, 0x3017) || in_inclusive_range16(bmp, 0xFF04, 0xFFE1))
302 && let Some(pos) = position(&GB2312_SYMBOLS[..], bmp)
303 {
304 return Some((0xA1, pos + 0xA1));
305 }
306 if in_range16(bmp, 0x3400, 0x4E00) {
308 return position(&GBK_BOTTOM[21..100], bmp).map(|pos| {
309 (
310 0xFE,
311 pos + if pos < (0x3F - 16) {
312 0x40 + 16
313 } else {
314 0x41 + 16
315 },
316 )
317 });
318 }
319 if in_range16(bmp, 0xF900, 0xFB00) {
321 return position(&GBK_BOTTOM[0..21], bmp).map(|pos| {
322 if pos < 5 {
323 (0xFD, pos + (190 - 94 - 5 + 0x41))
325 } else {
326 (0xFE, pos + (0x40 - 5))
328 }
329 });
330 }
331 if bmp < 0x02CA {
333 if in_range16(bmp, 0x00E0, 0x0262) && bmp != 0x00F7 {
334 if let Some(pos) = position(&GB2312_PINYIN[..], bmp) {
336 return Some((0xA8, pos + 0xA1));
337 }
338 } else if in_inclusive_range16(bmp, 0x00A4, 0x00F7)
339 || in_inclusive_range16(bmp, 0x02C7, 0x02C9)
340 {
341 if let Some(pos) = position(&GB2312_SYMBOLS[3..(0xAC - 0x60)], bmp) {
343 return Some((0xA1, pos + 0xA1 + 3));
344 }
345 }
346 return None;
347 }
348
349 if in_inclusive_range16(bmp, 0xE78D, 0xE864) {
350 if let Some(pos) = position(&GB18030_2022_OVERRIDE_PUA[..], bmp) {
352 let pair = &GB18030_2022_OVERRIDE_BYTES[pos];
353 return Some((pair[0].into(), pair[1].into()));
354 }
355 } else if bmp >= 0xFE17 {
356 if let Some(pos) = position(&GB2312_SYMBOLS_AFTER_GREEK[..], bmp) {
358 return Some((0xA6, pos + (0x9F - 0x60 + 0xA1)));
359 }
360 } else if bmp == 0x1E3F {
361 return Some((0xA8, 0x7B - 0x60 + 0xA1));
363 } else if in_range16(bmp, 0xA000, 0xD800) {
364 return None;
367 }
368 if let Some(other_pointer) = gb2312_other_encode(bmp) {
370 let other_lead = other_pointer as usize / 94;
371 let other_trail = other_pointer as usize % 94;
372 return Some((0xA2 + other_lead, 0xA1 + other_trail));
373 }
374 if in_range16(bmp, 0x02DA, 0x2010) {
379 return None;
380 }
381 if let Some(other_pointer) = gbk_other_encode(bmp) {
383 let other_lead = other_pointer as usize / (190 - 94);
384 let other_trail = other_pointer as usize % (190 - 94);
385 let offset = if other_trail < 0x3F { 0x40 } else { 0x41 };
386 return Some((other_lead + (0x81 + 0x20), other_trail + offset));
387 }
388 if (in_inclusive_range16(bmp, 0x2E81, 0x2ECA)
390 || in_inclusive_range16(bmp, 0x9FB4, 0x9FBB)
391 || in_inclusive_range16(bmp, 0xE816, 0xE855))
392 && let Some(pos) = position(&GBK_BOTTOM[21..], bmp)
393 {
394 let trail = pos + 16;
395 let offset = if trail < 0x3F { 0x40 } else { 0x41 };
396 return Some((0xFE, trail + offset));
397 }
398 let bmp_minus_gb2312_bottom_pua = bmp.wrapping_sub(0xE234);
400 if bmp_minus_gb2312_bottom_pua <= (0xE4C5 - 0xE234) {
401 let pua_lead = bmp_minus_gb2312_bottom_pua as usize / 94;
402 let pua_trail = bmp_minus_gb2312_bottom_pua as usize % 94;
403 return Some((0x81 + 0x77 + pua_lead, 0xA1 + pua_trail));
404 }
405 let bmp_minus_pua_between_hanzi = bmp.wrapping_sub(0xE810);
407 if bmp_minus_pua_between_hanzi < 5 {
408 return Some((0x81 + 0x56, 0xFF - 5 + bmp_minus_pua_between_hanzi as usize));
409 }
410 None
411}
412
413#[cfg(not(feature = "fast-gb-hanzi-encode"))]
414#[inline(always)]
415fn encode_hanzi(bmp: u16, _: u16) -> (u8, u8) {
416 if let Some((lead, trail)) = gb2312_level1_hanzi_encode(bmp) {
417 (lead, trail)
418 } else if let Some(hanzi_pointer) = gb2312_level2_hanzi_encode(bmp) {
419 let hanzi_lead = (hanzi_pointer / 94) + (0xD8);
420 let hanzi_trail = (hanzi_pointer % 94) + 0xA1;
421 (hanzi_lead as u8, hanzi_trail as u8)
422 } else {
423 let (lead, gbk_trail) = if bmp < 0x72DC {
424 let pointer = gbk_top_ideograph_encode(bmp) as usize;
426 let lead = (pointer / 190) + 0x81;
427 let gbk_trail = pointer % 190;
428 (lead, gbk_trail)
429 } else {
430 let gbk_left_ideograph_pointer = gbk_left_ideograph_encode(bmp) as usize;
432 let lead = (gbk_left_ideograph_pointer / (190 - 94)) + (0x81 + 0x29);
433 let gbk_trail = gbk_left_ideograph_pointer % (190 - 94);
434 (lead, gbk_trail)
435 };
436 let offset = if gbk_trail < 0x3F { 0x40 } else { 0x41 };
437 (lead as u8, (gbk_trail + offset) as u8)
438 }
439}
440
441#[cfg(feature = "fast-gb-hanzi-encode")]
442#[inline(always)]
443fn encode_hanzi(_: u16, bmp_minus_unified_start: u16) -> (u8, u8) {
444 gbk_hanzi_encode(bmp_minus_unified_start)
445}
446
447pub struct Gb18030Encoder {
448 extended: bool,
449}
450
451impl Gb18030Encoder {
452 pub fn new(encoding: &'static Encoding, extended_range: bool) -> Encoder {
453 Encoder::new(
454 encoding,
455 VariantEncoder::Gb18030(Gb18030Encoder {
456 extended: extended_range,
457 }),
458 )
459 }
460
461 pub fn max_buffer_length_from_utf16_without_replacement(
462 &self,
463 u16_length: usize,
464 ) -> Option<usize> {
465 if self.extended {
466 u16_length.checked_mul(4)
467 } else {
468 checked_add(2, u16_length.checked_mul(2))
471 }
472 }
473
474 pub fn max_buffer_length_from_utf8_without_replacement(
475 &self,
476 byte_length: usize,
477 ) -> Option<usize> {
478 if self.extended {
479 checked_add(2, byte_length.checked_mul(2))
486 } else {
487 byte_length.checked_add(3)
493 }
494 }
495
496 ascii_compatible_encoder_functions!(
497 {
498 let bmp_minus_unified_start = bmp.wrapping_sub(0x4E00);
499 if bmp_minus_unified_start < (0x9FA6 - 0x4E00) {
500 let (lead, trail) = encode_hanzi(bmp, bmp_minus_unified_start);
504 handle.write_two(lead, trail)
505 } else if bmp == 0xE5E5 {
506 return (
511 EncoderResult::unmappable_from_bmp(bmp),
512 source.consumed(),
513 handle.written(),
514 );
515 } else if bmp == 0x20AC && !self.extended {
516 handle.write_one(0x80u8)
517 } else {
518 match gbk_encode_non_unified(bmp) {
519 Some((lead, trail)) => handle.write_two(lead as u8, trail as u8),
520 None => {
521 if !self.extended {
522 return (
523 EncoderResult::unmappable_from_bmp(bmp),
524 source.consumed(),
525 handle.written(),
526 );
527 }
528 let range_pointer = gb18030_range_encode(bmp);
529 let first = range_pointer / (10 * 126 * 10);
530 let rem_first = range_pointer % (10 * 126 * 10);
531 let second = rem_first / (10 * 126);
532 let rem_second = rem_first % (10 * 126);
533 let third = rem_second / 10;
534 let fourth = rem_second % 10;
535 handle.write_four(
536 (first + 0x81) as u8,
537 (second + 0x30) as u8,
538 (third + 0x81) as u8,
539 (fourth + 0x30) as u8,
540 )
541 }
542 }
543 }
544 },
545 {
546 if !self.extended {
547 return (
548 EncoderResult::Unmappable(astral),
549 source.consumed(),
550 handle.written(),
551 );
552 }
553 let range_pointer = astral as usize + (189_000usize - 0x1_0000usize);
554 let first = range_pointer / (10 * 126 * 10);
555 let rem_first = range_pointer % (10 * 126 * 10);
556 let second = rem_first / (10 * 126);
557 let rem_second = rem_first % (10 * 126);
558 let third = rem_second / 10;
559 let fourth = rem_second % 10;
560 handle.write_four(
561 (first + 0x81) as u8,
562 (second + 0x30) as u8,
563 (third + 0x81) as u8,
564 (fourth + 0x30) as u8,
565 )
566 },
567 bmp,
568 astral,
569 self,
570 source,
571 handle,
572 copy_ascii_to_check_space_four,
573 check_space_four,
574 false
575 );
576}
577
578#[cfg(all(test, feature = "alloc"))]
582mod tests {
583 use super::super::testing::*;
584 use super::super::*;
585
586 fn decode_gb18030(bytes: &[u8], expect: &str) {
587 decode(GB18030, bytes, expect);
588 }
589
590 fn encode_gb18030(string: &str, expect: &[u8]) {
591 encode(GB18030, string, expect);
592 }
593
594 fn encode_gbk(string: &str, expect: &[u8]) {
595 encode(GBK, string, expect);
596 }
597
598 #[test]
599 fn test_gb18030_decode() {
600 decode_gb18030(b"", &"");
602
603 decode_gb18030(b"\x61\x62", "\u{0061}\u{0062}");
605
606 decode_gb18030(b"\x80", "\u{20AC}");
608 decode_gb18030(b"\xA2\xE3", "\u{20AC}");
609
610 decode_gb18030(b"\x81\x40", "\u{4E02}");
612 decode_gb18030(b"\x81\x7E", "\u{4E8A}");
613 decode_gb18030(b"\x81\x7F", "\u{FFFD}\u{007F}");
614 decode_gb18030(b"\x81\x80", "\u{4E90}");
615 decode_gb18030(b"\x81\xFE", "\u{4FA2}");
616 decode_gb18030(b"\xFE\x40", "\u{FA0C}");
617 decode_gb18030(b"\xFE\x7F", "\u{FFFD}\u{007F}");
618 decode_gb18030(b"\xFE\x80", "\u{4723}");
619 decode_gb18030(b"\xFE\xFE", "\u{E4C5}");
620
621 decode_gb18030(b"\xFE\x7E", "\u{9FB9}");
623 decode_gb18030(b"\xA6\xDD", "\u{FE14}");
624
625 decode_gb18030(b"\x82\x35\x91\x32", "\u{9FB9}");
627 decode_gb18030(b"\x84\x31\x83\x30", "\u{FE14}");
628
629 decode_gb18030(b"\xA3\xA0", "\u{3000}");
631 decode_gb18030(b"\xA1\xA1", "\u{3000}");
632
633 decode_gb18030(b"\xFF\x40", "\u{FFFD}\u{0040}");
635 decode_gb18030(b"\xE3\xFF\x9A\x33", "\u{FFFD}\u{FFFD}"); decode_gb18030(b"\xFF\x32\x9A\x33", "\u{FFFD}\u{0032}\u{FFFD}"); decode_gb18030(b"\xFF\x40\x00", "\u{FFFD}\u{0040}\u{0000}");
638 decode_gb18030(b"\xE3\xFF\x9A\x33\x00", "\u{FFFD}\u{FFFD}\u{0033}\u{0000}");
639 decode_gb18030(
640 b"\xFF\x32\x9A\x33\x00",
641 "\u{FFFD}\u{0032}\u{FFFD}\u{0033}\u{0000}",
642 );
643
644 decode_gb18030(b"\x81\x30\x81\x30", "\u{0080}");
646 decode_gb18030(b"\x81\x35\xF4\x37", "\u{E7C7}");
647 decode_gb18030(b"\x81\x37\xA3\x30", "\u{2603}");
648 decode_gb18030(b"\x94\x39\xDA\x33", "\u{1F4A9}");
649 decode_gb18030(b"\xE3\x32\x9A\x35", "\u{10FFFF}");
650 decode_gb18030(b"\xE3\x32\x9A\x36\x81\x30", "\u{FFFD}\u{FFFD}");
651 decode_gb18030(b"\xE3\x32\x9A\x36\x81\x40", "\u{FFFD}\u{4E02}");
652 decode_gb18030(b"\xE3\x32\x9A", "\u{FFFD}"); decode_gb18030(b"\xE3\x32\x9A\x00", "\u{FFFD}\u{0032}\u{FFFD}\u{0000}");
654 }
655
656 #[test]
657 fn test_gb18030_encode() {
658 encode_gb18030("", b"");
660
661 encode_gb18030("\u{0061}\u{0062}", b"\x61\x62");
663
664 encode_gb18030("\u{20AC}", b"\xA2\xE3");
666
667 encode_gb18030("\u{4E02}", b"\x81\x40");
669 encode_gb18030("\u{4E8A}", b"\x81\x7E");
670 if !cfg!(miri) {
671 encode_gb18030("\u{4E90}", b"\x81\x80");
673 encode_gb18030("\u{4FA2}", b"\x81\xFE");
674 encode_gb18030("\u{FA0C}", b"\xFE\x40");
675 encode_gb18030("\u{E843}", b"\xFE\x7E");
676 encode_gb18030("\u{4723}", b"\xFE\x80");
677 encode_gb18030("\u{E4C5}", b"\xFE\xFE");
678 }
679
680 encode_gb18030("\u{E5E5}", b"");
682 encode_gb18030("\u{3000}", b"\xA1\xA1");
683
684 encode_gb18030("\u{0080}", b"\x81\x30\x81\x30");
686 encode_gb18030("\u{E7C7}", b"\x81\x35\xF4\x37");
687 if !cfg!(miri) {
688 encode_gb18030("\u{2603}", b"\x81\x37\xA3\x30");
690 encode_gb18030("\u{1F4A9}", b"\x94\x39\xDA\x33");
691 encode_gb18030("\u{10FFFF}", b"\xE3\x32\x9A\x35");
692 }
693
694 encode_gb18030("\u{00F7}", b"\xA1\xC2");
696
697 encode_gb18030("\u{9FB9}", b"\xFE\x7E");
699 encode_gb18030("\u{FE14}", b"\xA6\xDD");
700 encode_gb18030("\u{E843}", b"\xFE\x7E");
701 encode_gb18030("\u{E791}", b"\xA6\xDD");
702
703 encode_gb18030("\u{E817}", b"\xFE\x52");
705 }
706
707 #[test]
708 fn test_gbk_encode() {
709 encode_gbk("", b"");
711
712 encode_gbk("\u{0061}\u{0062}", b"\x61\x62");
714
715 encode_gbk("\u{20AC}", b"\x80");
717
718 encode_gbk("\u{4E02}", b"\x81\x40");
720 encode_gbk("\u{4E8A}", b"\x81\x7E");
721 if !cfg!(miri) {
722 encode_gbk("\u{4E90}", b"\x81\x80");
724 encode_gbk("\u{4FA2}", b"\x81\xFE");
725 encode_gbk("\u{FA0C}", b"\xFE\x40");
726 encode_gbk("\u{E843}", b"\xFE\x7E");
727 encode_gbk("\u{4723}", b"\xFE\x80");
728 encode_gbk("\u{E4C5}", b"\xFE\xFE");
729 }
730
731 encode_gbk("\u{E5E5}", b"");
733 encode_gbk("\u{3000}", b"\xA1\xA1");
734
735 encode_gbk("\u{0080}", b"€");
737 encode_gbk("\u{E7C7}", b"");
738 if !cfg!(miri) {
739 encode_gbk("\u{2603}", b"☃");
741 encode_gbk("\u{1F4A9}", b"💩");
742 encode_gbk("\u{10FFFF}", b"");
743 }
744
745 encode_gbk("\u{00F7}", b"\xA1\xC2");
747
748 encode_gb18030("\u{9FB9}", b"\xFE\x7E");
750 encode_gb18030("\u{FE14}", b"\xA6\xDD");
751 encode_gb18030("\u{E843}", b"\xFE\x7E");
752 encode_gb18030("\u{E791}", b"\xA6\xDD");
753
754 encode_gb18030("\u{E817}", b"\xFE\x52");
756 }
757
758 #[test]
759 fn test_gb18030_encode_from_utf16_max_length() {
760 let mut output = [0u8; 20];
761 let mut encoder = GB18030.new_encoder();
762 {
763 let needed = encoder
764 .max_buffer_length_from_utf16_without_replacement(1)
765 .unwrap();
766 let (result, read, written) = encoder.encode_from_utf16_without_replacement(
767 &[0x3000],
768 &mut output[..needed],
769 true,
770 );
771 assert_eq!(result, EncoderResult::InputEmpty);
772 assert_eq!(read, 1);
773 assert_eq!(written, 2);
774 assert_eq!(output[0], 0xA1);
775 assert_eq!(output[1], 0xA1);
776 }
777 }
778}