1use crate::error::{Error, ErrorCode, Result};
2use alloc::vec::Vec;
3use core::cmp;
4use core::mem;
5use core::ops::Deref;
6use core::str;
7
8#[cfg(feature = "std")]
9use crate::io;
10#[cfg(feature = "std")]
11use crate::iter::LineColIterator;
12
13#[cfg(feature = "raw_value")]
14use crate::raw::BorrowedRawDeserializer;
15#[cfg(all(feature = "raw_value", feature = "std"))]
16use crate::raw::OwnedRawDeserializer;
17#[cfg(all(feature = "raw_value", feature = "std"))]
18use alloc::string::String;
19#[cfg(feature = "raw_value")]
20use serde::de::Visitor;
21
22pub trait Read<'de>: private::Sealed {
29 #[doc(hidden)]
30 fn next(&mut self) -> Result<Option<u8>>;
31 #[doc(hidden)]
32 fn peek(&mut self) -> Result<Option<u8>>;
33
34 #[doc(hidden)]
36 fn discard(&mut self);
37
38 #[doc(hidden)]
46 fn position(&self) -> Position;
47
48 #[doc(hidden)]
56 fn peek_position(&self) -> Position;
57
58 #[doc(hidden)]
61 fn byte_offset(&self) -> usize;
62
63 #[doc(hidden)]
67 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>>;
68
69 #[doc(hidden)]
76 fn parse_str_raw<'s>(
77 &'s mut self,
78 scratch: &'s mut Vec<u8>,
79 ) -> Result<Reference<'de, 's, [u8]>>;
80
81 #[doc(hidden)]
84 fn ignore_str(&mut self) -> Result<()>;
85
86 #[doc(hidden)]
89 fn decode_hex_escape(&mut self) -> Result<u16>;
90
91 #[cfg(feature = "raw_value")]
95 #[doc(hidden)]
96 fn begin_raw_buffering(&mut self);
97
98 #[cfg(feature = "raw_value")]
101 #[doc(hidden)]
102 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
103 where
104 V: Visitor<'de>;
105
106 #[doc(hidden)]
111 const should_early_return_if_failed: bool;
112
113 #[doc(hidden)]
116 fn set_failed(&mut self, failed: &mut bool);
117}
118
119pub struct Position {
120 pub line: usize,
121 pub column: usize,
122}
123
124pub enum Reference<'b, 'c, T>
125where
126 T: ?Sized + 'static,
127{
128 Borrowed(&'b T),
129 Copied(&'c T),
130}
131
132impl<'b, 'c, T> Deref for Reference<'b, 'c, T>
133where
134 T: ?Sized + 'static,
135{
136 type Target = T;
137
138 fn deref(&self) -> &Self::Target {
139 match *self {
140 Reference::Borrowed(b) => b,
141 Reference::Copied(c) => c,
142 }
143 }
144}
145
146#[cfg(feature = "std")]
148#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
149pub struct IoRead<R>
150where
151 R: io::Read,
152{
153 iter: LineColIterator<io::Bytes<R>>,
154 ch: Option<u8>,
156 #[cfg(feature = "raw_value")]
157 raw_buffer: Option<Vec<u8>>,
158}
159
160pub struct SliceRead<'a> {
165 slice: &'a [u8],
166 index: usize,
168 #[cfg(feature = "raw_value")]
169 raw_buffering_start_index: usize,
170}
171
172pub struct StrRead<'a> {
176 delegate: SliceRead<'a>,
177 #[cfg(feature = "raw_value")]
178 data: &'a str,
179}
180
181mod private {
183 pub trait Sealed {}
184}
185
186#[cfg(feature = "std")]
189impl<R> IoRead<R>
190where
191 R: io::Read,
192{
193 pub fn new(reader: R) -> Self {
195 IoRead {
196 iter: LineColIterator::new(reader.bytes()),
197 ch: None,
198 #[cfg(feature = "raw_value")]
199 raw_buffer: None,
200 }
201 }
202}
203
204#[cfg(feature = "std")]
205impl<R> private::Sealed for IoRead<R> where R: io::Read {}
206
207#[cfg(feature = "std")]
208impl<R> IoRead<R>
209where
210 R: io::Read,
211{
212 fn parse_str_bytes<'s, T, F>(
213 &'s mut self,
214 scratch: &'s mut Vec<u8>,
215 validate: bool,
216 result: F,
217 ) -> Result<T>
218 where
219 T: 's,
220 F: FnOnce(&'s Self, &'s [u8]) -> Result<T>,
221 {
222 loop {
223 let ch = tri!(next_or_eof(self));
224 if !is_escape(ch, true) {
225 scratch.push(ch);
226 continue;
227 }
228 match ch {
229 b'"' => {
230 return result(self, scratch);
231 }
232 b'\\' => {
233 tri!(parse_escape(self, validate, scratch));
234 }
235 _ => {
236 if validate {
237 return error(self, ErrorCode::ControlCharacterWhileParsingString);
238 }
239 scratch.push(ch);
240 }
241 }
242 }
243 }
244}
245
246#[cfg(feature = "std")]
247impl<'de, R> Read<'de> for IoRead<R>
248where
249 R: io::Read,
250{
251 #[inline]
252 fn next(&mut self) -> Result<Option<u8>> {
253 match self.ch.take() {
254 Some(ch) => {
255 #[cfg(feature = "raw_value")]
256 {
257 if let Some(buf) = &mut self.raw_buffer {
258 buf.push(ch);
259 }
260 }
261 Ok(Some(ch))
262 }
263 None => match self.iter.next() {
264 Some(Err(err)) => Err(Error::io(err)),
265 Some(Ok(ch)) => {
266 #[cfg(feature = "raw_value")]
267 {
268 if let Some(buf) = &mut self.raw_buffer {
269 buf.push(ch);
270 }
271 }
272 Ok(Some(ch))
273 }
274 None => Ok(None),
275 },
276 }
277 }
278
279 #[inline]
280 fn peek(&mut self) -> Result<Option<u8>> {
281 match self.ch {
282 Some(ch) => Ok(Some(ch)),
283 None => match self.iter.next() {
284 Some(Err(err)) => Err(Error::io(err)),
285 Some(Ok(ch)) => {
286 self.ch = Some(ch);
287 Ok(self.ch)
288 }
289 None => Ok(None),
290 },
291 }
292 }
293
294 #[cfg(not(feature = "raw_value"))]
295 #[inline]
296 fn discard(&mut self) {
297 self.ch = None;
298 }
299
300 #[cfg(feature = "raw_value")]
301 fn discard(&mut self) {
302 if let Some(ch) = self.ch.take() {
303 if let Some(buf) = &mut self.raw_buffer {
304 buf.push(ch);
305 }
306 }
307 }
308
309 fn position(&self) -> Position {
310 Position {
311 line: self.iter.line(),
312 column: self.iter.col(),
313 }
314 }
315
316 fn peek_position(&self) -> Position {
317 self.position()
320 }
321
322 fn byte_offset(&self) -> usize {
323 match self.ch {
324 Some(_) => self.iter.byte_offset() - 1,
325 None => self.iter.byte_offset(),
326 }
327 }
328
329 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
330 self.parse_str_bytes(scratch, true, as_str)
331 .map(Reference::Copied)
332 }
333
334 fn parse_str_raw<'s>(
335 &'s mut self,
336 scratch: &'s mut Vec<u8>,
337 ) -> Result<Reference<'de, 's, [u8]>> {
338 self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
339 .map(Reference::Copied)
340 }
341
342 fn ignore_str(&mut self) -> Result<()> {
343 loop {
344 let ch = tri!(next_or_eof(self));
345 if !is_escape(ch, true) {
346 continue;
347 }
348 match ch {
349 b'"' => {
350 return Ok(());
351 }
352 b'\\' => {
353 tri!(ignore_escape(self));
354 }
355 _ => {
356 return error(self, ErrorCode::ControlCharacterWhileParsingString);
357 }
358 }
359 }
360 }
361
362 fn decode_hex_escape(&mut self) -> Result<u16> {
363 let a = tri!(next_or_eof(self));
364 let b = tri!(next_or_eof(self));
365 let c = tri!(next_or_eof(self));
366 let d = tri!(next_or_eof(self));
367 match decode_four_hex_digits(a, b, c, d) {
368 Some(val) => Ok(val),
369 None => error(self, ErrorCode::InvalidEscape),
370 }
371 }
372
373 #[cfg(feature = "raw_value")]
374 fn begin_raw_buffering(&mut self) {
375 self.raw_buffer = Some(Vec::new());
376 }
377
378 #[cfg(feature = "raw_value")]
379 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
380 where
381 V: Visitor<'de>,
382 {
383 let raw = self.raw_buffer.take().unwrap();
384 let raw = match String::from_utf8(raw) {
385 Ok(raw) => raw,
386 Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint),
387 };
388 visitor.visit_map(OwnedRawDeserializer {
389 raw_value: Some(raw),
390 })
391 }
392
393 const should_early_return_if_failed: bool = true;
394
395 #[inline]
396 #[cold]
397 fn set_failed(&mut self, failed: &mut bool) {
398 *failed = true;
399 }
400}
401
402impl<'a> SliceRead<'a> {
405 pub fn new(slice: &'a [u8]) -> Self {
407 SliceRead {
408 slice,
409 index: 0,
410 #[cfg(feature = "raw_value")]
411 raw_buffering_start_index: 0,
412 }
413 }
414
415 fn position_of_index(&self, i: usize) -> Position {
416 let start_of_line = match memchr::memrchr(b'\n', &self.slice[..i]) {
417 Some(position) => position + 1,
418 None => 0,
419 };
420 Position {
421 line: 1 + memchr::memchr_iter(b'\n', &self.slice[..start_of_line]).count(),
422 column: i - start_of_line,
423 }
424 }
425
426 fn skip_to_escape(&mut self, forbid_control_characters: bool) {
427 if self.index == self.slice.len()
429 || is_escape(self.slice[self.index], forbid_control_characters)
430 {
431 return;
432 }
433 self.index += 1;
434
435 let rest = &self.slice[self.index..];
436
437 if !forbid_control_characters {
438 self.index += memchr::memchr2(b'"', b'\\', rest).unwrap_or(rest.len());
439 return;
440 }
441
442 #[cfg(fast_arithmetic = "64")]
450 type Chunk = u64;
451 #[cfg(fast_arithmetic = "32")]
452 type Chunk = u32;
453
454 const STEP: usize = mem::size_of::<Chunk>();
455 const ONE_BYTES: Chunk = Chunk::MAX / 255; for chunk in rest.chunks_exact(STEP) {
458 let chars = Chunk::from_le_bytes(chunk.try_into().unwrap());
459 let contains_ctrl = chars.wrapping_sub(ONE_BYTES * 0x20) & !chars;
460 let chars_quote = chars ^ (ONE_BYTES * Chunk::from(b'"'));
461 let contains_quote = chars_quote.wrapping_sub(ONE_BYTES) & !chars_quote;
462 let chars_backslash = chars ^ (ONE_BYTES * Chunk::from(b'\\'));
463 let contains_backslash = chars_backslash.wrapping_sub(ONE_BYTES) & !chars_backslash;
464 let masked = (contains_ctrl | contains_quote | contains_backslash) & (ONE_BYTES << 7);
465 if masked != 0 {
466 self.index = unsafe { chunk.as_ptr().offset_from(self.slice.as_ptr()) } as usize
468 + masked.trailing_zeros() as usize / 8;
469 return;
470 }
471 }
472
473 self.index += rest.len() / STEP * STEP;
474 self.skip_to_escape_slow();
475 }
476
477 #[cold]
478 #[inline(never)]
479 fn skip_to_escape_slow(&mut self) {
480 while self.index < self.slice.len() && !is_escape(self.slice[self.index], true) {
481 self.index += 1;
482 }
483 }
484
485 fn parse_str_bytes<'s, T, F>(
489 &'s mut self,
490 scratch: &'s mut Vec<u8>,
491 validate: bool,
492 result: F,
493 ) -> Result<Reference<'a, 's, T>>
494 where
495 T: ?Sized + 's,
496 F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>,
497 {
498 let mut start = self.index;
500
501 loop {
502 self.skip_to_escape(validate);
503 if self.index == self.slice.len() {
504 return error(self, ErrorCode::EofWhileParsingString);
505 }
506 match self.slice[self.index] {
507 b'"' => {
508 if scratch.is_empty() {
509 let borrowed = &self.slice[start..self.index];
512 self.index += 1;
513 return result(self, borrowed).map(Reference::Borrowed);
514 } else {
515 scratch.extend_from_slice(&self.slice[start..self.index]);
516 self.index += 1;
517 return result(self, scratch).map(Reference::Copied);
518 }
519 }
520 b'\\' => {
521 scratch.extend_from_slice(&self.slice[start..self.index]);
522 self.index += 1;
523 tri!(parse_escape(self, validate, scratch));
524 start = self.index;
525 }
526 _ => {
527 self.index += 1;
528 return error(self, ErrorCode::ControlCharacterWhileParsingString);
529 }
530 }
531 }
532 }
533}
534
535impl<'a> private::Sealed for SliceRead<'a> {}
536
537impl<'a> Read<'a> for SliceRead<'a> {
538 #[inline]
539 fn next(&mut self) -> Result<Option<u8>> {
540 Ok(if self.index < self.slice.len() {
543 let ch = self.slice[self.index];
544 self.index += 1;
545 Some(ch)
546 } else {
547 None
548 })
549 }
550
551 #[inline]
552 fn peek(&mut self) -> Result<Option<u8>> {
553 Ok(if self.index < self.slice.len() {
556 Some(self.slice[self.index])
557 } else {
558 None
559 })
560 }
561
562 #[inline]
563 fn discard(&mut self) {
564 self.index += 1;
565 }
566
567 fn position(&self) -> Position {
568 self.position_of_index(self.index)
569 }
570
571 fn peek_position(&self) -> Position {
572 self.position_of_index(cmp::min(self.slice.len(), self.index + 1))
575 }
576
577 fn byte_offset(&self) -> usize {
578 self.index
579 }
580
581 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
582 self.parse_str_bytes(scratch, true, as_str)
583 }
584
585 fn parse_str_raw<'s>(
586 &'s mut self,
587 scratch: &'s mut Vec<u8>,
588 ) -> Result<Reference<'a, 's, [u8]>> {
589 self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
590 }
591
592 fn ignore_str(&mut self) -> Result<()> {
593 loop {
594 self.skip_to_escape(true);
595 if self.index == self.slice.len() {
596 return error(self, ErrorCode::EofWhileParsingString);
597 }
598 match self.slice[self.index] {
599 b'"' => {
600 self.index += 1;
601 return Ok(());
602 }
603 b'\\' => {
604 self.index += 1;
605 tri!(ignore_escape(self));
606 }
607 _ => {
608 return error(self, ErrorCode::ControlCharacterWhileParsingString);
609 }
610 }
611 }
612 }
613
614 #[inline]
615 fn decode_hex_escape(&mut self) -> Result<u16> {
616 match self.slice[self.index..] {
617 [a, b, c, d, ..] => {
618 self.index += 4;
619 match decode_four_hex_digits(a, b, c, d) {
620 Some(val) => Ok(val),
621 None => error(self, ErrorCode::InvalidEscape),
622 }
623 }
624 _ => {
625 self.index = self.slice.len();
626 error(self, ErrorCode::EofWhileParsingString)
627 }
628 }
629 }
630
631 #[cfg(feature = "raw_value")]
632 fn begin_raw_buffering(&mut self) {
633 self.raw_buffering_start_index = self.index;
634 }
635
636 #[cfg(feature = "raw_value")]
637 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
638 where
639 V: Visitor<'a>,
640 {
641 let raw = &self.slice[self.raw_buffering_start_index..self.index];
642 let raw = match str::from_utf8(raw) {
643 Ok(raw) => raw,
644 Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint),
645 };
646 visitor.visit_map(BorrowedRawDeserializer {
647 raw_value: Some(raw),
648 })
649 }
650
651 const should_early_return_if_failed: bool = false;
652
653 #[inline]
654 #[cold]
655 fn set_failed(&mut self, _failed: &mut bool) {
656 self.slice = &self.slice[..self.index];
657 }
658}
659
660impl<'a> StrRead<'a> {
663 pub fn new(s: &'a str) -> Self {
665 StrRead {
666 delegate: SliceRead::new(s.as_bytes()),
667 #[cfg(feature = "raw_value")]
668 data: s,
669 }
670 }
671}
672
673impl<'a> private::Sealed for StrRead<'a> {}
674
675impl<'a> Read<'a> for StrRead<'a> {
676 #[inline]
677 fn next(&mut self) -> Result<Option<u8>> {
678 self.delegate.next()
679 }
680
681 #[inline]
682 fn peek(&mut self) -> Result<Option<u8>> {
683 self.delegate.peek()
684 }
685
686 #[inline]
687 fn discard(&mut self) {
688 self.delegate.discard();
689 }
690
691 fn position(&self) -> Position {
692 self.delegate.position()
693 }
694
695 fn peek_position(&self) -> Position {
696 self.delegate.peek_position()
697 }
698
699 fn byte_offset(&self) -> usize {
700 self.delegate.byte_offset()
701 }
702
703 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
704 self.delegate.parse_str_bytes(scratch, true, |_, bytes| {
705 Ok(unsafe { str::from_utf8_unchecked(bytes) })
709 })
710 }
711
712 fn parse_str_raw<'s>(
713 &'s mut self,
714 scratch: &'s mut Vec<u8>,
715 ) -> Result<Reference<'a, 's, [u8]>> {
716 self.delegate.parse_str_raw(scratch)
717 }
718
719 fn ignore_str(&mut self) -> Result<()> {
720 self.delegate.ignore_str()
721 }
722
723 fn decode_hex_escape(&mut self) -> Result<u16> {
724 self.delegate.decode_hex_escape()
725 }
726
727 #[cfg(feature = "raw_value")]
728 fn begin_raw_buffering(&mut self) {
729 self.delegate.begin_raw_buffering();
730 }
731
732 #[cfg(feature = "raw_value")]
733 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
734 where
735 V: Visitor<'a>,
736 {
737 let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index];
738 visitor.visit_map(BorrowedRawDeserializer {
739 raw_value: Some(raw),
740 })
741 }
742
743 const should_early_return_if_failed: bool = false;
744
745 #[inline]
746 #[cold]
747 fn set_failed(&mut self, failed: &mut bool) {
748 self.delegate.set_failed(failed);
749 }
750}
751
752impl<'a, 'de, R> private::Sealed for &'a mut R where R: Read<'de> {}
755
756impl<'a, 'de, R> Read<'de> for &'a mut R
757where
758 R: Read<'de>,
759{
760 fn next(&mut self) -> Result<Option<u8>> {
761 R::next(self)
762 }
763
764 fn peek(&mut self) -> Result<Option<u8>> {
765 R::peek(self)
766 }
767
768 fn discard(&mut self) {
769 R::discard(self);
770 }
771
772 fn position(&self) -> Position {
773 R::position(self)
774 }
775
776 fn peek_position(&self) -> Position {
777 R::peek_position(self)
778 }
779
780 fn byte_offset(&self) -> usize {
781 R::byte_offset(self)
782 }
783
784 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
785 R::parse_str(self, scratch)
786 }
787
788 fn parse_str_raw<'s>(
789 &'s mut self,
790 scratch: &'s mut Vec<u8>,
791 ) -> Result<Reference<'de, 's, [u8]>> {
792 R::parse_str_raw(self, scratch)
793 }
794
795 fn ignore_str(&mut self) -> Result<()> {
796 R::ignore_str(self)
797 }
798
799 fn decode_hex_escape(&mut self) -> Result<u16> {
800 R::decode_hex_escape(self)
801 }
802
803 #[cfg(feature = "raw_value")]
804 fn begin_raw_buffering(&mut self) {
805 R::begin_raw_buffering(self);
806 }
807
808 #[cfg(feature = "raw_value")]
809 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
810 where
811 V: Visitor<'de>,
812 {
813 R::end_raw_buffering(self, visitor)
814 }
815
816 const should_early_return_if_failed: bool = R::should_early_return_if_failed;
817
818 fn set_failed(&mut self, failed: &mut bool) {
819 R::set_failed(self, failed);
820 }
821}
822
823pub trait Fused: private::Sealed {}
827impl<'a> Fused for SliceRead<'a> {}
828impl<'a> Fused for StrRead<'a> {}
829
830fn is_escape(ch: u8, including_control_characters: bool) -> bool {
831 ch == b'"' || ch == b'\\' || (including_control_characters && ch < 0x20)
832}
833
834fn next_or_eof<'de, R>(read: &mut R) -> Result<u8>
835where
836 R: ?Sized + Read<'de>,
837{
838 match tri!(read.next()) {
839 Some(b) => Ok(b),
840 None => error(read, ErrorCode::EofWhileParsingString),
841 }
842}
843
844fn peek_or_eof<'de, R>(read: &mut R) -> Result<u8>
845where
846 R: ?Sized + Read<'de>,
847{
848 match tri!(read.peek()) {
849 Some(b) => Ok(b),
850 None => error(read, ErrorCode::EofWhileParsingString),
851 }
852}
853
854fn error<'de, R, T>(read: &R, reason: ErrorCode) -> Result<T>
855where
856 R: ?Sized + Read<'de>,
857{
858 let position = read.position();
859 Err(Error::syntax(reason, position.line, position.column))
860}
861
862fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> {
863 str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint))
864}
865
866fn parse_escape<'de, R: Read<'de>>(
869 read: &mut R,
870 validate: bool,
871 scratch: &mut Vec<u8>,
872) -> Result<()> {
873 let ch = tri!(next_or_eof(read));
874
875 match ch {
876 b'"' => scratch.push(b'"'),
877 b'\\' => scratch.push(b'\\'),
878 b'/' => scratch.push(b'/'),
879 b'b' => scratch.push(b'\x08'),
880 b'f' => scratch.push(b'\x0c'),
881 b'n' => scratch.push(b'\n'),
882 b'r' => scratch.push(b'\r'),
883 b't' => scratch.push(b'\t'),
884 b'u' => return parse_unicode_escape(read, validate, scratch),
885 _ => return error(read, ErrorCode::InvalidEscape),
886 }
887
888 Ok(())
889}
890
891#[cold]
894fn parse_unicode_escape<'de, R: Read<'de>>(
895 read: &mut R,
896 validate: bool,
897 scratch: &mut Vec<u8>,
898) -> Result<()> {
899 let mut n = tri!(read.decode_hex_escape());
900
901 if validate && n >= 0xDC00 && n <= 0xDFFF {
906 return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
908 }
909
910 loop {
911 if n < 0xD800 || n > 0xDBFF {
912 push_wtf8_codepoint(n as u32, scratch);
915 return Ok(());
916 }
917
918 let n1 = n;
920
921 if tri!(peek_or_eof(read)) == b'\\' {
922 read.discard();
923 } else {
924 return if validate {
925 read.discard();
926 error(read, ErrorCode::UnexpectedEndOfHexEscape)
927 } else {
928 push_wtf8_codepoint(n1 as u32, scratch);
929 Ok(())
930 };
931 }
932
933 if tri!(peek_or_eof(read)) == b'u' {
934 read.discard();
935 } else {
936 return if validate {
937 read.discard();
938 error(read, ErrorCode::UnexpectedEndOfHexEscape)
939 } else {
940 push_wtf8_codepoint(n1 as u32, scratch);
941 parse_escape(read, validate, scratch)
946 };
947 }
948
949 let n2 = tri!(read.decode_hex_escape());
950
951 if n2 < 0xDC00 || n2 > 0xDFFF {
952 if validate {
953 return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
954 }
955 push_wtf8_codepoint(n1 as u32, scratch);
956 n = n2;
958 continue;
959 }
960
961 let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000;
964 push_wtf8_codepoint(n, scratch);
965 return Ok(());
966 }
967}
968
969#[inline]
972fn push_wtf8_codepoint(n: u32, scratch: &mut Vec<u8>) {
973 if n < 0x80 {
974 scratch.push(n as u8);
975 return;
976 }
977
978 scratch.reserve(4);
979
980 unsafe {
981 let ptr = scratch.as_mut_ptr().add(scratch.len());
982
983 let encoded_len = match n {
984 0..=0x7F => unreachable!(),
985 0x80..=0x7FF => {
986 ptr.write((n >> 6 & 0b0001_1111) as u8 | 0b1100_0000);
987 2
988 }
989 0x800..=0xFFFF => {
990 ptr.write((n >> 12 & 0b0000_1111) as u8 | 0b1110_0000);
991 ptr.add(1).write((n >> 6 & 0b0011_1111) as u8 | 0b1000_0000);
992 3
993 }
994 0x1_0000..=0x10_FFFF => {
995 ptr.write((n >> 18 & 0b0000_0111) as u8 | 0b1111_0000);
996 ptr.add(1)
997 .write((n >> 12 & 0b0011_1111) as u8 | 0b1000_0000);
998 ptr.add(2).write((n >> 6 & 0b0011_1111) as u8 | 0b1000_0000);
999 4
1000 }
1001 0x11_0000.. => unreachable!(),
1002 };
1003 ptr.add(encoded_len - 1)
1004 .write((n & 0b0011_1111) as u8 | 0b1000_0000);
1005
1006 scratch.set_len(scratch.len() + encoded_len);
1007 }
1008}
1009
1010fn ignore_escape<'de, R>(read: &mut R) -> Result<()>
1013where
1014 R: ?Sized + Read<'de>,
1015{
1016 let ch = tri!(next_or_eof(read));
1017
1018 match ch {
1019 b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
1020 b'u' => {
1021 tri!(read.decode_hex_escape());
1028 }
1029 _ => {
1030 return error(read, ErrorCode::InvalidEscape);
1031 }
1032 }
1033
1034 Ok(())
1035}
1036
1037const fn decode_hex_val_slow(val: u8) -> Option<u8> {
1038 match val {
1039 b'0'..=b'9' => Some(val - b'0'),
1040 b'A'..=b'F' => Some(val - b'A' + 10),
1041 b'a'..=b'f' => Some(val - b'a' + 10),
1042 _ => None,
1043 }
1044}
1045
1046const fn build_hex_table(shift: usize) -> [i16; 256] {
1047 let mut table = [0; 256];
1048 let mut ch = 0;
1049 while ch < 256 {
1050 table[ch] = match decode_hex_val_slow(ch as u8) {
1051 Some(val) => (val as i16) << shift,
1052 None => -1,
1053 };
1054 ch += 1;
1055 }
1056 table
1057}
1058
1059static HEX0: [i16; 256] = build_hex_table(0);
1060static HEX1: [i16; 256] = build_hex_table(4);
1061
1062fn decode_four_hex_digits(a: u8, b: u8, c: u8, d: u8) -> Option<u16> {
1063 let a = HEX1[a as usize] as i32;
1064 let b = HEX0[b as usize] as i32;
1065 let c = HEX1[c as usize] as i32;
1066 let d = HEX0[d as usize] as i32;
1067
1068 let codepoint = ((a | b) << 8) | c | d;
1069
1070 if codepoint >= 0 {
1072 Some(codepoint as u16)
1073 } else {
1074 None
1075 }
1076}