Skip to content
This repository was archived by the owner on Feb 14, 2023. It is now read-only.

Commit c296179

Browse files
committed
Add Buffer::resize and Buffer::truncate.
This methods enable users to use `Buffer` without having an intermediate array. For example: ``` let mut buffer = Buffer::with_capacity(1024); buffer.resize(1024, 0); let len = fill_some_data(buffer.buf_mut()); buffer.truncate(len); ```
1 parent 4c59a0f commit c296179

File tree

4 files changed

+160
-0
lines changed

4 files changed

+160
-0
lines changed

src/buffer/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ impl BufImpl {
100100

101101
pub fn reserve(&mut self, additional: usize)[additional] -> bool;
102102

103+
pub fn resize(&mut self, new_len: usize, value: u8)[new_len, value] -> bool;
104+
103105
pub fn make_room(&mut self)[];
104106

105107
pub fn buf(&self)[] -> &[u8];
@@ -111,5 +113,7 @@ impl BufImpl {
111113
pub unsafe fn bytes_written(&mut self, add: usize)[add];
112114

113115
pub fn consume(&mut self, amt: usize)[amt];
116+
117+
pub fn truncate(&mut self, len: usize)[len];
114118
}
115119
}

src/buffer/slice_deque_buf.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ impl SliceDequeBuf {
4848
true
4949
}
5050

51+
pub fn resize(&mut self, new_len: usize, value: u8) -> bool {
52+
self.deque.resize(new_len, value);
53+
true
54+
}
55+
5156
/// This method is a no-op.
5257
pub fn make_room(&mut self) {}
5358

@@ -80,4 +85,8 @@ impl SliceDequeBuf {
8085
self.deque.move_head(offset);
8186
}
8287
}
88+
89+
pub fn truncate(&mut self, len: usize) {
90+
self.deque.truncate_back(len);
91+
}
8392
}

src/buffer/std_buf.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ impl StdBuf {
6363
self.buf.reserve(additional - usable_space)
6464
}
6565

66+
pub fn resize(&mut self, new_len: usize, value: u8) -> bool {
67+
if new_len <= self.len() {
68+
self.truncate(new_len);
69+
false
70+
} else {
71+
let additional = new_len - self.len();
72+
let res = self.reserve(additional);
73+
74+
unsafe {
75+
for x in &mut self.buf.as_mut_slice()[self.end .. self.end + additional] {
76+
*x = value;
77+
}
78+
}
79+
80+
self.end += additional;
81+
res
82+
}
83+
}
84+
6685
pub fn make_room(&mut self) {
6786
self.check_cursors();
6887

@@ -104,6 +123,11 @@ impl StdBuf {
104123
self.check_cursors();
105124
}
106125

126+
pub fn truncate(&mut self, len: usize) {
127+
self.end = cmp::min(self.pos + len, self.end);
128+
self.check_cursors();
129+
}
130+
107131
pub fn check_cursors(&mut self) -> bool {
108132
if self.pos == self.end {
109133
self.pos = 0;
@@ -233,3 +257,94 @@ fn read_into_full() {
233257
assert_eq!(buffer.read_from(&mut bytes).unwrap(), 1);
234258
assert_eq!(buffer.read_from(&mut bytes).unwrap(), 0);
235259
}
260+
261+
#[test]
262+
fn test_truncate() {
263+
use Buffer;
264+
let mut buffer = Buffer::with_capacity(32);
265+
266+
buffer.truncate(5);
267+
assert_eq!(buffer.len(), 0);
268+
269+
buffer.push_bytes(&[1, 2, 3, 4, 5, 6, 7]);
270+
assert_eq!(buffer.len(), 7);
271+
272+
buffer.truncate(10);
273+
assert_eq!(buffer.len(), 7);
274+
275+
buffer.truncate(7);
276+
assert_eq!(buffer.len(), 7);
277+
278+
buffer.truncate(5);
279+
assert_eq!(buffer.len(), 5);
280+
assert_eq!(buffer.buf(), &[1, 2, 3, 4, 5]);
281+
282+
buffer.consume(1);
283+
buffer.truncate(3);
284+
assert_eq!(buffer.len(), 3);
285+
assert_eq!(buffer.buf(), &[2, 3, 4]);
286+
287+
buffer.truncate(0);
288+
assert_eq!(buffer.len(), 0);
289+
}
290+
291+
#[test]
292+
fn test_resize() {
293+
use Buffer;
294+
let mut buffer = Buffer::with_capacity(10);
295+
296+
buffer.resize(10, 0);
297+
assert_eq!(buffer.len(), 10);
298+
assert_eq!(buffer.capacity(), 10);
299+
assert_eq!(buffer.buf(), &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
300+
301+
buffer.resize(11, 1);
302+
assert_eq!(buffer.len(), 11);
303+
assert_eq!(buffer.capacity(), 11);
304+
assert_eq!(buffer.buf(), &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
305+
306+
buffer.resize(5, 2);
307+
assert_eq!(buffer.len(), 5);
308+
assert_eq!(buffer.capacity(), 11);
309+
assert_eq!(buffer.buf(), &[0, 0, 0, 0, 0]);
310+
311+
buffer.resize(7, 3);
312+
assert_eq!(buffer.len(), 7);
313+
assert_eq!(buffer.capacity(), 11);
314+
assert_eq!(buffer.buf(), &[0, 0, 0, 0, 0, 3, 3]);
315+
assert_eq!(buffer.usable_space(), 4);
316+
assert_eq!(buffer.free_space(), 4);
317+
318+
buffer.consume(2);
319+
buffer.resize(7, 4);
320+
assert_eq!(buffer.len(), 7);
321+
assert_eq!(buffer.capacity(), 11);
322+
assert_eq!(buffer.buf(), &[0, 0, 0, 3, 3, 4, 4]);
323+
assert_eq!(buffer.usable_space(), 2);
324+
assert_eq!(buffer.free_space(), 4);
325+
326+
buffer.resize(11, 5);
327+
assert_eq!(buffer.len(), 11);
328+
assert_eq!(buffer.capacity(), 13);
329+
assert_eq!(buffer.buf(), &[0, 0, 0, 3, 3, 4, 4, 5, 5, 5, 5]);
330+
assert_eq!(buffer.usable_space(), 0);
331+
assert_eq!(buffer.free_space(), 2);
332+
333+
buffer.make_room();
334+
assert_eq!(buffer.usable_space(), 2);
335+
assert_eq!(buffer.free_space(), 2);
336+
337+
buffer.resize(13, 6);
338+
assert_eq!(buffer.len(), 13);
339+
assert_eq!(buffer.capacity(), 13);
340+
assert_eq!(buffer.buf(), &[0, 0, 0, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6]);
341+
assert_eq!(buffer.usable_space(), 0);
342+
assert_eq!(buffer.free_space(), 0);
343+
344+
buffer.resize(0, 7);
345+
assert_eq!(buffer.len(), 0);
346+
assert_eq!(buffer.capacity(), 13);
347+
assert_eq!(buffer.buf(), &[]);
348+
assert_eq!(buffer.usable_space(), 13);
349+
assert_eq!(buffer.free_space(), 13);
350+
}

src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,31 @@ impl Buffer {
10121012
}
10131013
}
10141014

1015+
/// Resizes the buffer in-place sto that `len` is equal to `new_len`.
1016+
///
1017+
/// If `new_len` is greater than `len`, the buffer is extended by the difference,
1018+
/// with each additional slot filled with `value`. If `new_len` is less than `len`,
1019+
/// the buffer is simply truncated.
1020+
///
1021+
/// Note that this will reallocate even if there is enough free space at the head of
1022+
/// the buffer if `len() + usable_space() < new_len`.
1023+
///
1024+
/// If you prefer copying data down in the buffer before attempting to reallocate
1025+
/// you may wish to call `.make_room()` first.
1026+
pub fn resize(&mut self, new_len: usize, value: u8) {
1027+
// Returns `true` if we reallocated out-of-place and thus need to re-zero.
1028+
if self.buf.resize(new_len, value) {
1029+
self.zeroed = 0;
1030+
}
1031+
}
1032+
1033+
/// Resizes the buffer in-place sto that `len` is equal to `new_len`.
1034+
///
1035+
/// Same as calling `.resize(new_len, 0)`.
1036+
pub fn resize_default(&mut self, new_len: usize) {
1037+
self.buf.resize(new_len, 0);
1038+
}
1039+
10151040
/// Get an immutable slice of the available bytes in this buffer.
10161041
///
10171042
/// Call `.consume()` to remove bytes from the beginning of this slice.
@@ -1175,6 +1200,13 @@ impl Buffer {
11751200
self.buf.consume(amt);
11761201
}
11771202

1203+
/// Shortens the buffer, keeping the first `len`.
1204+
///
1205+
/// If `len` is greater then buffer's length, this has no effect.
1206+
pub fn truncate(&mut self, len: usize) {
1207+
self.buf.truncate(len);
1208+
}
1209+
11781210
/// Empty this buffer by consuming all bytes.
11791211
pub fn clear(&mut self) {
11801212
let buf_len = self.len();

0 commit comments

Comments
 (0)