Created
February 10, 2015 04:08
-
-
Save shadowmint/e341206cf458a74cd3cd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use traits::Trait; | |
use array::ArrayExt; | |
use array::Array; | |
use array::Block; | |
use array::Raw; | |
use std::default::Default; | |
/// A set of errors to associate with the buffer | |
#[derive(Debug)] | |
pub enum BufferError { | |
/// A size bound was invalid | |
InvalidSize, | |
/// A set of bounded arrays was passed, but they didn't match the required size | |
SizeMismatch | |
} | |
/// A big fixed size pixel buffer | |
pub struct Buffer<T: Default + Copy> { | |
/// The length of this buffer in each dimension | |
dim: Trait<Array<u32> + 'static>, | |
/// The buffer for this buffer | |
data: Trait<Array<T> + 'static> | |
} | |
/// Temporary view into a buffer | |
pub struct BufferTmp<'a, T: Default + Copy + 'static> { | |
/// Parent we borrowed to get this tmp from | |
parent: &'a Buffer<T>, | |
/// The offset into the parent for this buffer | |
offset: Trait<Array<u32> + 'static>, | |
/// The size of this buffer | |
dim: Trait<Array<u32> + 'static>, | |
} | |
/// Temporary view into a buffer which is writable | |
pub struct BufferTmpMut<'a, T: Default + Copy + 'static> { | |
/// Parent we borrowed to get this tmp from | |
parent: &'a mut Buffer<T> | |
/// The offset into the parent for this buffer | |
offset: Trait<Array<u32> + 'static>, | |
/// The size of this buffer | |
dim: Trait<Array<u32> + 'static>, | |
} | |
impl<T: Default + Copy + 'static> Buffer<T> { | |
/// Create a new buffer from an external source | |
/// @param data The raw data buffer, eg. from c | |
/// @param dim The size of the buffer; eg. &[100, 100] | |
pub fn new(data:*mut T, dim:&[u32]) -> Buffer<T> { | |
let mut dims = Block::<u32>::with(dim); | |
let mut total = 1u32; | |
for i in dim.iter() { | |
total = total * *i; | |
} | |
return Buffer { | |
dim: dims, | |
data: Raw::new(data, total as usize) | |
}; | |
} | |
/// Create a new buffer from an external source | |
/// @param dim The size of the buffer; eg. &[100, 100] | |
pub fn alloc(dim:&[u32]) -> Buffer<T> { | |
let mut dims = Block::<u32>::with(dim); | |
let mut total = 1u32; | |
for i in dim.iter() { | |
total = total * *i; | |
} | |
return Buffer { | |
dim: dims, | |
data: Block::new(total as usize) | |
}; | |
} | |
/// Create a raw buffer with an offset and size from an existing on | |
pub fn sub<'a>(&'a self, offset:&[u32], size:&[u32]) -> Result<BufferTmp<'a, T>, BufferError> { | |
let dims = self.size(); | |
if offset.len() != dims.len() { return Err(BufferError::SizeMismatch); } | |
if size.len() != dims.len() { return Err(BufferError::SizeMismatch); } | |
for i in range(0, dims.len()) { | |
if (offset[i] + size[i]) > dims[i] { | |
return Err(BufferError::InvalidSize); | |
} | |
} | |
return Ok(BufferTmp { | |
parent: self, | |
dim: Block::<u32>::with(size), | |
offset: Block::<u32>::with(offset) | |
}); | |
} | |
/// Create a mut raw buffer with an offset and size from an existing on | |
pub fn mut_sub<'a>(&'a mut self, offset:&[u32], size:&[u32]) -> Result<TmpMutBuffer<'a, T>, BufferError> { | |
{ | |
let dims = self.size(); | |
if offset.len() != dims.len() { return Err(BufferError::SizeMismatch); } | |
if size.len() != dims.len() { return Err(BufferError::SizeMismatch); } | |
for i in range(0, dims.len()) { | |
if (offset[i] + size[i]) > dims[i] { | |
return Err(BufferError::InvalidSize); | |
} | |
} | |
} | |
return Ok(TmpMutBuffer { | |
parent: self, | |
dim: Block::<u32>::with(size), | |
offset: Block::<u32>::with(offset) | |
}); | |
} | |
/// Return the size of the buffer | |
pub fn size(&self) -> &[u32] { | |
return (*self.dim).as_slice(); | |
} | |
/// Return a copy of the inner pointer | |
pub fn data(&self) -> *const T { | |
return (&*self.data).data(); | |
} | |
} | |
impl<'a, T: Default + Copy + 'static> BufferTmp<'a, T> { | |
/// Return the size of the buffer | |
pub fn size(&self) -> &[u32] { | |
return (*self.dim).as_slice(); | |
} | |
/// Return a copy of the inner pointer | |
pub fn data(&self) -> *const T { | |
let size = self.parent.size(); | |
let offset = (*self.offset).as_slice(); | |
return (&*self.parent).data(); | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::Buffer; | |
#[test] | |
fn test_create_raw_buffer() { | |
let _ = Buffer::new(0 as *mut u8, &[10, 10]); | |
} | |
#[test] | |
fn test_create_alloc_buffer() { | |
let _ = Buffer::<u8>::alloc(&[10, 10]); | |
} | |
#[test] | |
fn test_create_sub_buffer() { | |
let buffer = Buffer::<u8>::alloc(&[10, 10]); | |
assert!(buffer.sub(&[0, 0], &[10, 10]).is_ok()); | |
assert!(buffer.sub(&[1, 0], &[10, 10]).is_err()); | |
assert!(buffer.sub(&[0, 1], &[10, 10]).is_err()); | |
assert!(buffer.sub(&[1, 0], &[10, 10]).is_err()); | |
assert!(buffer.sub(&[1, 0], &[10, 10]).is_err()); | |
} | |
#[test] | |
fn test_create_mut_sub_buffer() { | |
let mut buffer = Buffer::<u8>::alloc(&[10, 10]); | |
assert!(buffer.mut_sub(&[0, 0], &[10, 10]).is_ok()); | |
assert!(buffer.mut_sub(&[1, 0], &[10, 10]).is_err()); | |
assert!(buffer.mut_sub(&[0, 1], &[10, 10]).is_err()); | |
assert!(buffer.mut_sub(&[1, 0], &[10, 10]).is_err()); | |
assert!(buffer.mut_sub(&[1, 0], &[10, 10]).is_err()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
doug:rust-pixelbuffer doug$ cargo test | |
Compiling pixelbuffer v0.0.1 (file:///Users/doug/dev/rust-all/rust-pixelbuffer) | |
src/buffer.rs:133:39: 133:55 error: inherent implementations are not allowed for types not defined in the current module | |
src/buffer.rs:133:39: 133:55 error: inherent implementations are not allowed for types not defined in the current module | |
src/buffer.rs:133 impl<'a, T: Default + Copy + 'static> BufferTmp<'a, T> { | |
src/buffer.rs:133 impl<'a, T: Default + Copy + 'static> BufferTmp<'a, T> { | |
^~~~~~~~~~~~~~~~ | |
^~~~~~~~~~~~~~~~ | |
error: aborting due to previous error | |
error: aborting due to previous error | |
Build failed, waiting for other jobs to finish... | |
Could not compile `pixelbuffer`. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment