cbor/
slice.rs

1// This Source Code Form is subject to the terms of
2// the Mozilla Public License, v. 2.0. If a copy of
3// the MPL was not distributed with this file, You
4// can obtain one at http://mozilla.org/MPL/2.0/.
5
6//! `ReadSlice` trait to allow efficient reading of slices without copying.
7
8use std::error::Error;
9use std::fmt;
10use std::io::{self, Cursor};
11
12/// Type which supports reading a slice of bytes.
13pub trait ReadSlice {
14    fn read_slice(&mut self, n: usize) -> Result<&[u8], ReadSliceError>;
15}
16
17impl ReadSlice for Cursor<Vec<u8>> {
18    fn read_slice(&mut self, n: usize) -> Result<&[u8], ReadSliceError> {
19        let start = self.position() as usize;
20        if self.get_ref().len() - start < n {
21            return Err(ReadSliceError::InsufficientData)
22        }
23        self.set_position((start + n) as u64);
24        Ok(&self.get_ref()[start .. start + n])
25    }
26}
27
28impl<'r> ReadSlice for Cursor<&'r [u8]> {
29    fn read_slice(&mut self, n: usize) -> Result<&[u8], ReadSliceError> {
30        let start = self.position() as usize;
31        if self.get_ref().len() - start < n {
32            return Err(ReadSliceError::InsufficientData)
33        }
34        self.set_position((start + n) as u64);
35        Ok(&self.get_ref()[start .. start + n])
36    }
37}
38
39#[derive(Debug)]
40pub enum ReadSliceError {
41    IoError(io::Error),
42    InsufficientData
43}
44
45impl fmt::Display for ReadSliceError {
46    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
47        match *self {
48            ReadSliceError::IoError(ref e)   => write!(f, "ReadSliceError: I/O error: {}", *e),
49            ReadSliceError::InsufficientData => write!(f, "ReadSliceError: not enough data available")
50        }
51    }
52}
53
54impl Error for ReadSliceError {
55    fn description(&self) -> &str {
56        "ReadSliceError"
57    }
58
59    fn cause(&self) -> Option<&Error> {
60        match *self {
61            ReadSliceError::IoError(ref e) => Some(e),
62            _                              => None
63        }
64    }
65}