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 #[cfg(feature = "raw_value")]
159 raw_buffering_start_position: Position,
160}
161
162pub struct SliceRead<'a> {
167 slice: &'a [u8],
168 index: usize,
170 #[cfg(feature = "raw_value")]
171 raw_buffering_start_index: usize,
172}
173
174pub struct StrRead<'a> {
178 delegate: SliceRead<'a>,
179 #[cfg(feature = "raw_value")]
180 data: &'a str,
181}
182
183mod private {
185 pub trait Sealed {}
186}
187
188#[cfg(feature = "std")]
191impl<R> IoRead<R>
192where
193 R: io::Read,
194{
195 pub fn new(reader: R) -> Self {
203 IoRead {
204 iter: LineColIterator::new(reader.bytes()),
205 ch: None,
206 #[cfg(feature = "raw_value")]
207 raw_buffer: None,
208 #[cfg(feature = "raw_value")]
209 raw_buffering_start_position: Position { line: 1, column: 0 },
210 }
211 }
212}
213
214#[cfg(feature = "std")]
215impl<R> private::Sealed for IoRead<R> where R: io::Read {}
216
217#[cfg(feature = "std")]
218impl<R> IoRead<R>
219where
220 R: io::Read,
221{
222 fn parse_str_bytes<'s, T, F>(
223 &'s mut self,
224 scratch: &'s mut Vec<u8>,
225 validate: bool,
226 result: F,
227 ) -> Result<T>
228 where
229 T: 's,
230 F: FnOnce(&'s Self, &'s [u8]) -> Result<T>,
231 {
232 loop {
233 let ch = tri!(next_or_eof(self));
234 if !is_escape(ch, true) {
235 scratch.push(ch);
236 continue;
237 }
238 match ch {
239 b'"' => {
240 return result(self, scratch);
241 }
242 b'\\' => {
243 tri!(parse_escape(self, validate, scratch));
244 }
245 _ => {
246 if validate {
247 return error(self, ErrorCode::ControlCharacterWhileParsingString);
248 }
249 scratch.push(ch);
250 }
251 }
252 }
253 }
254}
255
256#[cfg(feature = "std")]
257impl<'de, R> Read<'de> for IoRead<R>
258where
259 R: io::Read,
260{
261 #[inline]
262 fn next(&mut self) -> Result<Option<u8>> {
263 match self.ch.take() {
264 Some(ch) => {
265 #[cfg(feature = "raw_value")]
266 {
267 if let Some(buf) = &mut self.raw_buffer {
268 buf.push(ch);
269 }
270 }
271 Ok(Some(ch))
272 }
273 None => match self.iter.next() {
274 Some(Err(err)) => Err(Error::io(err)),
275 Some(Ok(ch)) => {
276 #[cfg(feature = "raw_value")]
277 {
278 if let Some(buf) = &mut self.raw_buffer {
279 buf.push(ch);
280 }
281 }
282 Ok(Some(ch))
283 }
284 None => Ok(None),
285 },
286 }
287 }
288
289 #[inline]
290 fn peek(&mut self) -> Result<Option<u8>> {
291 match self.ch {
292 Some(ch) => Ok(Some(ch)),
293 None => match self.iter.next() {
294 Some(Err(err)) => Err(Error::io(err)),
295 Some(Ok(ch)) => {
296 self.ch = Some(ch);
297 Ok(self.ch)
298 }
299 None => Ok(None),
300 },
301 }
302 }
303
304 #[cfg(not(feature = "raw_value"))]
305 #[inline]
306 fn discard(&mut self) {
307 self.ch = None;
308 }
309
310 #[cfg(feature = "raw_value")]
311 fn discard(&mut self) {
312 if let Some(ch) = self.ch.take() {
313 if let Some(buf) = &mut self.raw_buffer {
314 buf.push(ch);
315 }
316 }
317 }
318
319 fn position(&self) -> Position {
320 Position {
321 line: self.iter.line(),
322 column: self.iter.col(),
323 }
324 }
325
326 fn peek_position(&self) -> Position {
327 self.position()
330 }
331
332 fn byte_offset(&self) -> usize {
333 match self.ch {
334 Some(_) => self.iter.byte_offset() - 1,
335 None => self.iter.byte_offset(),
336 }
337 }
338
339 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
340 self.parse_str_bytes(scratch, true, as_str)
341 .map(Reference::Copied)
342 }
343
344 fn parse_str_raw<'s>(
345 &'s mut self,
346 scratch: &'s mut Vec<u8>,
347 ) -> Result<Reference<'de, 's, [u8]>> {
348 self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
349 .map(Reference::Copied)
350 }
351
352 fn ignore_str(&mut self) -> Result<()> {
353 loop {
354 let ch = tri!(next_or_eof(self));
355 if !is_escape(ch, true) {
356 continue;
357 }
358 match ch {
359 b'"' => {
360 return Ok(());
361 }
362 b'\\' => {
363 tri!(ignore_escape(self));
364 }
365 _ => {
366 return error(self, ErrorCode::ControlCharacterWhileParsingString);
367 }
368 }
369 }
370 }
371
372 fn decode_hex_escape(&mut self) -> Result<u16> {
373 let a = tri!(next_or_eof(self));
374 let b = tri!(next_or_eof(self));
375 let c = tri!(next_or_eof(self));
376 let d = tri!(next_or_eof(self));
377 match decode_four_hex_digits(a, b, c, d) {
378 Some(val) => Ok(val),
379 None => error(self, ErrorCode::InvalidEscape),
380 }
381 }
382
383 #[cfg(feature = "raw_value")]
384 fn begin_raw_buffering(&mut self) {
385 let position = self.position();
386 self.raw_buffering_start_position = Position {
387 line: position.line,
388 column: position.column - usize::from(self.ch.is_some()),
389 };
390 self.raw_buffer = Some(Vec::new());
391 }
392
393 #[cfg(feature = "raw_value")]
394 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
395 where
396 V: Visitor<'de>,
397 {
398 let raw = self.raw_buffer.take().unwrap();
399 let raw = match String::from_utf8(raw) {
400 Ok(raw) => raw,
401 Err(err) => {
402 let prefix = &err.as_bytes()[..=err.utf8_error().valid_up_to()];
403 let line;
404 let column;
405 if let Some(last_newline) = memchr::memrchr(b'\n', prefix) {
406 line = self.raw_buffering_start_position.line
407 + memchr::memchr_iter(b'\n', &prefix[..last_newline]).count()
408 + 1;
409 column = prefix.len() - last_newline - 1;
410 } else {
411 line = self.raw_buffering_start_position.line;
412 column = self.raw_buffering_start_position.column + prefix.len();
413 }
414 return Err(Error::syntax(
415 ErrorCode::InvalidUnicodeCodePoint,
416 line,
417 column,
418 ));
419 }
420 };
421 visitor.visit_map(OwnedRawDeserializer {
422 raw_value: Some(raw),
423 })
424 }
425
426 const should_early_return_if_failed: bool = true;
427
428 #[inline]
429 #[cold]
430 fn set_failed(&mut self, failed: &mut bool) {
431 *failed = true;
432 }
433}
434
435impl<'a> SliceRead<'a> {
438 pub fn new(slice: &'a [u8]) -> Self {
440 SliceRead {
441 slice,
442 index: 0,
443 #[cfg(feature = "raw_value")]
444 raw_buffering_start_index: 0,
445 }
446 }
447
448 fn position_of_index(&self, i: usize) -> Position {
449 let start_of_line = match memchr::memrchr(b'\n', &self.slice[..i]) {
450 Some(position) => position + 1,
451 None => 0,
452 };
453 Position {
454 line: 1 + memchr::memchr_iter(b'\n', &self.slice[..start_of_line]).count(),
455 column: i - start_of_line,
456 }
457 }
458
459 fn skip_to_escape(&mut self, forbid_control_characters: bool) {
460 if self.index == self.slice.len()
462 || is_escape(self.slice[self.index], forbid_control_characters)
463 {
464 return;
465 }
466 self.index += 1;
467
468 let rest = &self.slice[self.index..];
469
470 if !forbid_control_characters {
471 self.index += memchr::memchr2(b'"', b'\\', rest).unwrap_or(rest.len());
472 return;
473 }
474
475 #[cfg(fast_arithmetic = "64")]
483 type Chunk = u64;
484 #[cfg(fast_arithmetic = "32")]
485 type Chunk = u32;
486
487 const STEP: usize = mem::size_of::<Chunk>();
488 const ONE_BYTES: Chunk = Chunk::MAX / 255; for chunk in rest.chunks_exact(STEP) {
491 let chars = Chunk::from_le_bytes(chunk.try_into().unwrap());
492 let contains_ctrl = chars.wrapping_sub(ONE_BYTES * 0x20) & !chars;
493 let chars_quote = chars ^ (ONE_BYTES * Chunk::from(b'"'));
494 let contains_quote = chars_quote.wrapping_sub(ONE_BYTES) & !chars_quote;
495 let chars_backslash = chars ^ (ONE_BYTES * Chunk::from(b'\\'));
496 let contains_backslash = chars_backslash.wrapping_sub(ONE_BYTES) & !chars_backslash;
497 let masked = (contains_ctrl | contains_quote | contains_backslash) & (ONE_BYTES << 7);
498 if masked != 0 {
499 self.index = unsafe { chunk.as_ptr().offset_from(self.slice.as_ptr()) } as usize
501 + masked.trailing_zeros() as usize / 8;
502 return;
503 }
504 }
505
506 self.index += rest.len() / STEP * STEP;
507 self.skip_to_escape_slow();
508 }
509
510 #[cold]
511 #[inline(never)]
512 fn skip_to_escape_slow(&mut self) {
513 while self.index < self.slice.len() && !is_escape(self.slice[self.index], true) {
514 self.index += 1;
515 }
516 }
517
518 fn parse_str_bytes<'s, T, F>(
522 &'s mut self,
523 scratch: &'s mut Vec<u8>,
524 validate: bool,
525 result: F,
526 ) -> Result<Reference<'a, 's, T>>
527 where
528 T: ?Sized + 's,
529 F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>,
530 {
531 let mut start = self.index;
533
534 loop {
535 self.skip_to_escape(validate);
536 if self.index == self.slice.len() {
537 return error(self, ErrorCode::EofWhileParsingString);
538 }
539 match self.slice[self.index] {
540 b'"' => {
541 if scratch.is_empty() {
542 let borrowed = &self.slice[start..self.index];
545 self.index += 1;
546 return result(self, borrowed).map(Reference::Borrowed);
547 } else {
548 scratch.extend_from_slice(&self.slice[start..self.index]);
549 self.index += 1;
550 return result(self, scratch).map(Reference::Copied);
551 }
552 }
553 b'\\' => {
554 scratch.extend_from_slice(&self.slice[start..self.index]);
555 self.index += 1;
556 tri!(parse_escape(self, validate, scratch));
557 start = self.index;
558 }
559 _ => {
560 self.index += 1;
561 return error(self, ErrorCode::ControlCharacterWhileParsingString);
562 }
563 }
564 }
565 }
566}
567
568impl<'a> private::Sealed for SliceRead<'a> {}
569
570impl<'a> Read<'a> for SliceRead<'a> {
571 #[inline]
572 fn next(&mut self) -> Result<Option<u8>> {
573 Ok(if self.index < self.slice.len() {
576 let ch = self.slice[self.index];
577 self.index += 1;
578 Some(ch)
579 } else {
580 None
581 })
582 }
583
584 #[inline]
585 fn peek(&mut self) -> Result<Option<u8>> {
586 Ok(if self.index < self.slice.len() {
589 Some(self.slice[self.index])
590 } else {
591 None
592 })
593 }
594
595 #[inline]
596 fn discard(&mut self) {
597 self.index += 1;
598 }
599
600 fn position(&self) -> Position {
601 self.position_of_index(self.index)
602 }
603
604 fn peek_position(&self) -> Position {
605 self.position_of_index(cmp::min(self.slice.len(), self.index + 1))
608 }
609
610 fn byte_offset(&self) -> usize {
611 self.index
612 }
613
614 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
615 self.parse_str_bytes(scratch, true, as_str)
616 }
617
618 fn parse_str_raw<'s>(
619 &'s mut self,
620 scratch: &'s mut Vec<u8>,
621 ) -> Result<Reference<'a, 's, [u8]>> {
622 self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
623 }
624
625 fn ignore_str(&mut self) -> Result<()> {
626 loop {
627 self.skip_to_escape(true);
628 if self.index == self.slice.len() {
629 return error(self, ErrorCode::EofWhileParsingString);
630 }
631 match self.slice[self.index] {
632 b'"' => {
633 self.index += 1;
634 return Ok(());
635 }
636 b'\\' => {
637 self.index += 1;
638 tri!(ignore_escape(self));
639 }
640 _ => {
641 return error(self, ErrorCode::ControlCharacterWhileParsingString);
642 }
643 }
644 }
645 }
646
647 #[inline]
648 fn decode_hex_escape(&mut self) -> Result<u16> {
649 match self.slice[self.index..] {
650 [a, b, c, d, ..] => {
651 self.index += 4;
652 match decode_four_hex_digits(a, b, c, d) {
653 Some(val) => Ok(val),
654 None => error(self, ErrorCode::InvalidEscape),
655 }
656 }
657 _ => {
658 self.index = self.slice.len();
659 error(self, ErrorCode::EofWhileParsingString)
660 }
661 }
662 }
663
664 #[cfg(feature = "raw_value")]
665 fn begin_raw_buffering(&mut self) {
666 self.raw_buffering_start_index = self.index;
667 }
668
669 #[cfg(feature = "raw_value")]
670 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
671 where
672 V: Visitor<'a>,
673 {
674 let raw = &self.slice[self.raw_buffering_start_index..self.index];
675 let raw = match str::from_utf8(raw) {
676 Ok(raw) => raw,
677 Err(err) => {
678 let at = self.raw_buffering_start_index + err.valid_up_to() + 1;
679 let position = self.position_of_index(at);
680 return Err(Error::syntax(
681 ErrorCode::InvalidUnicodeCodePoint,
682 position.line,
683 position.column,
684 ));
685 }
686 };
687 visitor.visit_map(BorrowedRawDeserializer {
688 raw_value: Some(raw),
689 })
690 }
691
692 const should_early_return_if_failed: bool = false;
693
694 #[inline]
695 #[cold]
696 fn set_failed(&mut self, _failed: &mut bool) {
697 self.slice = &self.slice[..self.index];
698 }
699}
700
701impl<'a> StrRead<'a> {
704 pub fn new(s: &'a str) -> Self {
706 StrRead {
707 delegate: SliceRead::new(s.as_bytes()),
708 #[cfg(feature = "raw_value")]
709 data: s,
710 }
711 }
712}
713
714impl<'a> private::Sealed for StrRead<'a> {}
715
716impl<'a> Read<'a> for StrRead<'a> {
717 #[inline]
718 fn next(&mut self) -> Result<Option<u8>> {
719 self.delegate.next()
720 }
721
722 #[inline]
723 fn peek(&mut self) -> Result<Option<u8>> {
724 self.delegate.peek()
725 }
726
727 #[inline]
728 fn discard(&mut self) {
729 self.delegate.discard();
730 }
731
732 fn position(&self) -> Position {
733 self.delegate.position()
734 }
735
736 fn peek_position(&self) -> Position {
737 self.delegate.peek_position()
738 }
739
740 fn byte_offset(&self) -> usize {
741 self.delegate.byte_offset()
742 }
743
744 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
745 self.delegate.parse_str_bytes(scratch, true, |_, bytes| {
746 Ok(unsafe { str::from_utf8_unchecked(bytes) })
750 })
751 }
752
753 fn parse_str_raw<'s>(
754 &'s mut self,
755 scratch: &'s mut Vec<u8>,
756 ) -> Result<Reference<'a, 's, [u8]>> {
757 self.delegate.parse_str_raw(scratch)
758 }
759
760 fn ignore_str(&mut self) -> Result<()> {
761 self.delegate.ignore_str()
762 }
763
764 fn decode_hex_escape(&mut self) -> Result<u16> {
765 self.delegate.decode_hex_escape()
766 }
767
768 #[cfg(feature = "raw_value")]
769 fn begin_raw_buffering(&mut self) {
770 self.delegate.begin_raw_buffering();
771 }
772
773 #[cfg(feature = "raw_value")]
774 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
775 where
776 V: Visitor<'a>,
777 {
778 let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index];
779 visitor.visit_map(BorrowedRawDeserializer {
780 raw_value: Some(raw),
781 })
782 }
783
784 const should_early_return_if_failed: bool = false;
785
786 #[inline]
787 #[cold]
788 fn set_failed(&mut self, failed: &mut bool) {
789 self.delegate.set_failed(failed);
790 }
791}
792
793impl<'de, R> private::Sealed for &mut R where R: Read<'de> {}
796
797impl<'de, R> Read<'de> for &mut R
798where
799 R: Read<'de>,
800{
801 fn next(&mut self) -> Result<Option<u8>> {
802 R::next(self)
803 }
804
805 fn peek(&mut self) -> Result<Option<u8>> {
806 R::peek(self)
807 }
808
809 fn discard(&mut self) {
810 R::discard(self);
811 }
812
813 fn position(&self) -> Position {
814 R::position(self)
815 }
816
817 fn peek_position(&self) -> Position {
818 R::peek_position(self)
819 }
820
821 fn byte_offset(&self) -> usize {
822 R::byte_offset(self)
823 }
824
825 fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
826 R::parse_str(self, scratch)
827 }
828
829 fn parse_str_raw<'s>(
830 &'s mut self,
831 scratch: &'s mut Vec<u8>,
832 ) -> Result<Reference<'de, 's, [u8]>> {
833 R::parse_str_raw(self, scratch)
834 }
835
836 fn ignore_str(&mut self) -> Result<()> {
837 R::ignore_str(self)
838 }
839
840 fn decode_hex_escape(&mut self) -> Result<u16> {
841 R::decode_hex_escape(self)
842 }
843
844 #[cfg(feature = "raw_value")]
845 fn begin_raw_buffering(&mut self) {
846 R::begin_raw_buffering(self);
847 }
848
849 #[cfg(feature = "raw_value")]
850 fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
851 where
852 V: Visitor<'de>,
853 {
854 R::end_raw_buffering(self, visitor)
855 }
856
857 const should_early_return_if_failed: bool = R::should_early_return_if_failed;
858
859 fn set_failed(&mut self, failed: &mut bool) {
860 R::set_failed(self, failed);
861 }
862}
863
864pub trait Fused: private::Sealed {}
868impl<'a> Fused for SliceRead<'a> {}
869impl<'a> Fused for StrRead<'a> {}
870
871fn is_escape(ch: u8, including_control_characters: bool) -> bool {
872 ch == b'"' || ch == b'\\' || (including_control_characters && ch < 0x20)
873}
874
875fn next_or_eof<'de, R>(read: &mut R) -> Result<u8>
876where
877 R: ?Sized + Read<'de>,
878{
879 match tri!(read.next()) {
880 Some(b) => Ok(b),
881 None => error(read, ErrorCode::EofWhileParsingString),
882 }
883}
884
885fn peek_or_eof<'de, R>(read: &mut R) -> Result<u8>
886where
887 R: ?Sized + Read<'de>,
888{
889 match tri!(read.peek()) {
890 Some(b) => Ok(b),
891 None => error(read, ErrorCode::EofWhileParsingString),
892 }
893}
894
895fn error<'de, R, T>(read: &R, reason: ErrorCode) -> Result<T>
896where
897 R: ?Sized + Read<'de>,
898{
899 let position = read.position();
900 Err(Error::syntax(reason, position.line, position.column))
901}
902
903fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> {
904 match str::from_utf8(slice) {
905 Ok(s) => Ok(s),
906 Err(err) => {
907 let position = read.position();
912 Err(Error::syntax(
913 ErrorCode::InvalidUnicodeCodePoint,
914 position.line,
915 position
916 .column
917 .saturating_sub(slice.len() - err.valid_up_to()),
918 ))
919 }
920 }
921}
922
923fn parse_escape<'de, R: Read<'de>>(
926 read: &mut R,
927 validate: bool,
928 scratch: &mut Vec<u8>,
929) -> Result<()> {
930 let ch = tri!(next_or_eof(read));
931
932 match ch {
933 b'"' => scratch.push(b'"'),
934 b'\\' => scratch.push(b'\\'),
935 b'/' => scratch.push(b'/'),
936 b'b' => scratch.push(b'\x08'),
937 b'f' => scratch.push(b'\x0c'),
938 b'n' => scratch.push(b'\n'),
939 b'r' => scratch.push(b'\r'),
940 b't' => scratch.push(b'\t'),
941 b'u' => return parse_unicode_escape(read, validate, scratch),
942 _ => return error(read, ErrorCode::InvalidEscape),
943 }
944
945 Ok(())
946}
947
948#[cold]
951fn parse_unicode_escape<'de, R: Read<'de>>(
952 read: &mut R,
953 validate: bool,
954 scratch: &mut Vec<u8>,
955) -> Result<()> {
956 let mut n = tri!(read.decode_hex_escape());
957
958 if validate && n >= 0xDC00 && n <= 0xDFFF {
963 return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
965 }
966
967 loop {
968 if n < 0xD800 || n > 0xDBFF {
969 push_wtf8_codepoint(n as u32, scratch);
972 return Ok(());
973 }
974
975 let n1 = n;
977
978 if tri!(peek_or_eof(read)) == b'\\' {
979 read.discard();
980 } else {
981 return if validate {
982 read.discard();
983 error(read, ErrorCode::UnexpectedEndOfHexEscape)
984 } else {
985 push_wtf8_codepoint(n1 as u32, scratch);
986 Ok(())
987 };
988 }
989
990 if tri!(peek_or_eof(read)) == b'u' {
991 read.discard();
992 } else {
993 return if validate {
994 read.discard();
995 error(read, ErrorCode::UnexpectedEndOfHexEscape)
996 } else {
997 push_wtf8_codepoint(n1 as u32, scratch);
998 parse_escape(read, validate, scratch)
1003 };
1004 }
1005
1006 let n2 = tri!(read.decode_hex_escape());
1007
1008 if n2 < 0xDC00 || n2 > 0xDFFF {
1009 if validate {
1010 return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
1011 }
1012 push_wtf8_codepoint(n1 as u32, scratch);
1013 n = n2;
1015 continue;
1016 }
1017
1018 let n = ((((n1 - 0xD800) as u32) << 10) | (n2 - 0xDC00) as u32) + 0x1_0000;
1021 push_wtf8_codepoint(n, scratch);
1022 return Ok(());
1023 }
1024}
1025
1026#[inline]
1029fn push_wtf8_codepoint(n: u32, scratch: &mut Vec<u8>) {
1030 if n < 0x80 {
1031 scratch.push(n as u8);
1032 return;
1033 }
1034
1035 scratch.reserve(4);
1036
1037 unsafe {
1043 let ptr = scratch.as_mut_ptr().add(scratch.len());
1044
1045 let encoded_len = match n {
1046 0..=0x7F => unreachable!(),
1047 0x80..=0x7FF => {
1048 ptr.write(((n >> 6) & 0b0001_1111) as u8 | 0b1100_0000);
1049 2
1050 }
1051 0x800..=0xFFFF => {
1052 ptr.write(((n >> 12) & 0b0000_1111) as u8 | 0b1110_0000);
1053 ptr.add(1)
1054 .write(((n >> 6) & 0b0011_1111) as u8 | 0b1000_0000);
1055 3
1056 }
1057 0x1_0000..=0x10_FFFF => {
1058 ptr.write(((n >> 18) & 0b0000_0111) as u8 | 0b1111_0000);
1059 ptr.add(1)
1060 .write(((n >> 12) & 0b0011_1111) as u8 | 0b1000_0000);
1061 ptr.add(2)
1062 .write(((n >> 6) & 0b0011_1111) as u8 | 0b1000_0000);
1063 4
1064 }
1065 0x11_0000.. => unreachable!(),
1066 };
1067 ptr.add(encoded_len - 1)
1068 .write((n & 0b0011_1111) as u8 | 0b1000_0000);
1069
1070 scratch.set_len(scratch.len() + encoded_len);
1071 }
1072}
1073
1074fn ignore_escape<'de, R>(read: &mut R) -> Result<()>
1077where
1078 R: ?Sized + Read<'de>,
1079{
1080 let ch = tri!(next_or_eof(read));
1081
1082 match ch {
1083 b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
1084 b'u' => {
1085 tri!(read.decode_hex_escape());
1092 }
1093 _ => {
1094 return error(read, ErrorCode::InvalidEscape);
1095 }
1096 }
1097
1098 Ok(())
1099}
1100
1101const fn decode_hex_val_slow(val: u8) -> Option<u8> {
1102 match val {
1103 b'0'..=b'9' => Some(val - b'0'),
1104 b'A'..=b'F' => Some(val - b'A' + 10),
1105 b'a'..=b'f' => Some(val - b'a' + 10),
1106 _ => None,
1107 }
1108}
1109
1110const fn build_hex_table(shift: usize) -> [i16; 256] {
1111 let mut table = [0; 256];
1112 let mut ch = 0;
1113 while ch < 256 {
1114 table[ch] = match decode_hex_val_slow(ch as u8) {
1115 Some(val) => (val as i16) << shift,
1116 None => -1,
1117 };
1118 ch += 1;
1119 }
1120 table
1121}
1122
1123static HEX0: [i16; 256] = build_hex_table(0);
1124static HEX1: [i16; 256] = build_hex_table(4);
1125
1126fn decode_four_hex_digits(a: u8, b: u8, c: u8, d: u8) -> Option<u16> {
1127 let a = HEX1[a as usize] as i32;
1128 let b = HEX0[b as usize] as i32;
1129 let c = HEX1[c as usize] as i32;
1130 let d = HEX0[d as usize] as i32;
1131
1132 let codepoint = ((a | b) << 8) | c | d;
1133
1134 if codepoint >= 0 {
1136 Some(codepoint as u16)
1137 } else {
1138 None
1139 }
1140}