mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-25 00:00:22 +02:00
Get compiling on Rust 1.0 beta
This commit is contained in:
+16
-23
@@ -1,5 +1,5 @@
|
|||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
use std::rt::heap;
|
use std::ops::DerefMut;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::usize;
|
use std::usize;
|
||||||
|
|
||||||
@@ -52,13 +52,9 @@ impl MemRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes(&self) -> &[u8] {
|
pub fn bytes(&self) -> &[u8] {
|
||||||
use std::raw::Slice;
|
use std::slice;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(Slice {
|
slice::from_raw_parts(self.ptr(), self.mem().len)
|
||||||
data: self.ptr(),
|
|
||||||
len: self.mem().len,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,33 +135,30 @@ impl Heap {
|
|||||||
return MemRef::none();
|
return MemRef::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
let alloc_len = len + mem::size_of::<Mem>();
|
let alloc_len = len +
|
||||||
|
mem::size_of::<Mem>() +
|
||||||
|
mem::size_of::<Vec<u8>>();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Attempt to allocate the memory
|
let mut vec: Vec<u8> = Vec::with_capacity(alloc_len);
|
||||||
let ptr: *mut Mem = mem::transmute(
|
vec.set_len(alloc_len);
|
||||||
heap::allocate(alloc_len, mem::min_align_of::<u8>()));
|
|
||||||
|
|
||||||
// If failed, return None
|
let ptr = vec.deref_mut().as_mut_ptr();
|
||||||
if ptr.is_null() {
|
|
||||||
return MemRef::none();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the mem header
|
ptr::write(ptr as *mut Vec<u8>, vec);
|
||||||
ptr::write(ptr, Mem::new(len, mem::transmute(self as &Allocator)));
|
|
||||||
|
let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize);
|
||||||
|
ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator)));
|
||||||
|
|
||||||
// Return the info
|
// Return the info
|
||||||
MemRef::new(ptr)
|
MemRef::new(ptr as *mut Mem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deallocate(&self, mem: *mut Mem) {
|
pub fn deallocate(&self, mem: *mut Mem) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let m: &Mem = mem::transmute(mem);
|
let ptr = mem as *mut u8;
|
||||||
|
let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>);
|
||||||
heap::deallocate(
|
|
||||||
mem as *mut u8, m.len + mem::size_of::<Mem>(),
|
|
||||||
mem::min_align_of::<u8>())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -135,8 +135,7 @@ impl SmallByteStr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_slice(bytes: &[u8]) -> Option<SmallByteStr> {
|
pub fn from_slice(bytes: &[u8]) -> Option<SmallByteStr> {
|
||||||
use std::mem;
|
use std::{mem, ptr};
|
||||||
use std::slice::bytes;
|
|
||||||
|
|
||||||
if bytes.len() > MAX_LEN {
|
if bytes.len() > MAX_LEN {
|
||||||
return None;
|
return None;
|
||||||
@@ -148,7 +147,12 @@ impl SmallByteStr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Copy the memory
|
// Copy the memory
|
||||||
bytes::copy_memory(bytes, &mut ret.bytes);
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(
|
||||||
|
bytes.as_ptr(),
|
||||||
|
ret.bytes.as_mut_ptr(),
|
||||||
|
bytes.len());
|
||||||
|
}
|
||||||
|
|
||||||
Some(ret)
|
Some(ret)
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-14
@@ -2,15 +2,12 @@ use {ByteBuf, SmallByteStr};
|
|||||||
use traits::{Buf, ByteStr, ToBytes};
|
use traits::{Buf, ByteStr, ToBytes};
|
||||||
use std::{fmt, mem, ops, ptr};
|
use std::{fmt, mem, ops, ptr};
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::marker::Reflect;
|
|
||||||
use std::raw::TraitObject;
|
|
||||||
use core::nonzero::NonZero;
|
|
||||||
|
|
||||||
const INLINE: usize = 1;
|
const INLINE: usize = 1;
|
||||||
|
|
||||||
/// A specialized `ByteStr` box.
|
/// A specialized `ByteStr` box.
|
||||||
pub struct Bytes {
|
pub struct Bytes {
|
||||||
vtable: NonZero<usize>,
|
vtable: usize,
|
||||||
data: *mut (),
|
data: *mut (),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +37,7 @@ impl Bytes {
|
|||||||
mem::forget(bytes);
|
mem::forget(bytes);
|
||||||
|
|
||||||
Bytes {
|
Bytes {
|
||||||
vtable: NonZero::new(vtable as usize | INLINE),
|
vtable: vtable as usize | INLINE,
|
||||||
data: data,
|
data: data,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -48,7 +45,7 @@ impl Bytes {
|
|||||||
let obj: TraitObject = mem::transmute(obj);
|
let obj: TraitObject = mem::transmute(obj);
|
||||||
|
|
||||||
Bytes {
|
Bytes {
|
||||||
vtable: NonZero::new(obj.vtable as usize),
|
vtable: obj.vtable as usize,
|
||||||
data: obj.data,
|
data: obj.data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +74,7 @@ impl Bytes {
|
|||||||
|
|
||||||
/// If the underlying `ByteStr` is of type `B`, returns the unwraped value,
|
/// If the underlying `ByteStr` is of type `B`, returns the unwraped value,
|
||||||
/// otherwise, returns the original `Bytes` as `Err`.
|
/// otherwise, returns the original `Bytes` as `Err`.
|
||||||
pub fn try_unwrap<B: ByteStr + Reflect>(self) -> Result<B, Bytes> {
|
pub fn try_unwrap<B: ByteStr>(self) -> Result<B, Bytes> {
|
||||||
if TypeId::of::<B>() == self.obj().get_type_id() {
|
if TypeId::of::<B>() == self.obj().get_type_id() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Underlying ByteStr value is of the correct type. Unwrap it
|
// Underlying ByteStr value is of the correct type. Unwrap it
|
||||||
@@ -103,12 +100,12 @@ impl Bytes {
|
|||||||
let obj = if self.is_inline() {
|
let obj = if self.is_inline() {
|
||||||
TraitObject {
|
TraitObject {
|
||||||
data: mem::transmute(&self.data),
|
data: mem::transmute(&self.data),
|
||||||
vtable: mem::transmute(*self.vtable - 1),
|
vtable: mem::transmute(self.vtable - 1),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TraitObject {
|
TraitObject {
|
||||||
data: self.data,
|
data: self.data,
|
||||||
vtable: mem::transmute(*self.vtable),
|
vtable: mem::transmute(self.vtable),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,12 +118,12 @@ impl Bytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_inline(&self) -> bool {
|
fn is_inline(&self) -> bool {
|
||||||
(*self.vtable & INLINE) == INLINE
|
(self.vtable & INLINE) == INLINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inline<B: ByteStr>() -> bool {
|
fn inline<B: ByteStr>() -> bool {
|
||||||
mem::size_of::<B>() <= mem::size_of::<usize>()
|
mem::size_of::<B>() <= 2 * mem::size_of::<usize>()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByteStr for Bytes {
|
impl ByteStr for Bytes {
|
||||||
@@ -239,7 +236,7 @@ impl<B: ByteStr> ByteStrPriv for B {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_id(&self) -> TypeId {
|
fn get_type_id(&self) -> TypeId {
|
||||||
Any::get_type_id(self)
|
TypeId::of::<B>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index(&self, index: usize) -> &u8 {
|
fn index(&self, index: usize) -> &u8 {
|
||||||
@@ -259,11 +256,19 @@ impl<B: ByteStr> ByteStrPriv for B {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Figure out how to not depend on the memory layout of trait objects
|
||||||
|
// Blocked: rust-lang/rust#24050
|
||||||
|
struct TraitObject {
|
||||||
|
data: *mut (),
|
||||||
|
vtable: *mut (),
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_size_of() {
|
pub fn test_size_of() {
|
||||||
// TODO: One day, there shouldn't be a drop flag
|
// TODO: One day, there shouldn't be a drop flag
|
||||||
let expect = mem::size_of::<usize>() * 3;
|
let ptr_size = mem::size_of::<usize>();
|
||||||
|
let expect = ptr_size * 3;
|
||||||
|
|
||||||
assert_eq!(expect, mem::size_of::<Bytes>());
|
assert_eq!(expect, mem::size_of::<Bytes>());
|
||||||
assert_eq!(expect, mem::size_of::<Option<Bytes>>());
|
assert_eq!(expect + ptr_size, mem::size_of::<Option<Bytes>>());
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -1,8 +1,6 @@
|
|||||||
#![crate_name = "bytes"]
|
#![crate_name = "bytes"]
|
||||||
#![unstable]
|
#![unstable]
|
||||||
|
|
||||||
#![feature(alloc, convert, core)]
|
|
||||||
|
|
||||||
pub use byte_buf::{ByteBuf, ROByteBuf, MutByteBuf};
|
pub use byte_buf::{ByteBuf, ROByteBuf, MutByteBuf};
|
||||||
pub use byte_str::{SeqByteStr, SmallByteStr, SmallByteStrBuf};
|
pub use byte_str::{SeqByteStr, SmallByteStr, SmallByteStrBuf};
|
||||||
pub use bytes::Bytes;
|
pub use bytes::Bytes;
|
||||||
@@ -11,9 +9,7 @@ pub use rope::{Rope, RopeBuf};
|
|||||||
pub use slice::{SliceBuf, MutSliceBuf};
|
pub use slice::{SliceBuf, MutSliceBuf};
|
||||||
|
|
||||||
use std::{cmp, fmt, io, ops, ptr, u32};
|
use std::{cmp, fmt, io, ops, ptr, u32};
|
||||||
use std::marker::Reflect;
|
use std::any::Any;
|
||||||
|
|
||||||
extern crate core;
|
|
||||||
|
|
||||||
mod alloc;
|
mod alloc;
|
||||||
mod byte_buf;
|
mod byte_buf;
|
||||||
@@ -201,7 +197,7 @@ pub trait MutBufExt {
|
|||||||
/// An immutable sequence of bytes. Operations will not mutate the original
|
/// An immutable sequence of bytes. Operations will not mutate the original
|
||||||
/// value. Since only immutable access is permitted, operations do not require
|
/// value. Since only immutable access is permitted, operations do not require
|
||||||
/// copying (though, sometimes copying will happen as an optimization).
|
/// copying (though, sometimes copying will happen as an optimization).
|
||||||
pub trait ByteStr : Clone + Sized + Send + Sync + Reflect + ToBytes + ops::Index<usize, Output=u8> + 'static {
|
pub trait ByteStr : Clone + Sized + Send + Sync + Any + ToBytes + ops::Index<usize, Output=u8> + 'static {
|
||||||
|
|
||||||
// Until HKT lands, the buf must be bound by 'static
|
// Until HKT lands, the buf must be bound by 'static
|
||||||
type Buf: Buf+'static;
|
type Buf: Buf+'static;
|
||||||
|
|||||||
+15
-40
@@ -1,16 +1,14 @@
|
|||||||
use super::{Buf, MutBuf};
|
use {alloc, Buf, MutBuf};
|
||||||
use std::{cmp, fmt, mem, ptr, slice};
|
use std::{cmp, fmt, io, ptr};
|
||||||
use std::rt::heap;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// Buf backed by a continous chunk of memory. Maintains a read cursor and a
|
/// Buf backed by a continous chunk of memory. Maintains a read cursor and a
|
||||||
/// write cursor. When reads and writes reach the end of the allocated buffer,
|
/// write cursor. When reads and writes reach the end of the allocated buffer,
|
||||||
/// wraps around to the start.
|
/// wraps around to the start.
|
||||||
pub struct RingBuf {
|
pub struct RingBuf {
|
||||||
ptr: *mut u8, // Pointer to the memory
|
ptr: alloc::MemRef, // Pointer to the memory
|
||||||
cap: usize, // Capacity of the buffer
|
cap: usize, // Capacity of the buffer
|
||||||
pos: usize, // Offset of read cursor
|
pos: usize, // Offset of read cursor
|
||||||
len: usize // Number of bytes to read
|
len: usize // Number of bytes to read
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There are most likely many optimizations that can be made
|
// TODO: There are most likely many optimizations that can be made
|
||||||
@@ -19,7 +17,7 @@ impl RingBuf {
|
|||||||
// Handle the 0 length buffer case
|
// Handle the 0 length buffer case
|
||||||
if capacity == 0 {
|
if capacity == 0 {
|
||||||
return RingBuf {
|
return RingBuf {
|
||||||
ptr: ptr::null_mut(),
|
ptr: alloc::MemRef::none(),
|
||||||
cap: 0,
|
cap: 0,
|
||||||
pos: 0,
|
pos: 0,
|
||||||
len: 0
|
len: 0
|
||||||
@@ -29,11 +27,10 @@ impl RingBuf {
|
|||||||
// Round to the next power of 2 for better alignment
|
// Round to the next power of 2 for better alignment
|
||||||
capacity = capacity.next_power_of_two();
|
capacity = capacity.next_power_of_two();
|
||||||
|
|
||||||
// Allocate the memory
|
let mem = alloc::HEAP.allocate(capacity as usize);
|
||||||
let ptr = unsafe { heap::allocate(capacity, mem::min_align_of::<u8>()) };
|
|
||||||
|
|
||||||
RingBuf {
|
RingBuf {
|
||||||
ptr: ptr as *mut u8,
|
ptr: mem,
|
||||||
cap: capacity,
|
cap: capacity,
|
||||||
pos: 0,
|
pos: 0,
|
||||||
len: 0
|
len: 0
|
||||||
@@ -75,18 +72,6 @@ impl RingBuf {
|
|||||||
cnt = cmp::min(cnt, self.write_remaining());
|
cnt = cmp::min(cnt, self.write_remaining());
|
||||||
self.len += cnt;
|
self.len += cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
unsafe {
|
|
||||||
slice::from_raw_parts(self.ptr as *const u8, self.cap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
|
||||||
unsafe {
|
|
||||||
slice::from_raw_parts_mut(self.ptr, self.cap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for RingBuf {
|
impl Clone for RingBuf {
|
||||||
@@ -102,12 +87,12 @@ impl Clone for RingBuf {
|
|||||||
let to = self.pos + self.len;
|
let to = self.pos + self.len;
|
||||||
|
|
||||||
if to > self.cap {
|
if to > self.cap {
|
||||||
ptr::copy(self.ptr as *const u8, ret.ptr, to % self.cap);
|
ptr::copy(self.ptr.ptr() as *const u8, ret.ptr.ptr(), to % self.cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr::copy(
|
ptr::copy(
|
||||||
self.ptr.offset(self.pos as isize) as *const u8,
|
self.ptr.ptr().offset(self.pos as isize) as *const u8,
|
||||||
ret.ptr.offset(self.pos as isize),
|
ret.ptr.ptr().offset(self.pos as isize),
|
||||||
cmp::min(self.len, self.cap - self.pos));
|
cmp::min(self.len, self.cap - self.pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,16 +109,6 @@ impl fmt::Debug for RingBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for RingBuf {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.cap > 0 {
|
|
||||||
unsafe {
|
|
||||||
heap::deallocate(self.ptr, self.cap, mem::min_align_of::<u8>())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Buf for RingBuf {
|
impl Buf for RingBuf {
|
||||||
|
|
||||||
fn remaining(&self) -> usize {
|
fn remaining(&self) -> usize {
|
||||||
@@ -147,7 +122,7 @@ impl Buf for RingBuf {
|
|||||||
to = self.cap
|
to = self.cap
|
||||||
}
|
}
|
||||||
|
|
||||||
&self.as_slice()[self.pos .. to]
|
&self.ptr.bytes()[self.pos .. to]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance(&mut self, cnt: usize) {
|
fn advance(&mut self, cnt: usize) {
|
||||||
@@ -167,7 +142,7 @@ impl MutBuf for RingBuf {
|
|||||||
|
|
||||||
fn mut_bytes(&mut self) -> &mut [u8] {
|
fn mut_bytes(&mut self) -> &mut [u8] {
|
||||||
if self.cap == 0 {
|
if self.cap == 0 {
|
||||||
return self.as_mut_slice();
|
return self.ptr.bytes_mut();
|
||||||
}
|
}
|
||||||
let mut from;
|
let mut from;
|
||||||
let mut to;
|
let mut to;
|
||||||
@@ -181,7 +156,7 @@ impl MutBuf for RingBuf {
|
|||||||
to = self.cap;
|
to = self.cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
&mut self.as_mut_slice()[from..to]
|
&mut self.ptr.bytes_mut()[from..to]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(core)]
|
|
||||||
|
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ struct Chunked {
|
|||||||
|
|
||||||
impl io::Read for Chunked {
|
impl io::Read for Chunked {
|
||||||
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
|
||||||
use std::cmp;
|
use std::{cmp, ptr};
|
||||||
use std::slice::bytes;
|
|
||||||
|
|
||||||
if self.chunks.is_empty() {
|
if self.chunks.is_empty() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@@ -30,9 +29,12 @@ impl io::Read for Chunked {
|
|||||||
let src = self.chunks[0];
|
let src = self.chunks[0];
|
||||||
let len = cmp::min(src.len(), dst.len());
|
let len = cmp::min(src.len(), dst.len());
|
||||||
|
|
||||||
bytes::copy_memory(
|
unsafe {
|
||||||
&src[..len],
|
ptr::copy_nonoverlapping(
|
||||||
&mut dst[..len]);
|
src[..len].as_ptr(),
|
||||||
|
dst[..len].as_mut_ptr(),
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
if len < src.len() {
|
if len < src.len() {
|
||||||
self.chunks[0] = &src[len..];
|
self.chunks[0] = &src[len..];
|
||||||
|
|||||||
Reference in New Issue
Block a user