1use embedded_io::{Error as _, Read, Write};
2
3use crate::buffer::Buffer;
4use crate::buffer::ChangeFlag;
5use crate::error::{can_retry_if_partial, Error as RJiterError, ErrorType, Result as RJiterResult};
6use crate::jiter::{
7 Jiter, JiterResult, JsonErrorType, JsonValue, LinePosition, NumberAny, NumberInt, Peek,
8};
9
10pub struct RJiter<'rj, R: Read> {
12 jiter: Jiter<'rj>,
13 buffer: Buffer<'rj, R>,
14}
15
16impl<R: Read> core::fmt::Debug for RJiter<'_, R> {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 write!(
19 f,
20 "RJiter {{ jiter: {:?}, buffer: {:?} }}",
21 self.jiter, self.buffer
22 )
23 }
24}
25
26impl<'rj, R: Read> RJiter<'rj, R> {
27 pub fn new(reader: &'rj mut R, buf: &'rj mut [u8]) -> Self {
33 #[allow(unsafe_code)]
34 let buf_alias = unsafe {
35 #[allow(mutable_transmutes)]
36 #[allow(clippy::transmute_ptr_to_ptr)]
37 core::mem::transmute::<&[u8], &'rj mut [u8]>(buf)
38 };
39 let buffer = Buffer::new(reader, buf_alias);
40 #[allow(clippy::indexing_slicing)]
42 let jiter = Jiter::new(&buf[..buffer.n_bytes]);
43
44 RJiter { jiter, buffer }
45 }
46
47 fn create_new_jiter(&mut self) {
48 #[allow(clippy::indexing_slicing)]
50 let jiter_buffer_2 = &self.buffer.buf[..self.buffer.n_bytes];
51 #[allow(unsafe_code)]
52 let jiter_buffer = unsafe { core::mem::transmute::<&[u8], &'rj [u8]>(jiter_buffer_2) };
53 self.jiter = Jiter::new(jiter_buffer);
54 }
55
56 pub fn peek(&mut self) -> RJiterResult<Peek> {
64 self.loop_until_success(jiter::Jiter::peek, None, false)
65 }
66
67 pub fn known_array(&mut self) -> RJiterResult<Option<Peek>> {
71 self.loop_until_success(jiter::Jiter::known_array, Some(b'['), false)
72 }
73
74 pub fn known_bool(&mut self, peek: Peek) -> RJiterResult<bool> {
78 self.loop_until_success(|j| j.known_bool(peek), None, false)
79 }
80
81 pub fn known_bytes(&mut self) -> RJiterResult<&[u8]> {
85 #[allow(unsafe_code)]
86 let f = |j: &mut Jiter<'rj>| unsafe {
87 core::mem::transmute::<JiterResult<&[u8]>, JiterResult<&'rj [u8]>>(j.known_bytes())
88 };
89 self.loop_until_success(f, None, false)
90 }
91
92 pub fn known_float(&mut self, peek: Peek) -> RJiterResult<f64> {
96 self.loop_until_success(|j| j.known_float(peek), None, true)
97 }
98
99 pub fn known_int(&mut self, peek: Peek) -> RJiterResult<NumberInt> {
103 self.loop_until_success(|j| j.known_int(peek), None, true)
104 }
105
106 pub fn known_null(&mut self) -> RJiterResult<()> {
110 self.loop_until_success(jiter::Jiter::known_null, None, false)
111 }
112
113 pub fn known_number(&mut self, peek: Peek) -> RJiterResult<NumberAny> {
117 self.loop_until_success(|j| j.known_number(peek), None, true)
118 }
119
120 pub fn known_object(&mut self) -> RJiterResult<Option<&str>> {
124 #[allow(unsafe_code)]
125 let f = |j: &mut Jiter<'rj>| unsafe {
126 core::mem::transmute::<JiterResult<Option<&str>>, JiterResult<Option<&'rj str>>>(
127 j.known_object(),
128 )
129 };
130 self.loop_until_success(f, Some(b'{'), false)
131 }
132
133 pub fn known_skip(&mut self, peek: Peek) -> RJiterResult<()> {
137 self.loop_until_success(|j| j.known_skip(peek), None, true)
138 }
139
140 pub fn known_str(&mut self) -> RJiterResult<&str> {
144 #[allow(unsafe_code)]
145 let f = |j: &mut Jiter<'rj>| unsafe {
146 core::mem::transmute::<JiterResult<&str>, JiterResult<&'rj str>>(j.known_str())
147 };
148 self.loop_until_success(f, None, false)
149 }
150
151 pub fn known_value(&mut self, peek: Peek) -> RJiterResult<JsonValue<'rj>> {
155 self.loop_until_success(|j| j.known_value(peek), None, true)
156 }
157
158 pub fn known_value_owned(&mut self, peek: Peek) -> RJiterResult<JsonValue<'static>> {
162 self.loop_until_success(|j| j.known_value_owned(peek), None, true)
163 }
164
165 pub fn next_array(&mut self) -> RJiterResult<Option<Peek>> {
169 self.loop_until_success(jiter::Jiter::next_array, Some(b'['), false)
170 }
171
172 pub fn array_step(&mut self) -> RJiterResult<Option<Peek>> {
176 self.loop_until_success(jiter::Jiter::array_step, Some(b','), false)
177 }
178
179 pub fn next_bool(&mut self) -> RJiterResult<bool> {
183 self.loop_until_success(jiter::Jiter::next_bool, None, false)
184 }
185
186 pub fn next_bytes(&mut self) -> RJiterResult<&[u8]> {
190 #[allow(unsafe_code)]
191 let f = |j: &mut Jiter<'rj>| unsafe {
192 core::mem::transmute::<JiterResult<&[u8]>, JiterResult<&'rj [u8]>>(j.next_bytes())
193 };
194 self.loop_until_success(f, None, false)
195 }
196
197 pub fn next_float(&mut self) -> RJiterResult<f64> {
201 self.loop_until_success(jiter::Jiter::next_float, None, true)
202 }
203
204 pub fn next_int(&mut self) -> RJiterResult<NumberInt> {
208 self.loop_until_success(jiter::Jiter::next_int, None, true)
209 }
210
211 pub fn next_key(&mut self) -> RJiterResult<Option<&str>> {
215 #[allow(unsafe_code)]
216 let f = |j: &mut Jiter<'rj>| unsafe {
217 core::mem::transmute::<JiterResult<Option<&str>>, JiterResult<Option<&'rj str>>>(
218 j.next_key(),
219 )
220 };
221 self.loop_until_success(f, Some(b','), false)
222 }
223
224 pub fn next_key_bytes(&mut self) -> RJiterResult<Option<&[u8]>> {
228 #[allow(unsafe_code)]
229 let f = |j: &mut Jiter<'rj>| unsafe {
230 core::mem::transmute::<JiterResult<Option<&[u8]>>, JiterResult<Option<&'rj [u8]>>>(
231 j.next_key_bytes(),
232 )
233 };
234 self.loop_until_success(f, Some(b','), false)
235 }
236
237 pub fn next_null(&mut self) -> RJiterResult<()> {
241 self.loop_until_success(jiter::Jiter::next_null, None, false)
242 }
243
244 pub fn next_number(&mut self) -> RJiterResult<NumberAny> {
248 self.loop_until_success(jiter::Jiter::next_number, None, true)
249 }
250
251 pub fn next_number_bytes(&mut self) -> RJiterResult<&[u8]> {
255 #[allow(unsafe_code)]
256 let f = |j: &mut Jiter<'rj>| unsafe {
257 core::mem::transmute::<JiterResult<&[u8]>, JiterResult<&'rj [u8]>>(
258 j.next_number_bytes(),
259 )
260 };
261 self.loop_until_success(f, None, true)
262 }
263
264 pub fn next_object(&mut self) -> RJiterResult<Option<&str>> {
268 #[allow(unsafe_code)]
269 let f = |j: &mut Jiter<'rj>| unsafe {
270 core::mem::transmute::<JiterResult<Option<&str>>, JiterResult<Option<&'rj str>>>(
271 j.next_object(),
272 )
273 };
274 self.loop_until_success(f, Some(b'{'), false)
275 }
276
277 pub fn next_object_bytes(&mut self) -> RJiterResult<Option<&[u8]>> {
281 #[allow(unsafe_code)]
282 let f = |j: &mut Jiter<'rj>| unsafe {
283 core::mem::transmute::<JiterResult<Option<&[u8]>>, JiterResult<Option<&'rj [u8]>>>(
284 j.next_object_bytes(),
285 )
286 };
287 self.loop_until_success(f, Some(b'{'), false)
288 }
289
290 pub fn next_skip(&mut self) -> RJiterResult<()> {
294 self.loop_until_success(jiter::Jiter::next_skip, None, true)
295 }
296
297 pub fn next_str(&mut self) -> RJiterResult<&str> {
301 #[allow(unsafe_code)]
302 let f = |j: &mut Jiter<'rj>| unsafe {
303 core::mem::transmute::<JiterResult<&str>, JiterResult<&'rj str>>(j.next_str())
304 };
305 self.loop_until_success(f, None, false)
306 }
307
308 pub fn next_value(&mut self) -> RJiterResult<JsonValue<'rj>> {
312 self.loop_until_success(jiter::Jiter::next_value, None, true)
313 }
314
315 pub fn next_value_owned(&mut self) -> RJiterResult<JsonValue<'static>> {
319 self.loop_until_success(jiter::Jiter::next_value_owned, None, true)
320 }
321
322 fn loop_until_success<T, F>(
327 &mut self,
328 mut f: F,
329 skip_spaces_token: Option<u8>,
330 should_eager_consume: bool,
331 ) -> RJiterResult<T>
332 where
333 F: FnMut(&mut Jiter<'rj>) -> JiterResult<T>,
334 T: core::fmt::Debug,
335 {
336 fn downgrade_ok_if_eof<T>(
340 result: &JiterResult<T>,
341 should_eager_consume: bool,
342 jiter: &Jiter,
343 n_bytes: usize,
344 ) -> bool {
345 if !result.is_ok() {
346 return false;
347 }
348 if !should_eager_consume {
349 return true;
350 }
351 if jiter.current_index() < n_bytes {
352 return true;
353 }
354 false
355 }
356 let jiter_pos = self.jiter.current_index();
357
358 let result = f(&mut self.jiter);
359 let is_ok = downgrade_ok_if_eof(
360 &result,
361 should_eager_consume,
362 &self.jiter,
363 self.buffer.n_bytes,
364 );
365 if is_ok {
366 if let Ok(value) = result {
368 return Ok(value);
369 }
370 }
371
372 self.skip_spaces_feeding(jiter_pos, skip_spaces_token)?;
373
374 loop {
375 let result = f(&mut self.jiter);
376
377 if let Err(e) = &result {
378 if !can_retry_if_partial(e) {
379 return Err(RJiterError::from_jiter_error(
380 self.current_index(),
381 e.clone(),
382 ));
383 }
384 }
385
386 if result.is_ok() {
387 let really_ok = downgrade_ok_if_eof(
388 &result,
389 should_eager_consume,
390 &self.jiter,
391 self.buffer.n_bytes,
392 );
393 if really_ok {
394 if let Ok(value) = result {
396 return Ok(value);
397 }
398 }
399 }
400
401 let n_read = self.buffer.read_more();
402 match n_read {
403 Err(e) => return Err(e),
404 Ok(0) => {
405 return result
407 .map_err(|e| RJiterError::from_jiter_error(self.current_index(), e));
408 }
409 Ok(_) => {
410 self.create_new_jiter();
411 }
412 }
413 }
414 }
415
416 fn skip_spaces_feeding(
420 &mut self,
421 jiter_pos: usize,
422 transparent_token: Option<u8>,
423 ) -> RJiterResult<()> {
424 let to_pos = 0;
425 let change_flag = ChangeFlag::new(&self.buffer);
426
427 if jiter_pos > to_pos {
428 self.buffer.shift_buffer(to_pos, jiter_pos);
429 }
430 self.buffer.skip_spaces(to_pos)?;
431 if let Some(transparent_token) = transparent_token {
432 if to_pos >= self.buffer.n_bytes {
433 self.buffer.read_more()?;
434 }
435 #[allow(clippy::indexing_slicing)]
437 if to_pos < self.buffer.n_bytes && self.buffer.buf[to_pos] == transparent_token {
438 self.buffer.skip_spaces(to_pos + 1)?;
439 }
440 }
441
442 if change_flag.is_changed(&self.buffer) {
443 self.create_new_jiter();
444 }
445 Ok(())
446 }
447
448 pub fn finish(&mut self) -> RJiterResult<()> {
452 loop {
453 let finish_in_this_buf = self.jiter.finish();
454 if let Err(e) = finish_in_this_buf {
457 return Err(RJiterError::from_jiter_error(self.current_index(), e));
458 }
459 if self.jiter.current_index() < self.buffer.buf.len() {
461 let n_new_bytes = self.buffer.read_more()?;
462 if n_new_bytes == 0 {
464 return Ok(());
465 }
466 }
467 self.buffer.shift_buffer(0, self.jiter.current_index());
468 self.create_new_jiter();
469 }
470 }
471
472 #[must_use]
476 pub fn current_index(&self) -> usize {
477 self.jiter.current_index() + self.buffer.n_shifted_out
478 }
479
480 #[must_use]
482 pub fn error_position(&self, index: usize) -> LinePosition {
483 let index = index - self.buffer.n_shifted_out;
484 let pos = self.jiter.error_position(index);
485 LinePosition::new(
486 pos.line + self.buffer.pos_shifted.line,
487 pos.column + self.buffer.pos_shifted.column,
488 )
489 }
490
491 fn handle_long<F, T, W: Write>(
501 &mut self,
502 parser: F,
503 writer: &mut W,
504 write_completed: impl Fn(T, usize, &mut W) -> RJiterResult<()>,
505 write_segment: impl Fn(&mut [u8], usize, usize, &mut W) -> RJiterResult<()>,
506 ) -> RJiterResult<()>
507 where
508 F: Fn(&mut Jiter<'rj>) -> JiterResult<T>,
509 T: core::fmt::Debug,
510 {
511 loop {
512 let result = parser(&mut self.jiter);
516 if let Ok(value) = result {
517 write_completed(value, self.current_index(), writer)?;
518 return Ok(());
519 }
520 #[allow(clippy::unwrap_used)]
523 let err = result.unwrap_err();
524 if !can_retry_if_partial(&err) {
525 return Err(RJiterError::from_jiter_error(self.current_index(), err));
526 }
527
528 if self.jiter.current_index() > 0 {
531 self.buffer.shift_buffer(0, self.jiter.current_index());
532 self.create_new_jiter();
533 }
534
535 #[allow(clippy::indexing_slicing)]
539 let bs_pos = self.buffer.buf[..self.buffer.n_bytes]
540 .iter()
541 .position(|&b| b == b'\\');
542 let segment_end_pos = match bs_pos {
543 None => {
546 if self.buffer.n_bytes == 0 {
547 0
548 } else {
549 self.buffer.n_bytes - 1
550 }
551 }
552 Some(bs_pos) if bs_pos > 1 => bs_pos,
555 Some(bs_pos) => {
558 let buf_len = self.buffer.n_bytes;
559 if buf_len < 3 {
561 bs_pos
562 } else {
563 #[allow(clippy::indexing_slicing)]
565 let after_bs = self.buffer.buf[2];
566 if after_bs != b'u' && after_bs != b'U' {
567 bs_pos + 2
568 } else {
569 if buf_len < 7 {
571 bs_pos
572 } else {
573 bs_pos + 6
574 }
575 }
576 }
577 }
578 };
579
580 let segment_end_pos = (0..=segment_end_pos)
582 .rev()
583 .find(
584 #[allow(clippy::indexing_slicing)]
585 |&pos| is_utf8_leading_byte(self.buffer.buf[pos]),
586 )
587 .unwrap_or(0);
588
589 if segment_end_pos > 1 {
591 write_segment(
592 self.buffer.buf,
593 segment_end_pos,
594 self.current_index(),
595 writer,
596 )?;
597 self.buffer.shift_buffer(1, segment_end_pos);
598 }
599
600 let n_new_bytes = self.buffer.read_more()?;
602 match n_new_bytes {
603 0 => return Err(RJiterError::from_jiter_error(self.current_index(), err)),
604 1.. => self.create_new_jiter(),
605 }
606 }
607 }
608
609 pub fn write_long_bytes<W: Write>(&mut self, writer: &mut W) -> RJiterResult<()> {
619 fn write_completed<W: Write>(
620 bytes: &[u8],
621 index: usize,
622 writer: &mut W,
623 ) -> RJiterResult<()> {
624 writer.write_all(bytes).map_err(|e| RJiterError {
625 error_type: ErrorType::IoError { kind: e.kind() },
626 index,
627 })
628 }
629 fn write_segment<W: Write>(
630 bytes: &mut [u8],
631 end_pos: usize,
632 index: usize,
633 writer: &mut W,
634 ) -> RJiterResult<()> {
635 #[allow(clippy::indexing_slicing)]
637 writer
638 .write_all(&bytes[1..end_pos])
639 .map_err(|e| RJiterError {
640 error_type: ErrorType::IoError { kind: e.kind() },
641 index,
642 })
643 }
644 #[allow(unsafe_code)]
645 let parser = |j: &mut Jiter<'rj>| unsafe {
646 core::mem::transmute::<JiterResult<&[u8]>, JiterResult<&'rj [u8]>>(j.known_bytes())
647 };
648 self.handle_long(parser, writer, write_completed, write_segment)
649 }
650
651 pub fn write_long_str<W: Write>(&mut self, writer: &mut W) -> RJiterResult<()> {
660 fn write_completed<W: Write>(
661 string: &str,
662 index: usize,
663 writer: &mut W,
664 ) -> RJiterResult<()> {
665 writer
666 .write_all(string.as_bytes())
667 .map_err(|e| RJiterError {
668 error_type: ErrorType::IoError { kind: e.kind() },
669 index,
670 })
671 }
672 fn write_segment<W: Write>(
673 bytes: &mut [u8],
674 end_pos: usize,
675 index: usize,
676 writer: &mut W,
677 ) -> RJiterResult<()> {
678 #[allow(clippy::indexing_slicing)]
681 let orig_char = bytes[end_pos];
682 #[allow(clippy::indexing_slicing)]
683 {
684 bytes[end_pos] = b'"';
685 }
686 #[allow(clippy::indexing_slicing)]
687 let sub_jiter_buf = &bytes[..=end_pos];
688 #[allow(unsafe_code)]
689 let sub_jiter_buf = unsafe { core::mem::transmute::<&[u8], &[u8]>(sub_jiter_buf) };
690 let mut sub_jiter = Jiter::new(sub_jiter_buf);
691 let sub_result = sub_jiter.known_str();
692 #[allow(clippy::indexing_slicing)]
693 {
694 bytes[end_pos] = orig_char;
695 }
696
697 match sub_result {
698 Ok(string) => writer
699 .write_all(string.as_bytes())
700 .map_err(|e| RJiterError {
701 error_type: ErrorType::IoError { kind: e.kind() },
702 index,
703 }),
704 Err(e) => Err(RJiterError::from_jiter_error(index, e)),
705 }
706 }
707 #[allow(unsafe_code)]
708 let parser = |j: &mut Jiter<'rj>| unsafe {
709 core::mem::transmute::<JiterResult<&str>, JiterResult<&'rj str>>(j.known_str())
710 };
711 self.handle_long(parser, writer, write_completed, write_segment)
712 }
713
714 pub fn known_skip_token(&mut self, token: &[u8]) -> RJiterResult<()> {
724 let change_flag = ChangeFlag::new(&self.buffer);
725 let mut pos = self.jiter.current_index();
726 let mut err_flag = false;
727
728 if pos + token.len() >= self.buffer.n_bytes {
730 self.buffer.shift_buffer(0, pos);
731 pos = 0;
732 }
733 while self.buffer.n_bytes < pos + token.len() {
734 let n_new_bytes = self.buffer.read_more()?;
735 if n_new_bytes == 0 {
736 err_flag = true;
739 break;
740 }
741 }
742
743 let found = if err_flag {
745 false
746 } else {
747 #[allow(clippy::indexing_slicing)]
749 let buf_view = &mut self.buffer.buf[pos..self.buffer.n_bytes];
750 buf_view.starts_with(token)
751 };
752
753 if found {
755 self.buffer.shift_buffer(0, pos + token.len());
756 }
757 if change_flag.is_changed(&self.buffer) {
758 self.create_new_jiter();
759 }
760
761 if found {
763 return Ok(());
764 }
765 Err(RJiterError::from_json_error(
766 self.current_index(),
767 JsonErrorType::ExpectedSomeIdent,
768 ))
769 }
770}
771
772fn is_utf8_leading_byte(b: u8) -> bool {
773 #[allow(clippy::manual_range_contains)]
776 let flag = (b < 0b1000_0000) || (b >= 0b1100_0000);
777 flag
778}