buf_redux/buffer/
std_buf.rs
1use safemem;
10
11use std::cmp;
12
13use self::impl_::RawBuf;
14
15pub struct StdBuf {
16 buf: RawBuf,
17 pos: usize,
18 end: usize,
19}
20
21impl StdBuf {
22 pub fn with_capacity(cap: usize) -> Self {
23 StdBuf {
24 buf: RawBuf::with_capacity(cap),
25 pos: 0,
26 end: 0,
27 }
28 }
29
30 pub fn capacity(&self) -> usize {
31 self.buf.capacity()
32 }
33
34 pub fn len(&self) -> usize {
35 self.end - self.pos
36 }
37
38 pub fn usable_space(&self) -> usize {
39 self.capacity() - self.end
40 }
41
42 pub fn reserve(&mut self, additional: usize) -> bool {
43 self.check_cursors();
44 let usable_space = self.usable_space();
45
46 if usable_space >= additional { return false }
48
49 if self.buf.reserve_in_place(additional - usable_space) {
51 return false;
52 }
53
54 if self.pos == self.end {
56 let capacity = self.buf.capacity();
57 self.buf = RawBuf::with_capacity(0);
59 self.buf = RawBuf::with_capacity(capacity + additional);
60 return true;
61 }
62
63 self.buf.reserve(additional - usable_space)
64 }
65
66 pub fn make_room(&mut self) {
67 self.check_cursors();
68
69 if self.pos == 0 { return; }
71
72 let len = self.len();
74
75 safemem::copy_over(unsafe { self.buf.as_mut_slice() },
76 self.pos, 0, len);
77
78 self.pos = 0;
79 self.end = len;
80 }
81
82 pub fn buf(&self) -> &[u8] {
83 unsafe {
84 &self.buf.as_slice()[self.pos .. self.end]
85 }
86 }
87
88 pub fn buf_mut(&mut self) -> &mut [u8] {
89 unsafe {
90 &mut self.buf.as_mut_slice()[self.pos .. self.end]
91 }
92 }
93
94 pub unsafe fn write_buf(&mut self) -> &mut [u8] {
95 &mut self.buf.as_mut_slice()[self.end ..]
96 }
97
98 pub unsafe fn bytes_written(&mut self, amt: usize) {
99 self.end = cmp::min(self.end + amt, self.capacity());
100 }
101
102 pub fn consume(&mut self, amt: usize) {
103 self.pos = cmp::min(self.pos + amt, self.end);
104 self.check_cursors();
105 }
106
107 pub fn check_cursors(&mut self) -> bool {
108 if self.pos == self.end {
109 self.pos = 0;
110 self.end = 0;
111 true
112 } else {
113 false
114 }
115 }
116}
117
118#[cfg(not(feature = "nightly"))]
119mod impl_ {
120 use std::mem;
121
122 pub struct RawBuf {
123 buf: Box<[u8]>,
124 }
125
126 impl RawBuf {
127 pub fn with_capacity(capacity: usize) -> Self {
128 let mut buf = Vec::with_capacity(capacity);
129 let true_cap = buf.capacity();
130
131 unsafe {
132 buf.set_len(true_cap);
133 }
134
135 RawBuf {
136 buf: buf.into_boxed_slice(),
137 }
138 }
139
140 pub fn capacity(&self) -> usize {
141 self.buf.len()
142 }
143
144 pub fn reserve(&mut self, additional: usize) -> bool {
145 let mut buf = mem::replace(&mut self.buf, Box::new([])).into_vec();
146
147 let old_ptr = self.buf.as_ptr();
148
149 buf.reserve_exact(additional);
150
151 unsafe {
152 let new_cap = buf.capacity();
153 buf.set_len(new_cap);
154 }
155
156 self.buf = buf.into_boxed_slice();
157
158 old_ptr == self.buf.as_ptr()
159 }
160
161 pub fn reserve_in_place(&mut self, _additional: usize) -> bool {
162 return false;
164 }
165
166 pub unsafe fn as_slice(&self) -> &[u8] {
167 &self.buf
168 }
169
170 pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
171 &mut self.buf
172 }
173 }
174}
175
176#[cfg(feature = "nightly")]
177mod impl_ {
178 extern crate alloc;
179
180 use self::alloc::raw_vec::RawVec;
181
182 use std::slice;
183
184 pub struct RawBuf {
185 buf: RawVec<u8>,
186 }
187
188 impl RawBuf {
189 pub fn with_capacity(capacity: usize) -> Self {
190 RawBuf {
191 buf: RawVec::with_capacity(capacity)
192 }
193 }
194
195 pub fn capacity(&self) -> usize {
196 self.buf.cap()
197 }
198
199 pub fn reserve(&mut self, additional: usize) -> bool {
200 let cap = self.capacity();
201 let old_ptr = self.buf.ptr();
202 self.buf.reserve_exact(cap, additional);
203 old_ptr != self.buf.ptr()
204 }
205
206 pub fn reserve_in_place(&mut self, additional: usize) -> bool {
207 let cap = self.capacity();
208 self.buf.reserve_in_place(cap, additional)
209 }
210
211 pub unsafe fn as_slice(&self) -> &[u8] {
212 slice::from_raw_parts(self.buf.ptr(), self.buf.cap())
213 }
214
215 pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
216 slice::from_raw_parts_mut(self.buf.ptr(), self.buf.cap())
217 }
218
219 }
220}
221
222#[test]
223fn read_into_full() {
224 use Buffer;
225
226 let mut buffer = Buffer::with_capacity(1);
227
228 assert_eq!(buffer.capacity(), 1);
229
230 let mut bytes = &[1u8, 2][..];
231
232 assert_eq!(buffer.read_from(&mut bytes).unwrap(), 1);
234 assert_eq!(buffer.read_from(&mut bytes).unwrap(), 0);
235}