scanner_rust/scanner_ascii.rs
1use std::{
2 char::REPLACEMENT_CHARACTER,
3 fs::File,
4 io::Read,
5 path::Path,
6 ptr::copy,
7 str::{FromStr, from_utf8_unchecked},
8};
9
10use educe::Educe;
11
12use crate::{ScannerError, kmp::compute_lps, whitespaces::*};
13
14/// A simple text scanner which can parse primitive types and strings using ASCII.
15#[derive(Educe)]
16#[educe(Debug)]
17pub struct ScannerAscii<R: Read, const N: usize = 256> {
18 #[educe(Debug(ignore))]
19 reader: R,
20 buf: [u8; N],
21 buf_length: usize,
22 buf_offset: usize,
23 passing_byte: Option<u8>,
24}
25
26impl<R: Read> ScannerAscii<R> {
27 /// Create a scanner from a reader.
28 ///
29 /// ```rust
30 /// use std::io;
31 ///
32 /// use scanner_rust::ScannerAscii;
33 ///
34 /// let mut sc = ScannerAscii::new(io::stdin());
35 /// ```
36 #[inline]
37 pub fn new(reader: R) -> ScannerAscii<R> {
38 Self::new2(reader)
39 }
40}
41
42impl<R: Read, const N: usize> ScannerAscii<R, N> {
43 /// Create a scanner from a reader and set the buffer size via generics.
44 ///
45 /// ```rust
46 /// use std::io;
47 ///
48 /// use scanner_rust::ScannerAscii;
49 ///
50 /// let mut sc: ScannerAscii<_, 1024> = ScannerAscii::new2(io::stdin());
51 /// ```
52 #[inline]
53 pub fn new2(reader: R) -> ScannerAscii<R, N> {
54 // The buffer must be at least 4 bytes to hold a full UTF-8 character.
55 const { assert!(N >= 4, "the buffer size N must be at least 4 bytes") };
56
57 ScannerAscii {
58 reader,
59 buf: [0u8; N],
60 buf_length: 0,
61 buf_offset: 0,
62 passing_byte: None,
63 }
64 }
65}
66
67impl ScannerAscii<File> {
68 /// Create a scanner to read data from a file by its path.
69 ///
70 /// ```rust
71 /// use scanner_rust::ScannerAscii;
72 ///
73 /// let mut sc = ScannerAscii::scan_path("Cargo.toml").unwrap();
74 /// ```
75 #[inline]
76 pub fn scan_path<P: AsRef<Path>>(path: P) -> Result<ScannerAscii<File>, ScannerError> {
77 Self::scan_path2(path)
78 }
79}
80
81impl<const N: usize> ScannerAscii<File, N> {
82 /// Create a scanner to read data from a file by its path and set the buffer size via generics.
83 ///
84 /// ```rust
85 /// use scanner_rust::ScannerAscii;
86 ///
87 /// let mut sc: ScannerAscii<_, 1024> =
88 /// ScannerAscii::scan_path2("Cargo.toml").unwrap();
89 /// ```
90 #[inline]
91 pub fn scan_path2<P: AsRef<Path>>(path: P) -> Result<ScannerAscii<File, N>, ScannerError> {
92 let reader = File::open(path)?;
93
94 Ok(ScannerAscii::new2(reader))
95 }
96}
97
98impl<R: Read, const N: usize> ScannerAscii<R, N> {
99 #[inline]
100 fn buf_align_to_front_end(&mut self) {
101 unsafe {
102 copy(self.buf.as_ptr().add(self.buf_offset), self.buf.as_mut_ptr(), self.buf_length);
103 }
104
105 self.buf_offset = 0;
106 }
107
108 #[inline]
109 fn buf_left_shift(&mut self, distance: usize) {
110 debug_assert!(self.buf_length >= distance);
111
112 self.buf_offset += distance;
113
114 if self.buf_offset >= N - 4 {
115 self.buf_align_to_front_end();
116 }
117
118 self.buf_length -= distance;
119 }
120
121 /// Left shift (if necessary) the buffer to remove bytes from the start of the buffer. Typically, you should use this after `peek`ing the buffer.
122 ///
123 /// # Safety
124 ///
125 /// `number_of_bytes` must not be greater than the length of the currently buffered data (the length of the slice returned by `peek`). A larger value underflows the internal buffer length and causes out-of-bounds access afterwards.
126 #[inline]
127 pub unsafe fn remove_heading_bytes_from_buffer(&mut self, number_of_bytes: usize) {
128 self.buf_left_shift(number_of_bytes);
129 }
130
131 fn passing_read(&mut self) -> Result<bool, ScannerError> {
132 if self.buf_length == 0 {
133 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
134
135 if size == 0 {
136 return Ok(false);
137 }
138
139 self.buf_length += size;
140
141 if let Some(passing_byte) = self.passing_byte.take()
142 && self.buf[self.buf_offset] == passing_byte
143 {
144 self.buf_left_shift(1);
145
146 return if size == 1 {
147 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
148
149 if size == 0 {
150 Ok(false)
151 } else {
152 self.buf_length += size;
153
154 Ok(true)
155 }
156 } else {
157 Ok(true)
158 };
159 }
160
161 Ok(true)
162 } else {
163 Ok(true)
164 }
165 }
166}
167
168impl<R: Read, const N: usize> ScannerAscii<R, N> {
169 /// Read the next char. If the data is not a correct char, it will return a `Ok(Some(REPLACEMENT_CHARACTER))` which is �. If there is nothing to read, it will return `Ok(None)`.
170 ///
171 /// ```rust
172 /// use scanner_rust::ScannerAscii;
173 ///
174 /// let mut sc = ScannerAscii::new("5 c ab".as_bytes());
175 ///
176 /// assert_eq!(Some('5'), sc.next_char().unwrap());
177 /// assert_eq!(Some(' '), sc.next_char().unwrap());
178 /// assert_eq!(Some('c'), sc.next_char().unwrap());
179 /// assert_eq!(Some(' '), sc.next_char().unwrap());
180 /// assert_eq!(Some('a'), sc.next_char().unwrap());
181 /// assert_eq!(Some('b'), sc.next_char().unwrap());
182 /// assert_eq!(None, sc.next_char().unwrap());
183 /// ```
184 pub fn next_char(&mut self) -> Result<Option<char>, ScannerError> {
185 if !self.passing_read()? {
186 return Ok(None);
187 }
188
189 let e = self.buf[self.buf_offset];
190
191 self.buf_left_shift(1);
192
193 if e >= 128 { Ok(Some(REPLACEMENT_CHARACTER)) } else { Ok(Some(e as char)) }
194 }
195
196 /// Read the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)). If there is nothing to read, it will return `Ok(None)`.
197 ///
198 /// ```rust
199 /// use scanner_rust::ScannerAscii;
200 ///
201 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
202 ///
203 /// assert_eq!(Some("123 456".into()), sc.next_line().unwrap());
204 /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
205 /// assert_eq!(Some("".into()), sc.next_line().unwrap());
206 /// assert_eq!(Some(" ab ".into()), sc.next_line().unwrap());
207 /// ```
208 pub fn next_line(&mut self) -> Result<Option<String>, ScannerError> {
209 if !self.passing_read()? {
210 return Ok(None);
211 }
212
213 let mut temp = String::new();
214
215 loop {
216 let e = self.buf[self.buf_offset];
217
218 match e {
219 b'\n' => {
220 if self.buf_length == 1 {
221 self.passing_byte = Some(b'\r');
222 self.buf_left_shift(1);
223 } else if self.buf[self.buf_offset + 1] == b'\r' {
224 self.buf_left_shift(2);
225 } else {
226 self.buf_left_shift(1);
227 }
228
229 return Ok(Some(temp));
230 },
231 b'\r' => {
232 if self.buf_length == 1 {
233 self.passing_byte = Some(b'\n');
234 self.buf_left_shift(1);
235 } else if self.buf[self.buf_offset + 1] == b'\n' {
236 self.buf_left_shift(2);
237 } else {
238 self.buf_left_shift(1);
239 }
240
241 return Ok(Some(temp));
242 },
243 _ => (),
244 }
245
246 self.buf_left_shift(1);
247
248 if e >= 128 {
249 temp.push(REPLACEMENT_CHARACTER);
250 } else {
251 temp.push(e as char);
252 }
253
254 if self.buf_length == 0 {
255 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
256
257 if size == 0 {
258 return Ok(Some(temp));
259 }
260
261 self.buf_length += size;
262 }
263 }
264 }
265
266 /// Read the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)) without validating ASCII. If there is nothing to read, it will return `Ok(None)`.
267 ///
268 /// ```rust
269 /// use scanner_rust::ScannerAscii;
270 ///
271 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
272 ///
273 /// assert_eq!(Some("123 456".into()), sc.next_line_raw().unwrap());
274 /// assert_eq!(Some("789 ".into()), sc.next_line_raw().unwrap());
275 /// assert_eq!(Some("".into()), sc.next_line_raw().unwrap());
276 /// assert_eq!(Some(" ab ".into()), sc.next_line_raw().unwrap());
277 /// ```
278 pub fn next_line_raw(&mut self) -> Result<Option<Vec<u8>>, ScannerError> {
279 if !self.passing_read()? {
280 return Ok(None);
281 }
282
283 let mut temp = Vec::new();
284
285 loop {
286 let e = self.buf[self.buf_offset];
287
288 match e {
289 b'\n' => {
290 if self.buf_length == 1 {
291 self.passing_byte = Some(b'\r');
292 self.buf_left_shift(1);
293 } else if self.buf[self.buf_offset + 1] == b'\r' {
294 self.buf_left_shift(2);
295 } else {
296 self.buf_left_shift(1);
297 }
298
299 return Ok(Some(temp));
300 },
301 b'\r' => {
302 if self.buf_length == 1 {
303 self.passing_byte = Some(b'\n');
304 self.buf_left_shift(1);
305 } else if self.buf[self.buf_offset + 1] == b'\n' {
306 self.buf_left_shift(2);
307 } else {
308 self.buf_left_shift(1);
309 }
310
311 return Ok(Some(temp));
312 },
313 _ => (),
314 }
315
316 self.buf_left_shift(1);
317
318 temp.push(e);
319
320 if self.buf_length == 0 {
321 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
322
323 if size == 0 {
324 return Ok(Some(temp));
325 }
326
327 self.buf_length += size;
328 }
329 }
330 }
331
332 /// Drop the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)). If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length of the dropped line.
333 ///
334 /// ```rust
335 /// use scanner_rust::ScannerAscii;
336 ///
337 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
338 ///
339 /// assert_eq!(Some(7), sc.drop_next_line().unwrap());
340 /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
341 /// assert_eq!(Some(0), sc.drop_next_line().unwrap());
342 /// assert_eq!(Some(" ab ".into()), sc.next_line().unwrap());
343 /// assert_eq!(None, sc.drop_next_line().unwrap());
344 /// ```
345 pub fn drop_next_line(&mut self) -> Result<Option<usize>, ScannerError> {
346 if !self.passing_read()? {
347 return Ok(None);
348 }
349
350 let mut c = 0;
351
352 loop {
353 let e = self.buf[self.buf_offset];
354
355 match e {
356 b'\n' => {
357 if self.buf_length == 1 {
358 self.passing_byte = Some(b'\r');
359 self.buf_left_shift(1);
360 } else if self.buf[self.buf_offset + 1] == b'\r' {
361 self.buf_left_shift(2);
362 } else {
363 self.buf_left_shift(1);
364 }
365
366 return Ok(Some(c));
367 },
368 b'\r' => {
369 if self.buf_length == 1 {
370 self.passing_byte = Some(b'\n');
371 self.buf_left_shift(1);
372 } else if self.buf[self.buf_offset + 1] == b'\n' {
373 self.buf_left_shift(2);
374 } else {
375 self.buf_left_shift(1);
376 }
377
378 return Ok(Some(c));
379 },
380 _ => (),
381 }
382
383 self.buf_left_shift(1);
384
385 c += 1;
386
387 if self.buf_length == 0 {
388 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
389
390 if size == 0 {
391 return Ok(Some(c));
392 }
393
394 self.buf_length += size;
395 }
396 }
397 }
398}
399
400impl<R: Read, const N: usize> ScannerAscii<R, N> {
401 /// Skip the next whitespaces (`javaWhitespace`). If there is nothing to read, it will return `Ok(false)`.
402 ///
403 /// ```rust
404 /// use scanner_rust::ScannerAscii;
405 ///
406 /// let mut sc = ScannerAscii::new("1 2 c".as_bytes());
407 ///
408 /// assert_eq!(Some('1'), sc.next_char().unwrap());
409 /// assert_eq!(Some(' '), sc.next_char().unwrap());
410 /// assert_eq!(Some('2'), sc.next_char().unwrap());
411 /// assert_eq!(true, sc.skip_whitespaces().unwrap());
412 /// assert_eq!(Some('c'), sc.next_char().unwrap());
413 /// assert_eq!(false, sc.skip_whitespaces().unwrap());
414 /// ```
415 pub fn skip_whitespaces(&mut self) -> Result<bool, ScannerError> {
416 if !self.passing_read()? {
417 return Ok(false);
418 }
419
420 loop {
421 if !is_whitespace_1(self.buf[self.buf_offset]) {
422 break;
423 }
424
425 self.buf_left_shift(1);
426
427 if self.buf_length == 0 {
428 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
429
430 if size == 0 {
431 return Ok(true);
432 }
433
434 self.buf_length += size;
435 }
436 }
437
438 Ok(true)
439 }
440
441 /// Read the next token separated by whitespaces. If there is nothing to read, it will return `Ok(None)`.
442 ///
443 /// ```rust
444 /// use scanner_rust::ScannerAscii;
445 ///
446 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
447 ///
448 /// assert_eq!(Some("123".into()), sc.next().unwrap());
449 /// assert_eq!(Some("456".into()), sc.next().unwrap());
450 /// assert_eq!(Some("789".into()), sc.next().unwrap());
451 /// assert_eq!(Some("ab".into()), sc.next().unwrap());
452 /// assert_eq!(None, sc.next().unwrap());
453 /// ```
454 #[allow(clippy::should_implement_trait)]
455 pub fn next(&mut self) -> Result<Option<String>, ScannerError> {
456 if !self.skip_whitespaces()? {
457 return Ok(None);
458 }
459
460 if self.buf_length == 0 {
461 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
462
463 if size == 0 {
464 return Ok(None);
465 }
466
467 self.buf_length += size;
468 }
469
470 let mut temp = String::new();
471
472 loop {
473 let e = self.buf[self.buf_offset];
474
475 if is_whitespace_1(e) {
476 return Ok(Some(temp));
477 }
478
479 self.buf_left_shift(1);
480
481 if e >= 128 {
482 temp.push(REPLACEMENT_CHARACTER);
483 } else {
484 temp.push(e as char);
485 }
486
487 if self.buf_length == 0 {
488 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
489
490 if size == 0 {
491 return Ok(Some(temp));
492 }
493
494 self.buf_length += size;
495 }
496 }
497 }
498
499 /// Read the next token separated by whitespaces without validating ASCII. If there is nothing to read, it will return `Ok(None)`.
500 ///
501 /// ```rust
502 /// use scanner_rust::ScannerAscii;
503 ///
504 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
505 ///
506 /// assert_eq!(Some("123".into()), sc.next_raw().unwrap());
507 /// assert_eq!(Some("456".into()), sc.next_raw().unwrap());
508 /// assert_eq!(Some("789".into()), sc.next_raw().unwrap());
509 /// assert_eq!(Some("ab".into()), sc.next_raw().unwrap());
510 /// assert_eq!(None, sc.next_raw().unwrap());
511 /// ```
512 pub fn next_raw(&mut self) -> Result<Option<Vec<u8>>, ScannerError> {
513 if !self.skip_whitespaces()? {
514 return Ok(None);
515 }
516
517 if self.buf_length == 0 {
518 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
519
520 if size == 0 {
521 return Ok(None);
522 }
523
524 self.buf_length += size;
525 }
526
527 let mut temp = Vec::new();
528
529 loop {
530 let e = self.buf[self.buf_offset];
531
532 if is_whitespace_1(e) {
533 return Ok(Some(temp));
534 }
535
536 self.buf_left_shift(1);
537
538 temp.push(e);
539
540 if self.buf_length == 0 {
541 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
542
543 if size == 0 {
544 return Ok(Some(temp));
545 }
546
547 self.buf_length += size;
548 }
549 }
550 }
551
552 /// Drop the next token separated by whitespaces. If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length of the dropped token.
553 ///
554 /// ```rust
555 /// use scanner_rust::ScannerAscii;
556 ///
557 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
558 ///
559 /// assert_eq!(Some(3), sc.drop_next().unwrap());
560 /// assert_eq!(Some("456".into()), sc.next().unwrap());
561 /// assert_eq!(Some(3), sc.drop_next().unwrap());
562 /// assert_eq!(Some("ab".into()), sc.next().unwrap());
563 /// assert_eq!(None, sc.drop_next().unwrap());
564 /// ```
565 pub fn drop_next(&mut self) -> Result<Option<usize>, ScannerError> {
566 if !self.skip_whitespaces()? {
567 return Ok(None);
568 }
569
570 if self.buf_length == 0 {
571 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
572
573 if size == 0 {
574 return Ok(None);
575 }
576
577 self.buf_length += size;
578 }
579
580 let mut c = 0;
581
582 loop {
583 if is_whitespace_1(self.buf[self.buf_offset]) {
584 return Ok(Some(c));
585 }
586
587 self.buf_left_shift(1);
588
589 c += 1;
590
591 if self.buf_length == 0 {
592 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
593
594 if size == 0 {
595 return Ok(Some(c));
596 }
597
598 self.buf_length += size;
599 }
600 }
601 }
602}
603
604impl<R: Read, const N: usize> ScannerAscii<R, N> {
605 /// Read the next bytes. If there is nothing to read, it will return `Ok(None)`.
606 ///
607 /// ```rust
608 /// use scanner_rust::ScannerAscii;
609 ///
610 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
611 ///
612 /// assert_eq!(Some("123".into()), sc.next_bytes(3).unwrap());
613 /// assert_eq!(Some(" 456".into()), sc.next_bytes(4).unwrap());
614 /// assert_eq!(Some("\r\n789 ".into()), sc.next_bytes(6).unwrap());
615 /// assert_eq!(Some("ab".into()), sc.next_raw().unwrap());
616 /// assert_eq!(Some(" ".into()), sc.next_bytes(2).unwrap());
617 /// assert_eq!(None, sc.next_bytes(2).unwrap());
618 /// ```
619 pub fn next_bytes(
620 &mut self,
621 max_number_of_bytes: usize,
622 ) -> Result<Option<Vec<u8>>, ScannerError> {
623 if !self.passing_read()? {
624 return Ok(None);
625 }
626
627 let mut temp = Vec::new();
628 let mut c = 0;
629
630 while c < max_number_of_bytes {
631 if self.buf_length == 0 {
632 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
633
634 if size == 0 {
635 return Ok(Some(temp));
636 }
637
638 self.buf_length += size;
639 }
640
641 let dropping_bytes = self.buf_length.min(max_number_of_bytes - c);
642
643 temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + dropping_bytes)]);
644
645 self.buf_left_shift(dropping_bytes);
646
647 c += dropping_bytes;
648 }
649
650 Ok(Some(temp))
651 }
652
653 /// Drop the next N bytes. If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length of the actually dropped bytes.
654 ///
655 /// ```rust
656 /// use scanner_rust::ScannerAscii;
657 ///
658 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
659 ///
660 /// assert_eq!(Some(7), sc.drop_next_bytes(7).unwrap());
661 /// assert_eq!(Some("".into()), sc.next_line().unwrap());
662 /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
663 /// assert_eq!(Some(1), sc.drop_next_bytes(1).unwrap());
664 /// assert_eq!(Some(" ab ".into()), sc.next_line().unwrap());
665 /// assert_eq!(None, sc.drop_next_bytes(1).unwrap());
666 /// ```
667 pub fn drop_next_bytes(
668 &mut self,
669 max_number_of_bytes: usize,
670 ) -> Result<Option<usize>, ScannerError> {
671 if !self.passing_read()? {
672 return Ok(None);
673 }
674
675 let mut c = 0;
676
677 while c < max_number_of_bytes {
678 if self.buf_length == 0 {
679 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
680
681 if size == 0 {
682 return Ok(Some(c));
683 }
684
685 self.buf_length += size;
686 }
687
688 let dropping_bytes = self.buf_length.min(max_number_of_bytes - c);
689
690 self.buf_left_shift(dropping_bytes);
691
692 c += dropping_bytes;
693 }
694
695 Ok(Some(c))
696 }
697}
698
699impl<R: Read, const N: usize> ScannerAscii<R, N> {
700 /// Read the next text until it reaches a specific boundary. If there is nothing to read, it will return `Ok(None)`.
701 ///
702 /// ```rust
703 /// use scanner_rust::ScannerAscii;
704 ///
705 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
706 ///
707 /// assert_eq!(Some("123".into()), sc.next_until(" ").unwrap());
708 /// assert_eq!(Some("456\r".into()), sc.next_until("\n").unwrap());
709 /// assert_eq!(Some("78".into()), sc.next_until("9 ").unwrap());
710 /// assert_eq!(Some("\n\n ab ".into()), sc.next_until("kk").unwrap());
711 /// assert_eq!(None, sc.next().unwrap());
712 /// ```
713 pub fn next_until<S: AsRef<str>>(
714 &mut self,
715 boundary: S,
716 ) -> Result<Option<String>, ScannerError> {
717 let boundary = boundary.as_ref();
718
719 Ok(self
720 .next_until_raw(boundary.as_bytes())?
721 .map(|bytes| String::from_utf8_lossy(&bytes).into_owned()))
722 }
723
724 /// Read the next data until it reaches a specific boundary without validating ASCII. If there is nothing to read, it will return `Ok(None)`.
725 ///
726 /// ```rust
727 /// use scanner_rust::ScannerAscii;
728 ///
729 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
730 ///
731 /// assert_eq!(Some("123".into()), sc.next_until_raw(" ").unwrap());
732 /// assert_eq!(Some("456\r".into()), sc.next_until_raw("\n").unwrap());
733 /// assert_eq!(Some("78".into()), sc.next_until_raw("9 ").unwrap());
734 /// assert_eq!(Some("\n\n ab ".into()), sc.next_until_raw("kk").unwrap());
735 /// assert_eq!(None, sc.next().unwrap());
736 /// ```
737 pub fn next_until_raw<D: ?Sized + AsRef<[u8]>>(
738 &mut self,
739 boundary: &D,
740 ) -> Result<Option<Vec<u8>>, ScannerError> {
741 if !self.passing_read()? {
742 return Ok(None);
743 }
744
745 let boundary = boundary.as_ref();
746 let boundary_length = boundary.len();
747 let mut temp = Vec::new();
748
749 // An empty boundary never matches, so keep reading until the end.
750 if boundary_length == 0 {
751 loop {
752 temp.extend_from_slice(
753 &self.buf[self.buf_offset..(self.buf_offset + self.buf_length)],
754 );
755
756 self.buf_left_shift(self.buf_length);
757
758 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
759
760 if size == 0 {
761 return Ok(Some(temp));
762 }
763
764 self.buf_length += size;
765 }
766 }
767
768 // Match the boundary across buffer refills with KMP so a mismatch never re-reads bytes.
769 let lps = compute_lps(boundary);
770 let mut b = 0;
771
772 loop {
773 let mut i = 0;
774
775 while i < self.buf_length {
776 let e = self.buf[self.buf_offset + i];
777
778 while b > 0 && e != boundary[b] {
779 b = lps[b - 1];
780 }
781
782 if e == boundary[b] {
783 b += 1;
784 }
785
786 i += 1;
787
788 if b == boundary_length {
789 // The matched boundary is the last `boundary_length` bytes seen so far.
790 temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + i)]);
791 temp.truncate(temp.len() - boundary_length);
792
793 self.buf_left_shift(i);
794
795 return Ok(Some(temp));
796 }
797 }
798
799 temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + self.buf_length)]);
800
801 self.buf_left_shift(self.buf_length);
802
803 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
804
805 if size == 0 {
806 return Ok(Some(temp));
807 }
808
809 self.buf_length += size;
810 }
811 }
812
813 /// Drop the next data until it reaches a specific boundary. If there is nothing to read, it will return `Ok(None)`.
814 ///
815 /// ```rust
816 /// use scanner_rust::ScannerAscii;
817 ///
818 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
819 ///
820 /// assert_eq!(Some(7), sc.drop_next_until("\r\n").unwrap());
821 /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
822 /// assert_eq!(Some(0), sc.drop_next_until("\n").unwrap());
823 /// assert_eq!(Some(" ab ".into()), sc.next_line().unwrap());
824 /// assert_eq!(None, sc.drop_next_until("").unwrap());
825 /// ```
826 pub fn drop_next_until<D: ?Sized + AsRef<[u8]>>(
827 &mut self,
828 boundary: &D,
829 ) -> Result<Option<usize>, ScannerError> {
830 if !self.passing_read()? {
831 return Ok(None);
832 }
833
834 let boundary = boundary.as_ref();
835 let boundary_length = boundary.len();
836 let mut c = 0;
837
838 // An empty boundary never matches, so keep reading until the end.
839 if boundary_length == 0 {
840 loop {
841 c += self.buf_length;
842
843 self.buf_left_shift(self.buf_length);
844
845 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
846
847 if size == 0 {
848 return Ok(Some(c));
849 }
850
851 self.buf_length += size;
852 }
853 }
854
855 // Match the boundary across buffer refills with KMP so a mismatch never re-reads bytes.
856 let lps = compute_lps(boundary);
857 let mut b = 0;
858
859 loop {
860 let mut i = 0;
861
862 while i < self.buf_length {
863 let e = self.buf[self.buf_offset + i];
864
865 while b > 0 && e != boundary[b] {
866 b = lps[b - 1];
867 }
868
869 if e == boundary[b] {
870 b += 1;
871 }
872
873 i += 1;
874
875 if b == boundary_length {
876 self.buf_left_shift(i);
877
878 return Ok(Some(c + i - boundary_length));
879 }
880 }
881
882 c += self.buf_length;
883
884 self.buf_left_shift(self.buf_length);
885
886 let size = self.reader.read(&mut self.buf[self.buf_offset..])?;
887
888 if size == 0 {
889 return Ok(Some(c));
890 }
891
892 self.buf_length += size;
893 }
894 }
895}
896
897impl<R: Read, const N: usize> ScannerAscii<R, N> {
898 /// Fill up the buffer as much as possible and return an immutable slice of all the currently buffered (unread) data.
899 /// Reading stops at the end of the stream or when the buffer is full. If `shift` is `true`, the buffered data is first moved to the front of the buffer so that up to the whole buffer size can be filled; if `false`, only the space after the current read position is filled.
900 ///
901 /// ```rust
902 /// use scanner_rust::ScannerAscii;
903 ///
904 /// let mut sc = ScannerAscii::new("123 456\r\n789 \n\n ab ".as_bytes());
905 ///
906 /// assert_eq!("123 456\r\n789 \n\n ab ".as_bytes(), sc.peek(false).unwrap());
907 /// ```
908 #[inline]
909 pub fn peek(&mut self, shift: bool) -> Result<&[u8], ScannerError> {
910 // Consume any line-terminator byte deferred by a previous read so it is not peeked again.
911 self.passing_read()?;
912
913 if shift {
914 self.buf_align_to_front_end();
915 }
916
917 loop {
918 let size = self.reader.read(&mut self.buf[(self.buf_offset + self.buf_length)..])?;
919
920 if size == 0 {
921 break;
922 }
923
924 self.buf_length += size;
925 }
926
927 Ok(&self.buf[self.buf_offset..(self.buf_offset + self.buf_length)])
928 }
929}
930
931impl<R: Read, const N: usize> ScannerAscii<R, N> {
932 #[inline]
933 fn next_raw_parse<T: FromStr>(&mut self) -> Result<Option<T>, ScannerError>
934 where
935 ScannerError: From<<T as FromStr>::Err>, {
936 let result = self.next_raw()?;
937
938 match result {
939 // SAFETY: for malformed input `s` may not be valid UTF-8 (technically UB to treat as a `&str`), but it is only fed to a primitive `FromStr` that reads it as bytes, so an invalid token merely fails to parse; validation is skipped for speed.
940 Some(s) => Ok(Some(unsafe { from_utf8_unchecked(&s) }.parse()?)),
941 None => Ok(None),
942 }
943 }
944}
945
946impl<R: Read, const N: usize> ScannerAscii<R, N> {
947 #[inline]
948 fn next_until_raw_parse<T: FromStr, D: ?Sized + AsRef<[u8]>>(
949 &mut self,
950 boundary: &D,
951 ) -> Result<Option<T>, ScannerError>
952 where
953 ScannerError: From<<T as FromStr>::Err>, {
954 let result = self.next_until_raw(boundary)?;
955
956 match result {
957 // SAFETY: for malformed input `s` may not be valid UTF-8 (technically UB to treat as a `&str`), but it is only fed to a primitive `FromStr` that reads it as bytes, so an invalid token merely fails to parse; validation is skipped for speed.
958 Some(s) => Ok(Some(unsafe { from_utf8_unchecked(&s) }.parse()?)),
959 None => Ok(None),
960 }
961 }
962}
963
964macro_rules! scanner_ascii_number_methods {
965 ($(($t:ty, $next:ident, $next_until:ident, $sample:literal, $v1:literal, $v2:literal)),+ $(,)?) => {
966 impl<R: Read, const N: usize> ScannerAscii<R, N> {
967 $(
968 #[doc = concat!(
969 "Read the next token separated by whitespaces and parse it to a `", stringify!($t), "` value. If there is nothing to read, it will return `Ok(None)`.\n\n```rust\nuse scanner_rust::ScannerAscii;\n\nlet mut sc = ScannerAscii::new(", stringify!($sample), ".as_bytes());\n\nassert_eq!(Some(", stringify!($v1), "), sc.", stringify!($next), "().unwrap());\nassert_eq!(Some(", stringify!($v2), "), sc.", stringify!($next), "().unwrap());\n```"
970 )]
971 #[inline]
972 pub fn $next(&mut self) -> Result<Option<$t>, ScannerError> {
973 self.next_raw_parse()
974 }
975 )+
976 }
977
978 impl<R: Read, const N: usize> ScannerAscii<R, N> {
979 $(
980 #[doc = concat!(
981 "Read the next text until it reaches a specific boundary and parse it to a `", stringify!($t), "` value. If there is nothing to read, it will return `Ok(None)`.\n\n```rust\nuse scanner_rust::ScannerAscii;\n\nlet mut sc = ScannerAscii::new(", stringify!($sample), ".as_bytes());\n\nassert_eq!(Some(", stringify!($v1), "), sc.", stringify!($next_until), "(\" \").unwrap());\nassert_eq!(Some(", stringify!($v2), "), sc.", stringify!($next_until), "(\" \").unwrap());\n```"
982 )]
983 #[inline]
984 pub fn $next_until<D: ?Sized + AsRef<[u8]>>(
985 &mut self,
986 boundary: &D,
987 ) -> Result<Option<$t>, ScannerError> {
988 self.next_until_raw_parse(boundary)
989 }
990 )+
991 }
992 };
993}
994
995scanner_ascii_number_methods! {
996 (u8, next_u8, next_u8_until, "1 2", 1, 2),
997 (u16, next_u16, next_u16_until, "1 2", 1, 2),
998 (u32, next_u32, next_u32_until, "1 2", 1, 2),
999 (u64, next_u64, next_u64_until, "1 2", 1, 2),
1000 (u128, next_u128, next_u128_until, "1 2", 1, 2),
1001 (usize, next_usize, next_usize_until, "1 2", 1, 2),
1002 (i8, next_i8, next_i8_until, "1 2", 1, 2),
1003 (i16, next_i16, next_i16_until, "1 2", 1, 2),
1004 (i32, next_i32, next_i32_until, "1 2", 1, 2),
1005 (i64, next_i64, next_i64_until, "1 2", 1, 2),
1006 (i128, next_i128, next_i128_until, "1 2", 1, 2),
1007 (isize, next_isize, next_isize_until, "1 2", 1, 2),
1008 (f32, next_f32, next_f32_until, "1 2.5", 1.0, 2.5),
1009 (f64, next_f64, next_f64_until, "1 2.5", 1.0, 2.5),
1010}