Skip to content

Commit

Permalink
Merge 5983b6d into 16820a2
Browse files Browse the repository at this point in the history
  • Loading branch information
andygrove committed Apr 28, 2018
2 parents 16820a2 + 5983b6d commit ac0450f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
44 changes: 40 additions & 4 deletions rust/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub struct Buffer<T> {
}

impl<T> Buffer<T> {

/// create a buffer from an existing region of memory (must already be byte-aligned)
pub fn from_raw_parts(data: *const T, len: i32) -> Self {
Buffer { data, len }
}
Expand All @@ -41,24 +43,27 @@ impl<T> Buffer<T> {
self.len
}

/// Get a pointer to the data contained by the buffer
pub fn data(&self) -> *const T {
self.data
}

pub fn slice(&self, start: usize, end: usize) -> &[T] {
assert!(start <= end);
assert!(start <= self.len as usize);
assert!(start < self.len as usize);
assert!(end <= self.len as usize);
unsafe { slice::from_raw_parts(self.data.offset(start as isize), (end - start) as usize) }
}

/// Get a reference to the value at the specified offset
pub fn get(&self, i: usize) -> &T {
assert!(i<self.len as usize);
unsafe { &(*self.data.offset(i as isize)) }
}

/// Deprecated method (used by Bitmap)
/// Write to a slot in the buffer
pub fn set(&mut self, i: usize, v: T) {
assert!(i<self.len as usize);
unsafe {
let p = mem::transmute::<*const T, *mut T>(self.data);
*p.offset(i as isize) = v;
Expand All @@ -75,6 +80,7 @@ impl<T> Buffer<T> {
}
}

/// Release the underlying memory when the Buffer goes out of scope
impl<T> Drop for Buffer<T> {
fn drop(&mut self) {
unsafe {
Expand All @@ -99,14 +105,16 @@ where

fn next(&mut self) -> Option<Self::Item> {
if self.index < self.len as isize {
let value = unsafe { *self.data.offset(self.index) };
self.index += 1;
Some(unsafe { *self.data.offset(self.index - 1) })
Some(value)
} else {
None
}
}
}

/// Copy the memory from a Vec<T> into a newly allocated Buffer<T>
macro_rules! array_from_primitive {
($DT:ty) => {
impl From<Vec<$DT>> for Buffer<$DT> {
Expand Down Expand Up @@ -159,7 +167,7 @@ impl From<Bytes> for Buffer<u8> {
mem::transmute::<*const u8, *const libc::c_void>(bytes.as_ptr()),
len * sz,
);
mem::transmute::<*mut libc::c_void, *const u8>(dst)
mem::transmute::<*mut libc::c_void, *mut u8>(dst)
},
}
}
Expand Down Expand Up @@ -237,4 +245,32 @@ mod tests {
.collect::<Vec<i32>>();
assert_eq!(c, vec![5, 8, 9, 8, 5]);
}

#[test]
#[should_panic]
fn test_get_out_of_bounds() {
let a = Buffer::from(vec![1, 2, 3, 4, 5]);
a.get(123); // should panic
}

#[test]
#[should_panic]
fn slice_start_out_of_bounds() {
let a = Buffer::from(vec![1, 2, 3, 4, 5]);
a.slice(5, 5); // should panic
}

#[test]
#[should_panic]
fn slice_end_out_of_bounds() {
let a = Buffer::from(vec![1, 2, 3, 4, 5]);
a.slice(0, 6); // should panic
}

#[test]
#[should_panic]
fn slice_end_before_start() {
let a = Buffer::from(vec![1, 2, 3, 4, 5]);
a.slice(3, 2); // should panic
}
}
20 changes: 20 additions & 0 deletions rust/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,24 @@ mod tests {
assert_eq!("Hello, World!", s);
}

#[test]
#[should_panic]
fn test_slice_start_out_of_bounds() {
let mut b: Builder<u8> = Builder::with_capacity(2);
b.slice_mut(2, 2); // should panic
}

#[test]
#[should_panic]
fn test_slice_end_out_of_bounds() {
let mut b: Builder<u8> = Builder::with_capacity(2);
b.slice_mut(0, 3); // should panic
}

#[test]
#[should_panic]
fn test_slice_end_before_start() {
let mut b: Builder<u8> = Builder::with_capacity(2);
b.slice_mut(1, 0); // should panic
}
}

0 comments on commit ac0450f

Please sign in to comment.