Skip to main content

ntex_bytes/
pages.rs

1#![allow(clippy::missing_panics_doc, clippy::box_collection)]
2use std::{borrow::Borrow, cell::Cell, cmp, collections::VecDeque, fmt, io, mem, ops, ptr};
3
4use crate::{BufMut, BytePageSize, ByteString, Bytes, BytesMut};
5use crate::{buf::UninitSlice, storage::StorageVec};
6
7pub struct BytePages {
8    st: Option<Box<Inner>>,
9    current: StorageVec,
10}
11
12struct Inner {
13    size: BytePageSize,
14    pages: VecDeque<BytePage>,
15}
16
17thread_local! {
18    static CACHE: Cell<Option<Box<Vec<Box<Inner>>>>> = Cell::new(Some(Box::default()));
19}
20const CACHE_SIZE: usize = 128;
21
22impl BytePages {
23    /// Creates a new `BytePages` with the specified page size.
24    ///
25    /// The returned `BytePages` will be hold one page with
26    /// specified capacity.
27    pub fn new(size: BytePageSize) -> Self {
28        debug_assert!(size != BytePageSize::Unset, "Page cannot be Unset");
29
30        let st = CACHE.with(move |c| {
31            let mut cache = c.take().unwrap();
32
33            let item = if let Some(mut item) = cache.pop() {
34                item.size = size;
35                item
36            } else {
37                Box::new(Inner {
38                    size,
39                    pages: VecDeque::with_capacity(8),
40                })
41            };
42            c.set(Some(cache));
43            item
44        });
45
46        BytePages {
47            st: Some(st),
48            current: StorageVec::sized(size),
49        }
50    }
51
52    fn pages(&self) -> &VecDeque<BytePage> {
53        &self.st.as_ref().unwrap().pages
54    }
55
56    fn pages_mut(&mut self) -> &mut VecDeque<BytePage> {
57        &mut self.st.as_mut().unwrap().pages
58    }
59
60    /// Get size of the page.
61    pub fn page_size(&self) -> BytePageSize {
62        self.st.as_ref().unwrap().size
63    }
64
65    /// Sets the page size for new pages.
66    pub fn set_page_size(&mut self, size: BytePageSize) {
67        self.st.as_mut().unwrap().size = size;
68    }
69
70    /// Insert a page to the front of the collection.
71    pub fn prepend<T>(&mut self, buf: T) -> bool
72    where
73        BytePage: From<T>,
74    {
75        let p = BytePage::from(buf);
76        if p.is_empty() {
77            false
78        } else {
79            self.pages_mut().push_front(p);
80            true
81        }
82    }
83
84    /// Appends a new page to the back of the collection.
85    pub fn append<T>(&mut self, buf: T)
86    where
87        BytePage: From<T>,
88    {
89        let p = BytePage::from(buf);
90        let remaining = self.current.remaining();
91
92        if p.len() <= remaining {
93            self.put_slice(p.as_ref());
94        } else if self.current.len() == 0 {
95            match p.into_storage() {
96                Ok(st) => {
97                    self.current = st;
98                }
99                Err(page) => {
100                    // add buffer to stack
101                    self.pages_mut().push_back(page);
102                }
103            }
104        } else {
105            // push current storage to stack
106            let storage = StorageVec::sized(self.page_size());
107            let page: BytePage = From::from(mem::replace(&mut self.current, storage));
108            let pages = self.pages_mut();
109            pages.push_back(page);
110            // add buffer to stack
111            pages.push_back(p);
112        }
113    }
114
115    #[inline]
116    /// Appends the given bytes to this page object.
117    ///
118    /// Tries to write the data into the current page first. If there
119    /// is insufficient space, one or more new pages are allocated as
120    /// needed, and the remaining data is copied into them.
121    pub fn extend_from_slice(&mut self, extend: &[u8]) {
122        self.put_slice(extend);
123    }
124
125    #[inline]
126    /// Gets the total number of pages.
127    pub fn len(&self) -> usize {
128        self.pages()
129            .iter()
130            .fold(self.current.len(), |c, page| c + page.len())
131    }
132
133    #[inline]
134    /// Checks if the `BytePages` instance is empty.
135    pub fn is_empty(&self) -> bool {
136        for p in self.pages() {
137            if !p.is_empty() {
138                return false;
139            }
140        }
141        self.current.len() == 0
142    }
143
144    #[inline]
145    /// Returns the total number of pages contained in this object.
146    pub fn num_pages(&self) -> usize {
147        if self.current.len() == 0 {
148            self.pages().len()
149        } else {
150            self.pages().len() + 1
151        }
152    }
153
154    /// Returns the first page from the collection.
155    pub fn take(&mut self) -> Option<BytePage> {
156        if let Some(page) = self.pages_mut().pop_front() {
157            Some(page)
158        } else if self.current.len() == 0 {
159            None
160        } else {
161            let storage = StorageVec::sized(self.page_size());
162            Some(BytePage::from(mem::replace(&mut self.current, storage)))
163        }
164    }
165
166    #[inline]
167    /// Copies all pages into another `BytePages` instance.
168    ///
169    /// Depending on the underlying storage, this operation might be `O(1)` or could
170    /// involve a memory copy.
171    pub fn copy_to(&self, pages: &mut BytePages) {
172        for p in self.pages() {
173            pages.append(p.clone());
174        }
175
176        if self.current.len() != 0 {
177            pages.append(BytePage::from(Bytes::copy_from_slice(
178                self.current.as_ref(),
179            )));
180        }
181    }
182
183    #[inline]
184    /// Moves all pages to another `BytePages` instance.
185    pub fn move_to(&mut self, pages: &mut BytePages) {
186        while let Some(page) = self.take() {
187            pages.append(page);
188        }
189    }
190
191    /// Splits the buffer into two at the given index.
192    ///
193    /// Afterwards, `self` contains elements `[at, len)`, and the returned `BytePage`
194    /// contains elements `[0, at)`.
195    ///
196    /// Depending on the underlying storage, this operation might be `O(1)` or could
197    /// involve a memory copy.
198    #[must_use]
199    pub fn split_to(&mut self, at: usize) -> BytePages {
200        let mut pages = BytePages::new(self.page_size());
201        self.split_into(at, &mut pages);
202        pages
203    }
204
205    /// Splits the buffer, adding the resulting items to the supplied pages object.
206    ///
207    /// Afterwards, `self` contains elements `[at, len)`, and the supplied `BytePage`
208    /// contains elements `[0, at)`.
209    ///
210    /// Depending on the underlying storage, this operation might be `O(1)` or could
211    /// involve a memory copy.
212    pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
213        {
214            let pages = self.pages_mut();
215
216            while let Some(mut page) = pages.pop_front() {
217                let len = cmp::min(page.len(), at);
218                to.append(page.split_to(len));
219
220                if !page.is_empty() {
221                    pages.push_front(page);
222                    return;
223                }
224                at -= len;
225            }
226        }
227        if at > 0
228            && let Some(mut page) = self.take()
229        {
230            let len = cmp::min(page.len(), at);
231            to.append(page.split_to(len));
232            self.append(page);
233        }
234    }
235
236    /// Converts `self` into an immutable `Bytes`.
237    #[inline]
238    #[must_use]
239    pub fn freeze(&mut self) -> Bytes {
240        let pages = self.num_pages();
241        if pages == 0 || self.is_empty() {
242            Bytes::new()
243        } else if pages == 1 {
244            self.take().unwrap().freeze()
245        } else {
246            let mut buf = BytesMut::with_capacity(self.len());
247            while let Some(p) = self.take() {
248                buf.extend_from_slice(&p);
249            }
250            buf.freeze()
251        }
252    }
253
254    #[inline]
255    pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
256        if self.pages().is_empty() && self.current.len() == 0 && pages.current.len() != 0 {
257            self.current =
258                mem::replace(&mut pages.current, StorageVec::sized(self.page_size()));
259        }
260    }
261
262    /// Access current page as `BytesMut` object
263    pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
264    where
265        F: FnOnce(&mut BytesMut) -> R,
266    {
267        let mut buf = BytesMut {
268            storage: StorageVec(self.current.0),
269        };
270        buf.storage.unsize();
271
272        let res = f(&mut buf);
273        mem::forget(buf);
274        res
275    }
276}
277
278impl Drop for BytePages {
279    fn drop(&mut self) {
280        CACHE.with(move |c| {
281            let mut cache = c.take().unwrap();
282            if cache.len() < CACHE_SIZE {
283                let mut st = self.st.take().unwrap();
284                st.pages.clear();
285                cache.push(st);
286            }
287            c.set(Some(cache));
288        });
289    }
290}
291
292impl fmt::Debug for BytePages {
293    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
294        let mut f = fmt.debug_tuple("BytePages");
295        for p in self.pages() {
296            f.field(p);
297        }
298        if self.current.len() != 0 {
299            f.field(&crate::debug::BsDebug(self.current.as_ref()));
300        }
301        f.finish()
302    }
303}
304
305impl Default for BytePages {
306    fn default() -> Self {
307        BytePages::new(BytePageSize::Size16)
308    }
309}
310
311impl BufMut for BytePages {
312    #[inline]
313    fn remaining_mut(&self) -> usize {
314        self.current.remaining()
315    }
316
317    #[inline]
318    unsafe fn advance_mut(&mut self, cnt: usize) {
319        // This call will panic if `cnt` is too big
320        self.current.set_len(self.current.len() + cnt);
321    }
322
323    #[inline]
324    fn chunk_mut(&mut self) -> &mut UninitSlice {
325        unsafe {
326            // This will never panic as `len` can never become invalid
327            let ptr = &mut self.current.as_ptr();
328            UninitSlice::from_raw_parts_mut(
329                ptr.add(self.current.len()),
330                self.remaining_mut(),
331            )
332        }
333    }
334
335    fn put_slice(&mut self, mut src: &[u8]) {
336        while !src.is_empty() {
337            let amount = cmp::min(src.len(), self.current.remaining());
338            unsafe {
339                ptr::copy_nonoverlapping(
340                    src.as_ptr(),
341                    self.chunk_mut().as_mut_ptr(),
342                    amount,
343                );
344                self.advance_mut(amount);
345            }
346            src = &src[amount..];
347
348            // add new page
349            if self.current.is_full() {
350                let storage = StorageVec::sized(self.page_size());
351                let page = BytePage::from(mem::replace(&mut self.current, storage));
352                self.pages_mut().push_back(page);
353            }
354        }
355    }
356
357    #[inline]
358    fn put_u8(&mut self, n: u8) {
359        self.current.put_u8(n);
360        if self.current.is_full() {
361            let storage = StorageVec::sized(self.page_size());
362            let page: BytePage = From::from(mem::replace(&mut self.current, storage));
363            self.pages_mut().push_back(page);
364        }
365    }
366
367    #[inline]
368    fn put_i8(&mut self, n: i8) {
369        self.put_u8(n as u8);
370    }
371}
372
373impl Clone for BytePages {
374    fn clone(&self) -> Self {
375        let size = self.page_size();
376        let mut pages = BytePages::new(size);
377        self.copy_to(&mut pages);
378        pages
379    }
380}
381
382impl io::Write for BytePages {
383    fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
384        self.put_slice(src);
385        Ok(src.len())
386    }
387
388    fn flush(&mut self) -> Result<(), io::Error> {
389        Ok(())
390    }
391}
392
393impl From<BytePages> for Bytes {
394    fn from(pages: BytePages) -> Bytes {
395        BytesMut::from(pages).freeze()
396    }
397}
398
399impl From<BytePages> for BytesMut {
400    fn from(mut pages: BytePages) -> BytesMut {
401        let mut buf = BytesMut::with_capacity(pages.len());
402        while let Some(p) = pages.take() {
403            buf.extend_from_slice(&p);
404        }
405        buf
406    }
407}
408
409pub struct BytePage {
410    inner: StorageType,
411}
412
413enum StorageType {
414    Bytes(Bytes),
415    Storage(StorageVec),
416    Vec(Vec<u8>),
417}
418
419impl BytePage {
420    #[inline]
421    /// Returns the number of bytes contained in this `BytePage`.
422    pub fn len(&self) -> usize {
423        match &self.inner {
424            StorageType::Bytes(b) => b.len(),
425            StorageType::Storage(b) => b.len(),
426            StorageType::Vec(b) => b.len(),
427        }
428    }
429
430    #[inline]
431    /// Returns true if the `BytePage` has a length of 0.
432    pub fn is_empty(&self) -> bool {
433        match &self.inner {
434            StorageType::Bytes(b) => b.is_empty(),
435            StorageType::Storage(b) => b.len() == 0,
436            StorageType::Vec(b) => b.is_empty(),
437        }
438    }
439
440    /// Return a raw pointer to data.
441    pub fn as_ptr(&self) -> *const u8 {
442        unsafe {
443            match &self.inner {
444                StorageType::Bytes(b) => b.storage.as_ptr(),
445                StorageType::Storage(b) => b.as_ptr(),
446                StorageType::Vec(b) => b.as_ptr(),
447            }
448        }
449    }
450
451    /// Splits the buffer into two at the given index.
452    ///
453    /// Afterwards, `self` contains elements `[at, len)`, and the returned `BytePage`
454    /// contains elements `[0, at)`.
455    ///
456    /// Depending on the underlying storage, this operation might be `O(1)` or could
457    /// involve a memory copy.
458    #[must_use]
459    pub fn split_to(&mut self, at: usize) -> BytePage {
460        match &mut self.inner {
461            StorageType::Bytes(b) => {
462                let buf = b.split_to(cmp::min(at, b.len()));
463                BytePage {
464                    inner: StorageType::Bytes(buf),
465                }
466            }
467            StorageType::Storage(_) => {
468                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
469                if let StorageType::Storage(st) = inner {
470                    self.inner = StorageType::Bytes(Bytes {
471                        storage: st.freeze(),
472                    });
473                    self.split_to(at)
474                } else {
475                    unreachable!()
476                }
477            }
478            StorageType::Vec(_) => {
479                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
480                if let StorageType::Vec(b) = inner {
481                    self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
482                    self.split_to(at)
483                } else {
484                    unreachable!()
485                }
486            }
487        }
488    }
489
490    /// Advance the internal cursor.
491    ///
492    /// Afterwards `self` contains elements `[cnt, len)`.
493    /// This is an `O(1)` operation.
494    ///
495    /// # Panics
496    ///
497    /// Panics if `cnt > len`.
498    #[inline]
499    pub fn advance_to(&mut self, cnt: usize) {
500        match &mut self.inner {
501            StorageType::Bytes(b) => b.advance_to(cnt),
502            StorageType::Storage(b) => unsafe { b.set_start(cnt as u32) },
503            StorageType::Vec(b) => {
504                self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
505            }
506        }
507    }
508
509    /// Converts `self` into an immutable `Bytes`.
510    #[inline]
511    #[must_use]
512    pub fn freeze(self) -> Bytes {
513        match self.inner {
514            StorageType::Bytes(b) => b,
515            StorageType::Storage(st) => Bytes {
516                storage: st.freeze(),
517            },
518            StorageType::Vec(v) => Bytes::from(v),
519        }
520    }
521
522    fn into_storage(self) -> Result<StorageVec, Self> {
523        if let StorageType::Storage(mut st) = self.inner {
524            // SAFETY: Converting back to `StorageVec` requires uniqueness.
525            if !st.is_full() && st.is_unique() {
526                Ok(st)
527            } else {
528                Err(Self {
529                    inner: StorageType::Storage(st),
530                })
531            }
532        } else {
533            Err(self)
534        }
535    }
536}
537
538impl Clone for BytePage {
539    fn clone(&self) -> Self {
540        let inner = match &self.inner {
541            StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
542            StorageType::Storage(st) => {
543                // SAFETY: We garantee that `st` is not being used
544                // for modification. `st` is marked as non-unique after clone
545                StorageType::Storage(unsafe { st.clone() })
546            }
547            StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
548        };
549
550        Self { inner }
551    }
552}
553
554impl AsRef<[u8]> for BytePage {
555    #[inline]
556    fn as_ref(&self) -> &[u8] {
557        match &self.inner {
558            StorageType::Bytes(b) => b.as_ref(),
559            StorageType::Storage(b) => b.as_ref(),
560            StorageType::Vec(b) => b.as_ref(),
561        }
562    }
563}
564
565impl Borrow<[u8]> for BytePage {
566    #[inline]
567    fn borrow(&self) -> &[u8] {
568        self.as_ref()
569    }
570}
571
572impl From<Bytes> for BytePage {
573    fn from(buf: Bytes) -> Self {
574        BytePage {
575            inner: StorageType::Bytes(buf),
576        }
577    }
578}
579
580impl<'a> From<&'a Bytes> for BytePage {
581    fn from(buf: &'a Bytes) -> Self {
582        BytePage {
583            inner: StorageType::Bytes(buf.clone()),
584        }
585    }
586}
587
588impl From<BytesMut> for BytePage {
589    fn from(buf: BytesMut) -> Self {
590        BytePage {
591            inner: StorageType::Storage(buf.storage),
592        }
593    }
594}
595
596impl From<ByteString> for BytePage {
597    fn from(s: ByteString) -> Self {
598        s.into_bytes().into()
599    }
600}
601
602impl<'a> From<&'a ByteString> for BytePage {
603    fn from(s: &'a ByteString) -> Self {
604        s.clone().into_bytes().into()
605    }
606}
607
608impl From<StorageVec> for BytePage {
609    fn from(buf: StorageVec) -> Self {
610        BytePage {
611            inner: StorageType::Storage(buf),
612        }
613    }
614}
615
616impl From<Vec<u8>> for BytePage {
617    fn from(buf: Vec<u8>) -> Self {
618        BytePage {
619            inner: StorageType::Vec(buf),
620        }
621    }
622}
623
624impl From<&'static str> for BytePage {
625    fn from(buf: &'static str) -> Self {
626        BytePage::from(Bytes::from_static(buf.as_bytes()))
627    }
628}
629
630impl From<&'static [u8]> for BytePage {
631    fn from(buf: &'static [u8]) -> Self {
632        BytePage::from(Bytes::from_static(buf))
633    }
634}
635
636impl<const N: usize> From<&'static [u8; N]> for BytePage {
637    fn from(src: &'static [u8; N]) -> Self {
638        BytePage::from(Bytes::from_static(src))
639    }
640}
641
642impl From<BytePage> for Bytes {
643    fn from(page: BytePage) -> Self {
644        match page.inner {
645            StorageType::Bytes(b) => b,
646            StorageType::Storage(storage) => BytesMut { storage }.freeze(),
647            StorageType::Vec(v) => Bytes::copy_from_slice(&v),
648        }
649    }
650}
651
652impl From<BytePage> for BytesMut {
653    fn from(page: BytePage) -> Self {
654        match page.inner {
655            StorageType::Bytes(b) => b.into(),
656            StorageType::Storage(storage) => BytesMut { storage },
657            StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
658        }
659    }
660}
661
662impl PartialEq for BytePage {
663    fn eq(&self, other: &BytePage) -> bool {
664        self.as_ref() == other.as_ref()
665    }
666}
667
668impl<'a> PartialEq<&'a [u8]> for BytePage {
669    fn eq(&self, other: &&'a [u8]) -> bool {
670        self.as_ref() == *other
671    }
672}
673
674impl<'a, const N: usize> PartialEq<&'a [u8; N]> for BytePage {
675    fn eq(&self, other: &&'a [u8; N]) -> bool {
676        self.as_ref() == other.as_ref()
677    }
678}
679
680impl io::Read for BytePage {
681    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
682        let len = cmp::min(self.len(), dst.len());
683        if len > 0 {
684            dst[..len].copy_from_slice(&self[..len]);
685            self.advance_to(len);
686        }
687        Ok(len)
688    }
689}
690
691impl ops::Deref for BytePage {
692    type Target = [u8];
693
694    #[inline]
695    fn deref(&self) -> &[u8] {
696        self.as_ref()
697    }
698}
699
700impl fmt::Debug for BytePage {
701    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
702        fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
703    }
704}
705
706#[cfg(test)]
707mod tests {
708    use super::*;
709
710    #[test]
711    fn pages() {
712        // pages
713        let mut pages = BytePages::new(BytePageSize::Size8);
714        assert!(pages.is_empty());
715        assert_eq!(pages.len(), 0);
716        assert_eq!(pages.num_pages(), 0);
717        pages.extend_from_slice(b"b");
718        assert_eq!(pages.len(), 1);
719        assert_eq!(pages.num_pages(), 1);
720        pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
721        assert_eq!(pages.len(), 9217);
722        assert_eq!(pages.num_pages(), 2);
723        assert!(!pages.is_empty());
724
725        let mut pgs = BytePages::new(BytePageSize::Size8);
726        pgs.put_i8(b'a' as i8);
727        let p = pgs.take().unwrap();
728        assert_eq!(p.len(), 1);
729        assert_eq!(p.as_ref(), b"a");
730
731        pgs.extend_from_slice("a".repeat(8 * 1024 - 1).as_bytes());
732        assert_eq!(pgs.num_pages(), 1);
733        pgs.put_u8(b'a');
734        assert_eq!(pgs.num_pages(), 1);
735        assert_eq!(pgs.current.len(), 0);
736
737        pgs.put_u8(b'a');
738        assert_eq!(pgs.num_pages(), 2);
739
740        pgs.append(Bytes::copy_from_slice("a".repeat(8 * 1024).as_bytes()));
741        assert_eq!(pgs.num_pages(), 3);
742        assert_eq!(pgs.current.len(), 0);
743
744        // page
745        let p = pages.take().unwrap();
746        assert_eq!(p.len(), 8192);
747        let p = pages.take().unwrap();
748        assert_eq!(p.len(), 1025);
749        assert!(!p.is_empty());
750        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
751        assert_eq!(p.as_ref(), "a".repeat(1025).as_bytes());
752        assert!(pages.take().is_none());
753
754        let p = BytePage::from(Bytes::copy_from_slice(b"123"));
755        assert_eq!(p.len(), 3);
756        assert!(!p.is_empty());
757        assert_eq!(p.as_ref(), b"123");
758        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
759
760        let p = BytePage::from(&b"123"[..]);
761        assert_eq!(p.len(), 3);
762        assert!(!p.is_empty());
763        assert_eq!(p.as_ref(), b"123");
764        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
765
766        let p = BytePage::from(b"123");
767        assert_eq!(p.len(), 3);
768        assert!(!p.is_empty());
769        assert_eq!(p.as_ref(), b"123");
770        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
771
772        let p = BytePage::from("123");
773        assert_eq!(p.len(), 3);
774        assert!(!p.is_empty());
775        assert_eq!(p.as_ref(), b"123");
776        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
777        assert_eq!(p.freeze(), b"123");
778
779        let p = BytePage::from(vec![b'1', b'2', b'3']);
780        assert_eq!(p.len(), 3);
781        assert!(!p.is_empty());
782        assert_eq!(p.as_ref(), b"123");
783        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
784        assert_eq!(p.freeze(), b"123");
785
786        let mut p = BytePage::from(vec![b'1', b'2', b'3']);
787        p.advance_to(1);
788        assert_eq!(p.len(), 2);
789        assert!(!p.is_empty());
790        assert_eq!(p.as_ref(), b"23");
791
792        // debug
793        let mut pages = BytePages::new(BytePageSize::Size8);
794        pages.extend_from_slice(b"b");
795        assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
796        let p = pages.take().unwrap();
797        assert_eq!(p.as_ref(), b"b");
798
799        let mut pages = BytePages::new(BytePageSize::Size8);
800        pages.extend_from_slice(b"a");
801        pages.append(Bytes::copy_from_slice(b"123"));
802        pages.pages_mut().push_back(p);
803        assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
804    }
805
806    #[test]
807    fn pages_copy_to() {
808        let mut pages = BytePages::default();
809        let mut pages2 = BytePages::default();
810        pages.put_slice(b"456");
811        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
812        pages.copy_to(&mut pages2);
813        let p = pages.freeze();
814        assert_eq!(p, b"123456");
815        let p2 = pages2.freeze();
816        assert_eq!(p2, b"123456");
817
818        let mut pages = BytePages::default();
819        let mut pages2 = BytePages::default();
820        pages.put_slice(b"456");
821        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
822        pages.copy_to(&mut pages2);
823        pages.put_u8(b'7');
824        let p = pages.freeze();
825        assert_eq!(p, b"1234567");
826        let p2 = pages2.freeze();
827        assert_eq!(p2, b"123456");
828
829        let mut pages = BytePages::default();
830        pages.put_slice(b"456");
831        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
832        let mut pages2 = pages.clone();
833        pages.put_u8(b'7');
834        let p = pages.freeze();
835        assert_eq!(p, b"1234567");
836        let p2 = pages2.freeze();
837        assert_eq!(p2, b"123456");
838    }
839
840    #[test]
841    fn pages_methods() {
842        // .split_to()
843        let mut pages = BytePages::default();
844        pages.put_slice(b"456");
845        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
846        let mut pages2 = pages.split_to(1);
847        let p = pages.freeze();
848        assert_eq!(p, b"23456");
849        let p2 = pages2.freeze();
850        assert_eq!(p2, b"1");
851
852        let mut pages = BytePages::default();
853        pages.put_slice(b"456");
854        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
855        let mut pages2 = pages.split_to(4);
856        let p = pages.freeze();
857        assert_eq!(p, b"56");
858        let p2 = pages2.freeze();
859        assert_eq!(p2, b"1234");
860
861        // .split_into()
862        let mut pages = BytePages::default();
863        pages.put_slice(b"456");
864        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
865        let mut pages2 = BytePages::default();
866        pages.split_into(1, &mut pages2);
867        let p = pages.freeze();
868        assert_eq!(p, b"23456");
869        let p2 = pages2.freeze();
870        assert_eq!(p2, b"1");
871
872        // with_bytes_vec()
873        let mut pages = BytePages::default();
874        pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
875        let p = pages.freeze();
876        assert_eq!(p, b"123");
877    }
878
879    #[test]
880    fn page_clone() {
881        // Bytes storage
882        let p = BytePage::from(Bytes::copy_from_slice(b"123"));
883        let p2 = p.clone();
884        assert_eq!(p, p2);
885
886        // StorageVec
887        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
888        if let StorageType::Storage(ref mut st) = p.inner {
889            assert!(st.is_unique());
890        } else {
891            panic!()
892        }
893        let p2 = p.clone();
894        assert_eq!(p, p2);
895        if let StorageType::Storage(mut st) = p.inner {
896            assert!(!st.is_unique());
897        } else {
898            panic!()
899        }
900
901        // Vec<u8> storage
902        let p = BytePage::from(vec![b'1', b'2', b'3']);
903        let p2 = p.clone();
904        assert_eq!(p, p2);
905        if let StorageType::Bytes(_) = p2.inner {
906        } else {
907            panic!()
908        }
909    }
910
911    #[test]
912    fn page_split_to() {
913        // Bytes storage
914        let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
915        let p2 = p.split_to(1);
916        assert_eq!(p, b"23");
917        assert_eq!(p2, b"1");
918
919        // StorageVec
920        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
921        let p2 = p.split_to(1);
922        assert_eq!(p, b"23");
923        assert_eq!(p2, b"1");
924
925        // Vec<u8> storage
926        let mut p = BytePage::from(vec![b'1', b'2', b'3']);
927        let p2 = p.split_to(1);
928        assert_eq!(p, b"23");
929        assert_eq!(p2, b"1");
930    }
931
932    #[test]
933    fn page_read() {
934        use std::io::Read;
935
936        let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
937
938        let mut buf = [0; 10];
939        assert_eq!(page.read(&mut buf).unwrap(), 3);
940        assert_eq!(page.len(), 0);
941        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
942    }
943}