Skip to main content

ntex_bytes/
lib.rs

1//! Provides abstractions for working with bytes.
2//!
3//! The `ntex-bytes` crate provides an efficient byte buffer structure
4//! ([`Bytes`](struct.Bytes.html)) and traits for working with buffer
5//! implementations ([`Buf`], [`BufMut`]).
6//!
7//! [`Buf`]: trait.Buf.html
8//! [`BufMut`]: trait.BufMut.html
9//!
10//! # `Bytes`
11//!
12//! `Bytes` is an efficient container for storing and operating on contiguous
13//! slices of memory. It is intended for use primarily in networking code, but
14//! could have applications elsewhere as well.
15//!
16//! `Bytes` values facilitate zero-copy network programming by allowing multiple
17//! `Bytes` objects to point to the same underlying memory. This is managed by
18//! using a reference count to track when the memory is no longer needed and can
19//! be freed.
20//!
21//! A `Bytes` handle can be created directly from an existing `BytesMut` store
22//! is used first and written to. For example:
23//!
24//! ```rust
25//! use ntex_bytes::{BytesMut, BufMut};
26//!
27//! let mut buf = BytesMut::with_capacity(1024);
28//! buf.put(&b"hello world"[..]);
29//! buf.put_u16(1234);
30//!
31//! let a = buf.take();
32//! assert_eq!(a, b"hello world\x04\xD2"[..]);
33//!
34//! buf.put(&b"goodbye world"[..]);
35//!
36//! let b = buf.take();
37//! assert_eq!(b, b"goodbye world"[..]);
38//!
39//! assert_eq!(buf.capacity(), 998);
40//! ```
41//!
42//! In the above example, only a single buffer of 1024 is allocated. The handles
43//! `a` and `b` will share the underlying buffer and maintain indices tracking
44//! the view into the buffer represented by the handle.
45//!
46//! See the [struct docs] for more details.
47//!
48//! [struct docs]: struct.Bytes.html
49//!
50#![doc(html_root_url = "https://docs.rs/ntex-bytes/")]
51#![deny(clippy::pedantic)]
52#![allow(
53    unsafe_op_in_unsafe_fn,
54    clippy::cast_sign_loss,
55    clippy::cast_possible_wrap,
56    clippy::cast_possible_truncation,
57    clippy::must_use_candidate,
58    clippy::unnecessary_wraps
59)]
60
61extern crate alloc;
62
63pub mod buf;
64pub use crate::buf::{Buf, BufMut};
65
66mod bvec;
67mod bytes;
68mod debug;
69mod hex;
70mod pages;
71mod serde;
72mod storage;
73mod string;
74mod stvec;
75
76mod stext;
77mod stext_arc;
78
79pub use crate::bvec::BytesMut;
80pub use crate::bytes::Bytes;
81pub use crate::pages::{BytePage, BytePages};
82pub use crate::stext::{StorageExt, StorageExtStr, StorageVTable};
83pub use crate::string::ByteString;
84
85#[doc(hidden)]
86pub use crate::stvec::METADATA_SIZE;
87
88#[doc(hidden)]
89#[deprecated]
90pub type BytesVec = BytesMut;
91
92#[doc(hidden)]
93pub mod info {
94    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
95    pub struct Info {
96        pub id: usize,
97        pub refs: u32,
98        pub kind: Kind,
99        pub capacity: usize,
100    }
101
102    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
103    pub enum Kind {
104        Inline,
105        Static,
106        Vec,
107        StExt,
108    }
109}
110
111#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
112pub enum BytePageSize {
113    Size4 = 0,
114    Size8 = 1,
115    #[default]
116    Size16 = 2,
117    Size24 = 3,
118    Size32 = 4,
119    Size48 = 5,
120    Size64 = 6,
121    Unset = 7,
122}
123
124impl BytePageSize {
125    pub const fn capacity(self) -> usize {
126        match self {
127            BytePageSize::Size4 => 4 * 1024,
128            BytePageSize::Size8 => 8 * 1024,
129            BytePageSize::Size16 => 16 * 1024,
130            BytePageSize::Size24 => 24 * 1024,
131            BytePageSize::Size32 => 32 * 1024,
132            BytePageSize::Size48 => 48 * 1024,
133            BytePageSize::Size64 | BytePageSize::Unset => 64 * 1024,
134        }
135    }
136
137    pub const fn half_capacity(self) -> usize {
138        match self {
139            BytePageSize::Size4 => 2 * 1024,
140            BytePageSize::Size8 => 4 * 1024,
141            BytePageSize::Size16 => 8 * 1024,
142            BytePageSize::Size24 => 12 * 1024,
143            BytePageSize::Size32
144            | BytePageSize::Size48
145            | BytePageSize::Size64
146            | BytePageSize::Unset => 16 * 1024,
147        }
148    }
149}
150
151/// Set pages cache size
152///
153/// Size is set for current thread
154pub fn set_pages_cache(size: usize) {
155    self::stvec::set_pages_cache(size);
156}
157
158#[cfg(test)]
159mod tests {
160    use super::*;
161
162    #[test]
163    fn page_size() {
164        assert_eq!(BytePageSize::Size4.capacity(), 4 * 1024);
165        assert_eq!(BytePageSize::Size8.capacity(), 8 * 1024);
166        assert_eq!(BytePageSize::Size16.capacity(), 16 * 1024);
167        assert_eq!(BytePageSize::Size24.capacity(), 24 * 1024);
168        assert_eq!(BytePageSize::Size32.capacity(), 32 * 1024);
169        assert_eq!(BytePageSize::Size48.capacity(), 48 * 1024);
170        assert_eq!(BytePageSize::Size64.capacity(), 64 * 1024);
171        assert_eq!(BytePageSize::Unset.capacity(), 64 * 1024);
172        assert_eq!(BytePageSize::Size4.half_capacity(), 2 * 1024);
173        assert_eq!(BytePageSize::Size8.half_capacity(), 4 * 1024);
174        assert_eq!(BytePageSize::Size16.half_capacity(), 8 * 1024);
175        assert_eq!(BytePageSize::Size24.half_capacity(), 12 * 1024);
176        assert_eq!(BytePageSize::Size32.half_capacity(), 16 * 1024);
177        assert_eq!(BytePageSize::Size48.half_capacity(), 16 * 1024);
178        assert_eq!(BytePageSize::Size64.half_capacity(), 16 * 1024);
179        assert_eq!(BytePageSize::Unset.half_capacity(), 16 * 1024);
180    }
181}