1#![deny(clippy::correctness, unsafe_code)]
51#![warn(
52 clippy::perf,
53 clippy::complexity,
54 clippy::style,
55 clippy::nursery,
56 clippy::pedantic,
57 clippy::clone_on_ref_ptr,
58 clippy::decimal_literal_representation,
59 clippy::float_cmp_const,
60 clippy::missing_docs_in_private_items,
61 clippy::multiple_inherent_impl,
62 clippy::unwrap_used,
63 clippy::cargo_common_metadata,
64 clippy::used_underscore_binding
65)]
66
67use std::fmt::{Debug, Formatter};
68use std::io;
69use std::io::{BufRead, ErrorKind, Read, Write};
70
71#[derive(Debug)]
81pub struct UnownedWriteBuffer<const S: usize> {
82 fill_count: usize,
84 buffer: [u8; S],
86}
87
88impl<const S: usize> UnownedWriteBuffer<S> {
89 #[must_use]
93 pub const fn new() -> Self {
94 let buf = Self {
95 fill_count: 0,
96 buffer: [0; S],
97 };
98
99 assert!(buf.buffer.len() >= 16, "UnownedWriteBuffer is too small");
100
101 buf
102 }
103}
104
105impl Default for UnownedWriteBuffer<0x4000> {
106 fn default() -> Self {
107 Self {
108 fill_count: 0,
109 buffer: [0; 0x4000],
110 }
111 }
112}
113
114impl<const S: usize> UnownedWriteBuffer<S> {
115 #[must_use]
117 pub const fn available(&self) -> usize {
118 self.buffer.len() - self.fill_count
119 }
120
121 #[must_use]
122 pub const fn size(&self) -> usize {
123 S
124 }
125
126 fn push<T: Write>(&mut self, write: &mut T) -> io::Result<()> {
128 if self.fill_count == 0 {
129 return Ok(());
130 }
131
132 let mut count = 0usize;
133 while count < self.fill_count {
134 match write.write(&self.buffer[count..self.fill_count]) {
135 Ok(cnt) => {
136 count += cnt;
137 continue;
138 }
139 Err(e) => {
140 if count == 0 {
141 return Err(e);
142 }
143 self.buffer.copy_within(count..self.fill_count, 0);
144 self.fill_count -= count;
145 return Err(e);
146 }
147 }
148 }
149
150 self.fill_count = 0;
151 Ok(())
152 }
153
154 pub fn flush<T: Write>(&mut self, write: &mut T) -> io::Result<()> {
158 self.push(write)?;
159 write.flush()
160 }
161
162 pub fn try_write<T: Write>(&mut self, buffer: &[u8]) -> usize {
168 if buffer.is_empty() {
169 return 0;
170 }
171 let available = self.available();
172 if available == 0 {
173 return 0;
174 }
175
176 if available < buffer.len() {
177 self.buffer[self.fill_count..].copy_from_slice(&buffer[..available]);
179 self.fill_count += available;
180 return available;
181 }
182
183 self.buffer[self.fill_count..self.fill_count + buffer.len()].copy_from_slice(buffer);
185 self.fill_count += buffer.len();
186 buffer.len()
187 }
188
189 pub fn write<T: Write>(&mut self, write: &mut T, buffer: &[u8]) -> io::Result<usize> {
198 if buffer.is_empty() {
199 return Ok(0);
200 }
201 let mut available = self.available();
202 if available == 0 {
203 self.push(write)?;
204 available = self.buffer.len();
205 }
206
207 if available < buffer.len() {
208 self.buffer[self.fill_count..].copy_from_slice(&buffer[..available]);
210 self.fill_count += available;
211 return Ok(available);
212 }
213
214 self.buffer[self.fill_count..self.fill_count + buffer.len()].copy_from_slice(buffer);
216 self.fill_count += buffer.len();
217 Ok(buffer.len())
218 }
219
220 pub fn write_all<T: Write>(&mut self, write: &mut T, buffer: &[u8]) -> io::Result<()> {
230 if buffer.is_empty() {
231 return Ok(());
232 }
233
234 let mut count = 0usize;
235 loop {
236 let rem = buffer.len() - count;
237 let mut available = self.available();
238
239 if available == 0 {
240 self.push(write)?;
241 available = self.buffer.len();
242 }
243
244 if available < rem {
245 self.buffer[self.fill_count..].copy_from_slice(&buffer[count..count + available]);
247 self.fill_count += available;
248 count += available;
249 if count >= buffer.len() {
250 return Ok(());
251 }
252 continue;
253 }
254
255 self.buffer[self.fill_count..self.fill_count + rem].copy_from_slice(&buffer[count..]);
257 self.fill_count += rem;
258 return Ok(());
259 }
260 }
261
262 pub fn borrow<'a, T: Write>(&'a mut self, write: &'a mut T) -> BorrowedWriteBuffer<'a, T, S> {
266 BorrowedWriteBuffer {
267 buffer: self,
268 write,
269 }
270 }
271}
272
273pub struct BorrowedWriteBuffer<'a, T: Write, const S: usize> {
276 buffer: &'a mut UnownedWriteBuffer<S>,
278 write: &'a mut T,
280}
281
282impl<T: Write, const S: usize> Debug for BorrowedWriteBuffer<'_, T, S> {
283 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
284 Debug::fmt(&self.buffer, f)
285 }
286}
287
288impl<T: Write, const S: usize> Write for BorrowedWriteBuffer<'_, T, S> {
289 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
290 self.buffer.write(self.write, buf)
291 }
292
293 fn flush(&mut self) -> io::Result<()> {
294 self.buffer.flush(self.write)
295 }
296
297 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
298 self.buffer.write_all(self.write, buf)
299 }
300}
301
302#[derive(Debug)]
311pub struct UnownedReadBuffer<const S: usize> {
312 read_count: usize,
314 fill_count: usize,
316 buffer: [u8; S],
318}
319
320impl<const S: usize> UnownedReadBuffer<S> {
321 #[must_use]
326 pub const fn new() -> Self {
327 let buf = Self {
328 read_count: 0,
329 fill_count: 0,
330 buffer: [0; S],
331 };
332
333 assert!(buf.buffer.len() >= 16, "UnownedReadBuffer is too small");
334
335 buf
336 }
337}
338
339impl Default for UnownedReadBuffer<0x4000> {
340 fn default() -> Self {
341 Self {
342 read_count: 0,
343 fill_count: 0,
344 buffer: [0; 0x4000],
345 }
346 }
347}
348
349impl<const S: usize> UnownedReadBuffer<S> {
350 fn feed<T: Read>(&mut self, read: &mut T) -> io::Result<bool> {
352 if self.read_count > 0 {
353 if self.read_count < self.fill_count {
354 self.buffer.copy_within(self.read_count..self.fill_count, 0);
355 }
356 self.fill_count -= self.read_count;
357 self.read_count = 0;
358 }
359
360 let count = read.read(&mut self.buffer.as_mut_slice()[self.fill_count..])?;
361 if count == 0 {
362 return Ok(false);
363 }
364
365 self.fill_count += count;
366 Ok(true)
367 }
368
369 #[must_use]
371 pub const fn available(&self) -> usize {
372 self.fill_count - self.read_count
373 }
374
375 pub fn ensure_readable<T: Read>(&mut self, read: &mut T) -> io::Result<bool> {
382 if self.available() > 0 {
383 return Ok(true);
384 }
385
386 self.feed(read)
387 }
388
389 pub fn try_read(&mut self, buffer: &mut [u8]) -> usize {
393 if buffer.is_empty() {
394 return 0;
395 }
396
397 let available = self.available();
398 if available == 0 {
399 return 0;
400 }
401
402 if available >= buffer.len() {
403 buffer.copy_from_slice(
405 &self.buffer.as_slice()[self.read_count..self.read_count + buffer.len()],
406 );
407 self.read_count += buffer.len();
408 return buffer.len();
409 }
410
411 buffer[..available]
413 .copy_from_slice(&self.buffer.as_slice()[self.read_count..self.fill_count]);
414 self.read_count = 0;
416 self.fill_count = 0;
417 available
418 }
419
420 pub fn read<T: Read>(&mut self, read: &mut T, buffer: &mut [u8]) -> io::Result<usize> {
428 if buffer.is_empty() {
429 return Ok(0);
430 }
431
432 let mut available = self.available();
433 if available == 0 {
434 if !self.feed(read)? {
435 return Ok(0);
436 }
437
438 available = self.available();
439 }
440
441 if available >= buffer.len() {
442 buffer.copy_from_slice(
444 &self.buffer.as_slice()[self.read_count..self.read_count + buffer.len()],
445 );
446 self.read_count += buffer.len();
447 return Ok(buffer.len());
448 }
449
450 buffer[..available]
452 .copy_from_slice(&self.buffer.as_slice()[self.read_count..self.fill_count]);
453 self.read_count = 0;
455 self.fill_count = 0;
456 Ok(available)
457 }
458
459 pub fn read_exact<T: Read>(&mut self, read: &mut T, buffer: &mut [u8]) -> io::Result<()> {
467 if buffer.is_empty() {
468 return Ok(());
469 }
470
471 let mut buffer = buffer;
472
473 if self.available() == 0 && !self.feed(read)? {
474 return Err(io::Error::from(ErrorKind::UnexpectedEof));
475 }
476
477 loop {
478 let available = self.available();
479 if available >= buffer.len() {
480 buffer.copy_from_slice(
482 &self.buffer.as_slice()[self.read_count..self.read_count + buffer.len()],
483 );
484 self.read_count += buffer.len();
485 return Ok(());
486 }
487
488 buffer[..available].copy_from_slice(
490 &self.buffer.as_slice()[self.read_count..self.read_count + available],
491 );
492 self.read_count = 0;
494 self.fill_count = 0;
495 if !self.feed(read)? {
496 return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
497 }
498 buffer = &mut buffer[available..];
499 }
500 }
501
502 pub fn read_until<T: Read>(
509 &mut self,
510 read: &mut T,
511 byte: u8,
512 buf: &mut Vec<u8>,
513 ) -> io::Result<usize> {
514 let mut count: usize = 0;
515
516 if self.available() == 0 && !self.feed(read)? {
517 return Ok(0);
518 }
519
520 loop {
521 for idx in self.read_count..self.fill_count {
522 if self.buffer[idx] == byte {
523 let to_push = &self.buffer[self.read_count..=idx];
524 buf.extend_from_slice(to_push);
525 self.read_count += to_push.len();
526 return Ok(count + to_push.len());
527 }
528 }
529
530 let to_push = &self.buffer[self.read_count..self.fill_count];
531 buf.extend_from_slice(to_push);
532 count += to_push.len();
533 self.read_count = 0;
534 self.fill_count = 0;
535 if !self.feed(read)? {
536 return Ok(count);
537 }
538 }
539 }
540
541 pub fn read_until_limit<T: Read>(
549 &mut self,
550 read: &mut T,
551 byte: u8,
552 limit: usize,
553 buf: &mut Vec<u8>,
554 ) -> io::Result<usize> {
555 let mut count: usize = 0;
556
557 if limit == 0 {
558 return Ok(0);
559 }
560
561 if self.available() == 0 && !self.feed(read)? {
562 return Ok(0);
563 }
564
565 loop {
566 let mut to_push = &self.buffer[self.read_count..self.fill_count];
567 if count + to_push.len() > limit {
568 to_push = &to_push[..limit - count];
569 }
570
571 debug_assert!(count + to_push.len() <= limit);
572
573 for idx in 0..to_push.len() {
574 if to_push[idx] == byte {
575 to_push = &to_push[..=idx];
576 buf.extend_from_slice(to_push);
577 self.read_count += to_push.len();
578 return Ok(count + to_push.len());
579 }
580 }
581
582 buf.extend_from_slice(to_push);
583 count += to_push.len();
584 self.read_count += to_push.len();
585 if count >= limit {
586 return Ok(count);
587 }
588
589 if !self.feed(read)? {
590 return Ok(count);
591 }
592 }
593 }
594
595 pub fn read_to_end<T: Read>(&mut self, read: &mut T, buf: &mut Vec<u8>) -> io::Result<usize> {
601 if self.available() == 0 && !self.feed(read)? {
602 return Ok(0);
603 }
604
605 let mut count = 0usize;
606
607 loop {
608 let push = &self.buffer.as_slice()[self.read_count..self.fill_count];
609 buf.extend_from_slice(push);
610 count += push.len();
611 self.fill_count = 0;
612 self.read_count = 0;
613 if !self.feed(read)? {
614 return Ok(count);
615 }
616 }
617 }
618
619 pub fn read_to_string<T: Read>(&mut self, read: &mut T, buf: &mut String) -> io::Result<usize> {
630 let mut count = 0usize;
631 if self.available() == 0 && !self.feed(read)? {
632 return Ok(0);
633 }
634
635 loop {
636 let to_push = &self.buffer[self.read_count..self.fill_count];
637 let mut utf_index = 0;
638 while utf_index + 4 < to_push.len() {
640 utf_index += next_utf8(to_push, utf_index)?;
641 }
642
643 if utf_index > 0 {
644 buf.push_str(read_utf8(&to_push[..utf_index])?);
645 count += utf_index;
646 self.read_count += utf_index; }
648
649 if self.feed(read)? {
650 continue;
651 }
652
653 let to_push = &self.buffer[self.read_count..self.fill_count];
655
656 debug_assert!(!to_push.is_empty() && to_push.len() <= 4);
658
659 let mut utf_index = 0;
660 loop {
661 if utf_index >= to_push.len() {
662 break;
663 }
664 let len = utf8_len(to_push[utf_index]);
665 if len > to_push.len() - utf_index {
666 return Err(io::Error::new(
667 ErrorKind::InvalidData,
668 "stream did not contain valid utf-8",
669 ));
670 }
671 match len {
672 1 => (),
673 2 => utf8_cont_assert(to_push[utf_index + 1])?,
674 3 => {
675 utf8_cont_assert(to_push[utf_index + 1])?;
676 utf8_cont_assert(to_push[utf_index + 2])?;
677 }
678 4 => {
679 utf8_cont_assert(to_push[utf_index + 1])?;
680 utf8_cont_assert(to_push[utf_index + 2])?;
681 utf8_cont_assert(to_push[utf_index + 3])?;
682 }
683 _ => unreachable!(),
684 }
685
686 utf_index += len;
687 }
688
689 buf.push_str(read_utf8(to_push)?);
690 return Ok(count + to_push.len());
691 }
692 }
693
694 pub fn read_line<T: Read>(&mut self, read: &mut T, buf: &mut String) -> io::Result<usize> {
709 let mut count = 0usize;
710 if self.available() == 0 && !self.feed(read)? {
711 return Ok(0);
712 }
713
714 loop {
715 for idx in self.read_count..self.fill_count {
716 if self.buffer[idx] == b'\n' {
717 let to_push = &self.buffer[self.read_count..=idx];
719
720 let mut utf_index = 0usize;
721 while utf_index < to_push.len() {
722 utf_index += next_utf8(to_push, utf_index)?;
726 }
727 buf.push_str(read_utf8(to_push)?);
728 self.read_count += to_push.len();
729 return Ok(count + to_push.len());
730 }
731 }
732
733 let to_push = &self.buffer[self.read_count..self.fill_count];
734 let mut utf_index = 0;
735 while utf_index + 4 < to_push.len() {
737 utf_index += next_utf8(to_push, utf_index)?;
738 }
739
740 if utf_index > 0 {
741 buf.push_str(read_utf8(&to_push[..utf_index])?);
742 count += utf_index;
743 self.read_count += utf_index;
744 }
745
746 if !self.feed(read)? {
747 return Ok(count);
748 }
749 }
750 }
751
752 pub fn fill_buf<T: Read>(&mut self, read: &mut T) -> io::Result<&[u8]> {
756 if self.available() == 0 && !self.feed(read)? {
757 return Ok(&[]);
758 }
759
760 Ok(&self.buffer.as_slice()[self.read_count..self.fill_count])
761 }
762
763 pub fn consume(&mut self, amt: usize) {
769 assert!(self.read_count + amt <= self.fill_count);
770 self.read_count += amt;
771 }
772
773 pub fn borrow<'a, T: Read>(&'a mut self, read: &'a mut T) -> BorrowedReadBuffer<'a, T, S> {
779 BorrowedReadBuffer { buffer: self, read }
780 }
781}
782
783pub struct BorrowedReadBuffer<'a, T: Read, const S: usize> {
786 buffer: &'a mut UnownedReadBuffer<S>,
788 read: &'a mut T,
790}
791
792impl<T: Read, const S: usize> Debug for BorrowedReadBuffer<'_, T, S> {
793 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
794 Debug::fmt(&self.buffer, f)
795 }
796}
797
798impl<T: Read, const S: usize> Read for BorrowedReadBuffer<'_, T, S> {
799 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
800 self.buffer.read(self.read, buf)
801 }
802
803 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
804 self.buffer.read_to_end(self.read, buf)
805 }
806
807 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
808 self.buffer.read_to_string(self.read, buf)
809 }
810
811 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
812 self.buffer.read_exact(self.read, buf)
813 }
814}
815
816impl<T: Read, const S: usize> BufRead for BorrowedReadBuffer<'_, T, S> {
817 fn fill_buf(&mut self) -> io::Result<&[u8]> {
818 self.buffer.fill_buf(self.read)
819 }
820
821 fn consume(&mut self, amt: usize) {
822 self.buffer.consume(amt);
823 }
824
825 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
826 self.buffer.read_until(self.read, byte, buf)
827 }
828
829 fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
830 self.buffer.read_line(self.read, buf)
831 }
832}
833
834fn next_utf8(to_push: &[u8], count: usize) -> io::Result<usize> {
842 Ok(match utf8_len(to_push[count]) {
843 1 => 1,
844 2 => {
845 utf8_cont_assert(to_push[count + 1])?;
846 2
847 }
848 3 => {
849 utf8_cont_assert(to_push[count + 1])?;
850 utf8_cont_assert(to_push[count + 2])?;
851 3
852 }
853 4 => {
854 utf8_cont_assert(to_push[count + 1])?;
855 utf8_cont_assert(to_push[count + 2])?;
856 utf8_cont_assert(to_push[count + 3])?;
857 4
858 }
859 _ => {
860 return Err(io::Error::new(
861 ErrorKind::InvalidData,
862 "stream did not contain valid utf-8",
863 ))
864 }
865 })
866}
867
868fn read_utf8(to_push: &[u8]) -> io::Result<&str> {
871 core::str::from_utf8(to_push).map_or_else(
872 |_| {
873 Err(io::Error::new(
874 ErrorKind::InvalidData,
875 "Unvalid UTF-8 detected",
876 ))
877 },
878 Ok,
879 )
880}
881
882fn utf8_cont_assert(cont: u8) -> io::Result<()> {
884 if cont & 0b1100_0000 == 0b1000_0000 {
885 return Ok(());
886 }
887
888 Err(io::Error::new(
889 ErrorKind::InvalidData,
890 "stream did not contain valid utf-8",
891 ))
892}
893
894const fn utf8_len(first: u8) -> usize {
897 if first & 0b1000_0000 == 0 {
898 return 1;
899 }
900
901 if first & 0b1110_0000 == 0b1100_0000 {
902 return 2;
903 }
904
905 if first & 0b1111_0000 == 0b1110_0000 {
906 return 3;
907 }
908
909 if first & 0b1111_1000 == 0b1111_0000 {
910 return 4;
911 }
912
913 0
915}