Skip to content

Commit 30015c2

Browse files
NobodyXulelongg
authored andcommitted
Add conversion from BytesMut to Vec<u8> (tokio-rs#543)
1 parent 2575cb2 commit 30015c2

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

0 commit comments

Comments
 (0)