Skip to content

Commit 068ed41

Browse files
authored
Add conversion from BytesMut to Vec<u8> (#543)
1 parent f514bd3 commit 068ed41

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/bytes_mut.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,43 @@ impl PartialEq<Bytes> for BytesMut {
15401540
}
15411541
}
15421542

1543+
impl From<BytesMut> for Vec<u8> {
1544+
fn from(mut bytes: BytesMut) -> Self {
1545+
let kind = bytes.kind();
1546+
1547+
let mut vec = if kind == KIND_VEC {
1548+
unsafe {
1549+
let (off, _) = bytes.get_vec_pos();
1550+
rebuild_vec(bytes.ptr.as_ptr(), bytes.len, bytes.cap, off)
1551+
}
1552+
} else if kind == KIND_ARC {
1553+
let shared = unsafe { &mut *(bytes.data as *mut Shared) };
1554+
if shared.is_unique() {
1555+
let vec = mem::replace(&mut shared.vec, Vec::new());
1556+
1557+
unsafe { release_shared(shared) };
1558+
1559+
vec
1560+
} else {
1561+
return bytes.deref().into();
1562+
}
1563+
} else {
1564+
return bytes.deref().into();
1565+
};
1566+
1567+
let len = bytes.len;
1568+
1569+
unsafe {
1570+
ptr::copy(bytes.ptr.as_ptr(), vec.as_mut_ptr(), len);
1571+
vec.set_len(len);
1572+
}
1573+
1574+
mem::forget(bytes);
1575+
1576+
vec
1577+
}
1578+
}
1579+
15431580
#[inline]
15441581
fn vptr(ptr: *mut u8) -> NonNull<u8> {
15451582
if cfg!(debug_assertions) {

tests/test_bytes.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,3 +1028,40 @@ fn box_slice_empty() {
10281028
let b = Bytes::from(empty);
10291029
assert!(b.is_empty());
10301030
}
1031+
1032+
#[test]
1033+
fn bytes_into_vec() {
1034+
// Test kind == KIND_VEC
1035+
let content = b"helloworld";
1036+
1037+
let mut bytes = BytesMut::new();
1038+
bytes.put_slice(content);
1039+
1040+
let vec: Vec<u8> = bytes.into();
1041+
assert_eq!(&vec, content);
1042+
1043+
// Test kind == KIND_ARC, shared.is_unique() == True
1044+
let mut bytes = BytesMut::new();
1045+
bytes.put_slice(b"abcdewe23");
1046+
bytes.put_slice(content);
1047+
1048+
// Overwrite the bytes to make sure only one reference to the underlying
1049+
// Vec exists.
1050+
bytes = bytes.split_off(9);
1051+
1052+
let vec: Vec<u8> = bytes.into();
1053+
assert_eq!(&vec, content);
1054+
1055+
// Test kind == KIND_ARC, shared.is_unique() == False
1056+
let prefix = b"abcdewe23";
1057+
1058+
let mut bytes = BytesMut::new();
1059+
bytes.put_slice(prefix);
1060+
bytes.put_slice(content);
1061+
1062+
let vec: Vec<u8> = bytes.split_off(prefix.len()).into();
1063+
assert_eq!(&vec, content);
1064+
1065+
let vec: Vec<u8> = bytes.into();
1066+
assert_eq!(&vec, prefix);
1067+
}

0 commit comments

Comments
 (0)