unowned_buf/
lib.rs

1//! Buffered Read+BufRead and Write for Rust that does not own the underlying Read/Write
2//!
3//! # Example usage
4//! ```rust
5//! use std::io;
6//! use std::io::ErrorKind;
7//! use std::net::TcpStream;
8//! use std::sync::Mutex;
9//! use unowned_buf::{UnownedReadBuffer, UnownedWriteBuffer};
10//!
11//! #[derive(Debug)]
12//! struct DuplexBufferedTcpStream {
13//!     stream: TcpStream,
14//!     read_buf: Mutex<UnownedReadBuffer<0x4000>>,
15//!     write_buf: Mutex<UnownedWriteBuffer<0x4000>>,
16//! }
17//!
18//! impl DuplexBufferedTcpStream {
19//!     fn new(stream: TcpStream) -> DuplexBufferedTcpStream {
20//!         Self {
21//!             stream,
22//!             read_buf: Mutex::new(UnownedReadBuffer::new()),
23//!             write_buf: Mutex::new(UnownedWriteBuffer::new()),
24//!         }
25//!     }
26//!
27//!     fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
28//!         self.read_buf.try_lock()
29//!             .map_err(|_| io::Error::from(ErrorKind::WouldBlock))?
30//!             .read(&mut &self.stream, buf)
31//!     }
32//!
33//!     fn write(&self, buf: &[u8]) -> io::Result<usize> {
34//!         self.write_buf.try_lock()
35//!             .map_err(|_| io::Error::from(ErrorKind::WouldBlock))?
36//!             .write(&mut &self.stream, buf)
37//!     }
38//!
39//!     fn flush(&self) -> io::Result<()> {
40//!         self.write_buf.try_lock()
41//!             .map_err(|_| io::Error::from(ErrorKind::WouldBlock))?
42//!             .flush(&mut &self.stream)
43//!     }
44//!
45//!     //Add other fn delegates from BufRead, Read or Write as needed or implement the traits for these directly.
46//!     //Or add set/get timeout fns that delete to the TcpStream.
47//! }
48//! ```
49
50#![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///
72/// Unowned Write buffer.
73///
74/// # S Generic: Size of the buffer.
75/// beware that if this size is too large, and you stack allocate this struct
76/// then you will hit the guard page and your program will crash.
77/// If you must use very large buffers then Box this struct.
78///
79///
80#[derive(Debug)]
81pub struct UnownedWriteBuffer<const S: usize> {
82    /// How many bytes in the buffer have we filled and must still be sent to a `Write` impl?
83    fill_count: usize,
84    /// The buffer
85    buffer: [u8; S],
86}
87
88impl<const S: usize> UnownedWriteBuffer<S> {
89    /// Construct a new Buffer
90    /// # Panics
91    /// if S is smaller than 16.
92    #[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    /// Returns the amount of bytes that can still be written into the internal buffer.
116    #[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    /// Push some bytes to the Write impl.
127    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    /// Flush all bytes to the underlying Write impl. This call also calls `Write::flush` afterward.
155    /// # Errors
156    /// Propagated from `Write` impl
157    pub fn flush<T: Write>(&mut self, write: &mut T) -> io::Result<()> {
158        self.push(write)?;
159        write.flush()
160    }
161
162    /// Write as many bytes as can still fit to the internal buffer.
163    /// This function returns 0 if the internal buffer is full.
164    /// If the supplied buffer is only partially written then this fn guarantees that
165    /// the entire internal buffer has been filled and subsequent calls to `try_write` are pointless
166    /// unless flush or `write`/`write_all` are first called.
167    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            //PARTIAL WRITE
178            self.buffer[self.fill_count..].copy_from_slice(&buffer[..available]);
179            self.fill_count += available;
180            return available;
181        }
182
183        //FULL WRITE
184        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    /// Write as many bytes as can still fit to the internal buffer.
190    /// This call will not push the internal buffer to the Write impl if the internal buffer
191    /// still had room for at least one byte. It is only guaranteed to at least "write" 1 byte.
192    /// This fn might call the underlying write impl several times.
193    ///
194    /// # Errors
195    /// Propagated from `Write` impl
196    ///
197    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            //PARTIAL WRITE
209            self.buffer[self.fill_count..].copy_from_slice(&buffer[..available]);
210            self.fill_count += available;
211            return Ok(available);
212        }
213
214        //FULL WRITE
215        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    /// Writes all bytes to the internal buffer if they fit,
221    /// otherwise all excess bytes are flushed to the underlying Write impl.
222    ///
223    /// This fn only returns `Ok()` if all bytes are either in the internal buffer or already
224    /// written to the underlying Write impl.
225    ///
226    /// # Errors
227    /// Propagated from `Write` impl
228    ///
229    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                //PARTIAL WRITE
246                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            //FULL WRITE
256            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    /// This fn "borrows"/associates this buffer with a Write impl. The returned `BorrowedWriteBuffer`
263    /// has the same lifetime as the Write impl and &mut self combined and can be used as a dyn Write.
264    /// This might be required to call some library functions which demand a dyn Write as parameter.
265    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
273/// Borrowed dyn Write of a `UnownedWriteBuffer`.
274/// This borrowed version is directly associated with a Write impl, but is subject to lifetimes.
275pub struct BorrowedWriteBuffer<'a, T: Write, const S: usize> {
276    /// Read ref
277    buffer: &'a mut UnownedWriteBuffer<S>,
278    /// Write ref
279    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///
303/// Unowned Read buffer.
304///
305/// # S Generic: Size of the buffer.
306/// beware that if this size is too large, and you stack allocate this struct
307/// then you will hit the guard page and your program will crash.
308///
309///
310#[derive(Debug)]
311pub struct UnownedReadBuffer<const S: usize> {
312    /// How much have we read?
313    read_count: usize,
314    /// How much can we read?
315    fill_count: usize,
316    /// The buffer
317    buffer: [u8; S],
318}
319
320impl<const S: usize> UnownedReadBuffer<S> {
321    /// Construct a new Buffer
322    ///
323    /// # Panics
324    /// if S is smaller than 16
325    #[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    /// reads some bytes from the read impl.
351    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    /// returns the amount of bytes that can still be read from the internal buffer.
370    #[must_use]
371    pub const fn available(&self) -> usize {
372        self.fill_count - self.read_count
373    }
374
375    /// This fn will return true if at least one byte can be read.
376    /// If the internal buffer is not empty this fn immediately returns true.
377    /// If the internal buffer is empty then it will call `read()` once and return true if the read did not return Ok(0).
378    ///
379    /// # Errors
380    /// propagated from Read, including `TimedOut` and `WouldBlock`
381    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    /// This fn reads as many bytes as possible from the internal buffer.
390    /// it returns 0 if the internal buffer is empty.
391    ///
392    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            //FULL READ
404            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        //PARTIAL READ
412        buffer[..available]
413            .copy_from_slice(&self.buffer.as_slice()[self.read_count..self.fill_count]);
414        //The buffer is empty now.
415        self.read_count = 0;
416        self.fill_count = 0;
417        available
418    }
419
420    /// This fn will read as many bytes as possible from the internal buffer.
421    /// If the internal buffer is empty when this fn is called then 1 call to the `Read` impl is made to fill the buffer.
422    /// This fn only returns Ok(0) if the 1 call to the underlying read impl returned 0.
423    /// This fn does not call the read impl if `available()` != 0.
424    /// # Errors
425    /// Propagated from the `Read` impl
426    ///
427    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            //FULL READ
443            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        //PARTIAL READ
451        buffer[..available]
452            .copy_from_slice(&self.buffer.as_slice()[self.read_count..self.fill_count]);
453        //The buffer is empty now.
454        self.read_count = 0;
455        self.fill_count = 0;
456        Ok(available)
457    }
458
459    /// This fn will read the entire buffer from either the internal buffer or the
460    /// `Read` impl. Multiple calls to the read impl may be made if necessary to fill the buffer.
461    ///
462    /// # Errors
463    /// Propagated from the `Read` impl
464    /// `ErrorKind::UnexpectedEof` if the `Read` impl returns Ok(0) before the buffer was filled.
465    ///
466    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                //FULL read
481                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            //PARTIAL READ
489            buffer[..available].copy_from_slice(
490                &self.buffer.as_slice()[self.read_count..self.read_count + available],
491            );
492            //The buffer is empty now.
493            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    /// Reads until either EOF happens or the desired byte is found.
503    /// This fn may call the underlying `Read` impl multiple times until the buffer is filled.
504    ///
505    /// # Errors
506    /// Propagated from the `Read` impl
507    ///
508    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    /// Reads until either EOF happens or the desired byte is found or limit bytes have been appended to buf.
542    /// The actual read impl may supply more bytes than limit, the excess is stored in the internal buffer in this case.
543    /// Returns the amount of bytes appended to the buf vec.
544    ///
545    /// # Errors
546    /// Propagated from the `Read` impl
547    ///
548    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    /// Reads all remaining bytes into the buffer.
596    /// Those bytes may be from the internal buffer and then from the underlying `Read` impl.
597    /// # Errors
598    /// Propagated from the `Read` impl
599    ///
600    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    /// Reads all remaining bytes into the String.
620    /// Those bytes may be from the internal buffer and then from the underlying `Read` impl.
621    /// If the `Read` or buffer contained non-valid utf-8 sequences then this fn returns an `io::Error` with Kind `InvalidData`.
622    /// No data is lost in this case as bytes read and already placed in the buf are, in the buf and all remaining bytes
623    /// starting with those that were not valid utf-8 are in the internal buffer and can be fetched with a call to `try_read()`.
624    ///
625    /// # Errors
626    /// Propagated from the `Read` impl
627    /// `ErrorKind::InvalidData` if invalid utf-8 is found.
628    ///
629    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            //We leave up to 4 bytes in the buffer for the next cycle because those may be part of an incomplete multibyte sequence.
639            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; //feed will compact the buffer.
647            }
648
649            if self.feed(read)? {
650                continue;
651            }
652
653            //EOF, the rest we must check multibyte for bounds. We must carefully analyze!
654            let to_push = &self.buffer[self.read_count..self.fill_count];
655
656            //Bounds: we have at least 1 byte remaining at this point.
657            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    ///
695    /// Reads all bytes into the string until \n is found, or EOF occurred.
696    /// Data is first taken from the internal buffer and then taken from the `Read` impl.
697    ///
698    /// # Major difference from `BufRead`'s `read_line` fn:
699    /// this fn guarantees that no data is discarded when invalid utf-8 is encountered.
700    /// buf may contain some valid bytes in this case but all invalid bytes are retained in the internal buffer
701    /// so that the next call to `read()` can pick them up. call `available()` so you know how many bytes to read!
702    /// `BufRead`'s `read_line` fn just discards the last chunk of invalid data.
703    ///
704    /// # Errors
705    /// Propagated from the `Read` impl
706    /// `ErrorKind::InvalidData` if invalid utf-8 is found.
707    ///
708    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                    //We found it!
718                    let to_push = &self.buffer[self.read_count..=idx];
719
720                    let mut utf_index = 0usize;
721                    while utf_index < to_push.len() {
722                        //Panic safety, we do not need to check for bounds here,
723                        //The last byte in the buffer is known to be \n where utf8_len does return 1!
724                        //\n is not a valid continuation so a call to utf8_cont_assert(\n) will always fail.
725                        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            //We leave up to 4 bytes in the buffer for the next cycle because those may be part of an incomplete multibyte sequence.
736            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    /// `ReadBuf`'s fill buf equivalent. This will only pull data from the underlying read if the internal buffer is empty.
753    /// # Errors
754    /// Propagated from the `Read` impl
755    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    /// `ReadBuf`'s consume fn.
764    /// In general, it should be paired with calls to `fill_buf`
765    /// # Panics
766    /// This function will panic if amt is > available
767    ///
768    pub fn consume(&mut self, amt: usize) {
769        assert!(self.read_count + amt <= self.fill_count);
770        self.read_count += amt;
771    }
772
773    /// Borrows this unowned buffer and associates it with `Read` impl.
774    /// The returned `BorrowedReadBuffer` is both dyn `Read` and dyn `ReadBuf`.
775    /// This may be necessary to call some api function from a library that expects such datatypes.
776    /// The returned `BorrowedReadBuffer` is subject to the lifetime of both the read and self.
777    ///
778    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
783/// Borrowed dyn Read/ReadBuf of a `UnownedReadBuffer`.
784/// This borrowed version is directly associated with a `Read` impl, but is subject to lifetimes.
785pub struct BorrowedReadBuffer<'a, T: Read, const S: usize> {
786    /// buffer ref
787    buffer: &'a mut UnownedReadBuffer<S>,
788    /// read ref
789    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
834/// This fn returns the size of the next utf-8 character in bytes.
835/// this can return 1,2,3,4 or Err.
836/// Err is returned if the bit for an utf-8 continuation byte is set on the first byte.
837/// Err is returned if any of the subsequent bytes do NOT have the utf-8 continuation bit set.
838///
839/// This fn does not check the buffer for bounds and assumes the caller ensures that at least 4 bytes
840/// or an invalid utf-8 sequence is encountered before end of buffer.
841fn 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
868/// This fn does a `utf::from_utf8` safety check,
869/// and then converts errors that should never exist (`Utf8Error`) to `io::Error`
870fn 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
882/// This fn returns err if the given byte does not have the utf-8 continuation bits set.
883fn 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
894/// This fn returns the length in bytes the first utf-8 byte suggests.
895/// 0 is returned for invalid first utf-8 bytes.
896const 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    //INVALID
914    0
915}