add generic Idx
type argument to Buffer
and Length
This commit is contained in:
parent
88b1e3b668
commit
7e0af1b8f6
|
@ -2,28 +2,30 @@ use core::fmt::{self, Debug, Display};
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash)]
|
#[derive(Clone, Copy, Debug, Hash)]
|
||||||
pub enum Length {
|
pub enum Length<Idx> {
|
||||||
Unbounded,
|
Unbounded,
|
||||||
Bounded(usize),
|
Bounded(Idx),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Length {
|
impl<Idx: Copy> Length<Idx> {
|
||||||
pub fn try_len(&self) -> Option<usize> {
|
pub fn try_len(&self) -> Option<Idx> {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => None,
|
Length::Unbounded => None,
|
||||||
Length::Bounded(n) => Some(n),
|
Length::Bounded(n) => Some(n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn len(&self) -> usize {
|
pub unsafe fn len(&self) -> Idx {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => {
|
Length::Unbounded => panic!(
|
||||||
panic!("attempt to convert `Length::Unbounded` to `usize`")
|
"attempt to convert `Length::Unbounded` to `Length::Idx`"
|
||||||
}
|
),
|
||||||
Length::Bounded(n) => n,
|
Length::Bounded(n) => n,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Idx> Length<Idx> {
|
||||||
pub fn is_bounded(&self) -> bool {
|
pub fn is_bounded(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => false,
|
Length::Unbounded => false,
|
||||||
|
@ -32,62 +34,64 @@ impl Length {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Length {
|
impl<Idx: Debug> Display for Length<Idx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
Debug::fmt(self, f)
|
Debug::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Length {
|
impl<Idx: PartialEq> PartialEq for Length<Idx> {
|
||||||
fn eq(&self, rhs: &Length) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
match (*self, *rhs) {
|
match (self, rhs) {
|
||||||
(Length::Unbounded, _) => false,
|
(&Length::Unbounded, _) => false,
|
||||||
(_, Length::Unbounded) => false,
|
(_, &Length::Unbounded) => false,
|
||||||
(Length::Bounded(a), Length::Bounded(ref b)) => a.eq(b),
|
(&Length::Bounded(ref a), &Length::Bounded(ref b)) => a.eq(b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ne(&self, rhs: &Length) -> bool {
|
fn ne(&self, rhs: &Self) -> bool {
|
||||||
match (*self, *rhs) {
|
match (self, rhs) {
|
||||||
(Length::Unbounded, _) => false,
|
(&Length::Unbounded, _) => false,
|
||||||
(_, Length::Unbounded) => false,
|
(_, &Length::Unbounded) => false,
|
||||||
(Length::Bounded(a), Length::Bounded(ref b)) => a.ne(b),
|
(&Length::Bounded(ref a), &Length::Bounded(ref b)) => a.ne(b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<usize> for Length {
|
impl<Idx: PartialEq> PartialEq<Idx> for Length<Idx> {
|
||||||
fn eq(&self, rhs: &usize) -> bool {
|
fn eq(&self, rhs: &Idx) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => false,
|
Length::Unbounded => false,
|
||||||
Length::Bounded(n) => n.eq(rhs),
|
Length::Bounded(ref n) => n.eq(rhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ne(&self, rhs: &usize) -> bool {
|
fn ne(&self, rhs: &Idx) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => false,
|
Length::Unbounded => false,
|
||||||
Length::Bounded(n) => n.eq(rhs),
|
Length::Bounded(ref n) => n.eq(rhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Length {
|
impl<Idx: PartialOrd> PartialOrd for Length<Idx> {
|
||||||
fn partial_cmp(&self, rhs: &Length) -> Option<Ordering> {
|
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
|
||||||
match (*self, *rhs) {
|
match (self, rhs) {
|
||||||
(Length::Unbounded, Length::Unbounded) => None,
|
(&Length::Unbounded, &Length::Unbounded) => None,
|
||||||
(Length::Unbounded, _) => Some(Ordering::Greater),
|
(&Length::Unbounded, _) => Some(Ordering::Greater),
|
||||||
(_, Length::Unbounded) => Some(Ordering::Less),
|
(_, &Length::Unbounded) => Some(Ordering::Less),
|
||||||
(Length::Bounded(a), Length::Bounded(ref b)) => a.partial_cmp(b),
|
(&Length::Bounded(ref a), &Length::Bounded(ref b)) => {
|
||||||
|
a.partial_cmp(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd<usize> for Length {
|
impl<Idx: PartialOrd> PartialOrd<Idx> for Length<Idx> {
|
||||||
fn partial_cmp(&self, rhs: &usize) -> Option<Ordering> {
|
fn partial_cmp(&self, rhs: &Idx) -> Option<Ordering> {
|
||||||
match *self {
|
match *self {
|
||||||
Length::Unbounded => Some(Ordering::Greater),
|
Length::Unbounded => Some(Ordering::Greater),
|
||||||
Length::Bounded(n) => n.partial_cmp(rhs),
|
Length::Bounded(ref n) => n.partial_cmp(rhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,23 +11,24 @@ use error::Infallible;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
use self::length::Length;
|
use self::length::Length;
|
||||||
|
|
||||||
pub trait Buffer<T>
|
pub trait Buffer<T, Idx>
|
||||||
where
|
where
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
|
Idx: PartialEq + PartialOrd,
|
||||||
{
|
{
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
fn len(&self) -> Length;
|
fn len(&self) -> Length<Idx>;
|
||||||
fn commit(
|
fn commit(
|
||||||
&mut self,
|
&mut self,
|
||||||
slice: Option<BufferCommit<T>>,
|
slice: Option<BufferCommit<T>>,
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
unsafe fn slice_unchecked<'a>(
|
unsafe fn slice_unchecked<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<usize>,
|
range: Range<Idx>,
|
||||||
) -> BufferSlice<'a, T>;
|
) -> BufferSlice<'a, T>;
|
||||||
|
|
||||||
fn slice<'a>(&'a self, range: Range<usize>) -> Option<BufferSlice<'a, T>> {
|
fn slice<'a>(&'a self, range: Range<Idx>) -> Option<BufferSlice<'a, T>> {
|
||||||
if self.len() >= range.end && self.len() > range.start {
|
if self.len() >= range.end && self.len() > range.start {
|
||||||
unsafe { Some(self.slice_unchecked(range)) }
|
unsafe { Some(self.slice_unchecked(range)) }
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,14 +215,14 @@ impl<T> DerefMut for BufferCommit<T> {
|
||||||
|
|
||||||
macro_rules! impl_slice {
|
macro_rules! impl_slice {
|
||||||
(@inner $buffer:ty $( , $lt:lifetime )* ) => {
|
(@inner $buffer:ty $( , $lt:lifetime )* ) => {
|
||||||
impl<$( $lt, )* T> Buffer<T> for $buffer
|
impl<$( $lt, )* T> Buffer<T, usize> for $buffer
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
[T]: ToOwned,
|
[T]: ToOwned,
|
||||||
{
|
{
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn len(&self) -> Length {
|
fn len(&self) -> Length<usize> {
|
||||||
Length::Bounded(<Self as AsRef<[T]>>::as_ref(self).len())
|
Length::Bounded(<Self as AsRef<[T]>>::as_ref(self).len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +273,10 @@ mod file {
|
||||||
use super::{Buffer, BufferCommit, BufferSlice};
|
use super::{Buffer, BufferCommit, BufferSlice};
|
||||||
use super::length::Length;
|
use super::length::Length;
|
||||||
|
|
||||||
impl Buffer<u8> for RefCell<File> {
|
impl Buffer<u8, usize> for RefCell<File> {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn len(&self) -> Length {
|
fn len(&self) -> Length<usize> {
|
||||||
Length::Bounded(
|
Length::Bounded(
|
||||||
self.borrow()
|
self.borrow()
|
||||||
.metadata()
|
.metadata()
|
||||||
|
|
|
@ -2,6 +2,7 @@ use core::mem;
|
||||||
use alloc::Vec;
|
use alloc::Vec;
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
|
use block::Address; // TODO
|
||||||
use buffer::{Buffer, BufferSlice};
|
use buffer::{Buffer, BufferSlice};
|
||||||
use sys::superblock::Superblock;
|
use sys::superblock::Superblock;
|
||||||
use sys::block_group::BlockGroupDescriptor;
|
use sys::block_group::BlockGroupDescriptor;
|
||||||
|
@ -20,13 +21,13 @@ impl<T> From<(T, usize)> for Struct<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safe wrapper for raw sys structs
|
/// Safe wrapper for raw sys structs
|
||||||
pub struct Ext2<B: Buffer<u8>> {
|
pub struct Ext2<B: Buffer<u8, usize>> {
|
||||||
buffer: B,
|
buffer: B,
|
||||||
superblock: Struct<Superblock>,
|
superblock: Struct<Superblock>,
|
||||||
block_groups: Struct<Vec<BlockGroupDescriptor>>,
|
block_groups: Struct<Vec<BlockGroupDescriptor>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: Buffer<u8>> Ext2<B>
|
impl<B: Buffer<u8, usize>> Ext2<B>
|
||||||
where
|
where
|
||||||
Error: From<B::Error>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
|
@ -164,7 +165,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Inodes<'a, B: 'a + Buffer<u8>> {
|
pub struct Inodes<'a, B: 'a + Buffer<u8, usize>> {
|
||||||
buffer: &'a B,
|
buffer: &'a B,
|
||||||
block_groups: &'a [BlockGroupDescriptor],
|
block_groups: &'a [BlockGroupDescriptor],
|
||||||
block_size: usize,
|
block_size: usize,
|
||||||
|
@ -174,7 +175,7 @@ pub struct Inodes<'a, B: 'a + Buffer<u8>> {
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, B: 'a + Buffer<u8>> Iterator for Inodes<'a, B>
|
impl<'a, B: 'a + Buffer<u8, usize>> Iterator for Inodes<'a, B>
|
||||||
where
|
where
|
||||||
Error: From<B::Error>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,12 +51,12 @@ impl Debug for BlockGroupDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockGroupDescriptor {
|
impl BlockGroupDescriptor {
|
||||||
pub unsafe fn find_descriptor<'a, E>(
|
pub unsafe fn find_descriptor<B: Buffer<u8, usize>>(
|
||||||
haystack: &'a Buffer<u8, Error = E>,
|
haystack: &B,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) -> Result<(BlockGroupDescriptor, usize), Error>
|
) -> Result<(BlockGroupDescriptor, usize), Error>
|
||||||
where
|
where
|
||||||
Error: From<E>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
let end = offset + mem::size_of::<BlockGroupDescriptor>();
|
let end = offset + mem::size_of::<BlockGroupDescriptor>();
|
||||||
if haystack.len() < end {
|
if haystack.len() < end {
|
||||||
|
@ -70,13 +70,13 @@ impl BlockGroupDescriptor {
|
||||||
Ok(descr)
|
Ok(descr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn find_descriptor_table<'a, E>(
|
pub unsafe fn find_descriptor_table<B: Buffer<u8, usize>>(
|
||||||
haystack: &'a Buffer<u8, Error = E>,
|
haystack: &B,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
count: usize,
|
count: usize,
|
||||||
) -> Result<(Vec<BlockGroupDescriptor>, usize), Error>
|
) -> Result<(Vec<BlockGroupDescriptor>, usize), Error>
|
||||||
where
|
where
|
||||||
Error: From<E>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
let end = offset + count * mem::size_of::<BlockGroupDescriptor>();
|
let end = offset + count * mem::size_of::<BlockGroupDescriptor>();
|
||||||
if haystack.len() < end {
|
if haystack.len() < end {
|
||||||
|
|
|
@ -96,13 +96,13 @@ impl Debug for Inode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inode {
|
impl Inode {
|
||||||
pub unsafe fn find_inode<'a, E>(
|
pub unsafe fn find_inode<B: Buffer<u8, usize>>(
|
||||||
haystack: &'a Buffer<u8, Error = E>,
|
haystack: &B,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
size: usize,
|
size: usize,
|
||||||
) -> Result<(Inode, usize), Error>
|
) -> Result<(Inode, usize), Error>
|
||||||
where
|
where
|
||||||
Error: From<E>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
if size != mem::size_of::<Inode>() {
|
if size != mem::size_of::<Inode>() {
|
||||||
unimplemented!("inodes with a size != 128");
|
unimplemented!("inodes with a size != 128");
|
||||||
|
|
|
@ -194,11 +194,11 @@ impl Debug for Superblock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Superblock {
|
impl Superblock {
|
||||||
pub unsafe fn find<'a, E>(
|
pub unsafe fn find<B: Buffer<u8, usize>>(
|
||||||
haystack: &'a Buffer<u8, Error = E>,
|
haystack: &B,
|
||||||
) -> Result<(Superblock, usize), Error>
|
) -> Result<(Superblock, usize), Error>
|
||||||
where
|
where
|
||||||
Error: From<E>,
|
Error: From<B::Error>,
|
||||||
{
|
{
|
||||||
let offset = 1024;
|
let offset = 1024;
|
||||||
let end = offset + mem::size_of::<Superblock>();
|
let end = offset + mem::size_of::<Superblock>();
|
||||||
|
|
Reference in a new issue