WIP hacks to enable no_std and no alloc
This commit is contained in:
parent
2f053855d5
commit
7b8f1095d4
|
@ -20,3 +20,10 @@ mp4parse = "0.8"
|
|||
ogg = "0.5.1"
|
||||
time = "0.1"
|
||||
walkdir = "1.0"
|
||||
|
||||
[dependencies]
|
||||
genio = { version = "0.2", optional = true, default-features = false }
|
||||
heapless = { version = "0.5", optional = true, default-features = false }
|
||||
|
||||
[features]
|
||||
nostd = ["genio", "heapless"]
|
||||
|
|
22
src/crc.rs
22
src/crc.rs
|
@ -5,7 +5,13 @@
|
|||
// you may not use this file except in compliance with the License.
|
||||
// A copy of the License has been included in the root of the repository.
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
use std::io;
|
||||
#[cfg(feature = "nostd")]
|
||||
use genio as io;
|
||||
|
||||
use crate::error::io_Result;
|
||||
|
||||
use input::ReadBytes;
|
||||
|
||||
// These tables were taken from the tables in crc.c in libflac.
|
||||
|
@ -114,7 +120,7 @@ impl<R: ReadBytes> Crc16Reader<R> {
|
|||
|
||||
impl<R: ReadBytes> ReadBytes for Crc8Reader<R> {
|
||||
#[inline(always)]
|
||||
fn read_u8(&mut self) -> io::Result<u8> {
|
||||
fn read_u8(&mut self) -> io_Result<u8> {
|
||||
match self.inner.read_u8() {
|
||||
Ok(byte) => {
|
||||
self.update_state(byte);
|
||||
|
@ -124,7 +130,7 @@ impl<R: ReadBytes> ReadBytes for Crc8Reader<R> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>> {
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>> {
|
||||
match self.inner.read_u8_or_eof() {
|
||||
Ok(Some(byte)) => {
|
||||
self.update_state(byte);
|
||||
|
@ -135,18 +141,18 @@ impl<R: ReadBytes> ReadBytes for Crc8Reader<R> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_into(&mut self, _buffer: &mut [u8]) -> io::Result<()> {
|
||||
fn read_into(&mut self, _buffer: &mut [u8]) -> io_Result<()> {
|
||||
panic!("CRC reader does not support read_into.");
|
||||
}
|
||||
|
||||
fn skip(&mut self, _amount: u32) -> io::Result<()> {
|
||||
fn skip(&mut self, _amount: u32) -> io_Result<()> {
|
||||
panic!("CRC reader does not support skip, it does not compute CRC over skipped data.");
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: ReadBytes> ReadBytes for Crc16Reader<R> {
|
||||
#[inline(always)]
|
||||
fn read_u8(&mut self) -> io::Result<u8> {
|
||||
fn read_u8(&mut self) -> io_Result<u8> {
|
||||
match self.inner.read_u8() {
|
||||
Ok(byte) => {
|
||||
self.update_state(byte);
|
||||
|
@ -156,7 +162,7 @@ impl<R: ReadBytes> ReadBytes for Crc16Reader<R> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>> {
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>> {
|
||||
match self.inner.read_u8_or_eof() {
|
||||
Ok(Some(byte)) => {
|
||||
self.update_state(byte);
|
||||
|
@ -167,11 +173,11 @@ impl<R: ReadBytes> ReadBytes for Crc16Reader<R> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_into(&mut self, _buffer: &mut [u8]) -> io::Result<()> {
|
||||
fn read_into(&mut self, _buffer: &mut [u8]) -> io_Result<()> {
|
||||
panic!("CRC reader does not support read_into.");
|
||||
}
|
||||
|
||||
fn skip(&mut self, _amount: u32) -> io::Result<()> {
|
||||
fn skip(&mut self, _amount: u32) -> io_Result<()> {
|
||||
panic!("CRC reader does not support skip, it does not compute CRC over skipped data.");
|
||||
}
|
||||
}
|
||||
|
|
37
src/error.rs
37
src/error.rs
|
@ -7,17 +7,26 @@
|
|||
|
||||
//! The `error` module defines the error and result types.
|
||||
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::result;
|
||||
use std::string;
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
use std::{error, io, string};
|
||||
#[cfg(feature = "nostd")]
|
||||
use genio as io;
|
||||
|
||||
use core::fmt;
|
||||
use core::result;
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
pub type io_Error = io::Error;
|
||||
#[cfg(feature = "nostd")]
|
||||
pub type io_Error = &'static str;
|
||||
|
||||
pub type io_Result<T> = core::result::Result<T, io_Error>;
|
||||
|
||||
/// An error that prevents successful decoding of the FLAC stream.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Not a decoding error, but a problem with the underlying IO.
|
||||
IoError(io::Error),
|
||||
IoError(io_Error),
|
||||
|
||||
/// An ill-formed FLAC stream was encountered.
|
||||
FormatError(&'static str),
|
||||
|
@ -44,6 +53,7 @@ impl PartialEq for Error {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
|
||||
match *self {
|
||||
|
@ -61,6 +71,7 @@ impl fmt::Display for Error {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
|
@ -79,12 +90,13 @@ impl error::Error for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Error {
|
||||
impl From<io_Error> for Error {
|
||||
fn from(err: io_Error) -> Error {
|
||||
Error::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
impl From<string::FromUtf8Error> for Error {
|
||||
fn from(_: string::FromUtf8Error) -> Error {
|
||||
// Vendor strings and Vorbis comments are the only place where UTF-8 is
|
||||
|
@ -92,6 +104,15 @@ impl From<string::FromUtf8Error> for Error {
|
|||
Error::FormatError("Vorbis comment or vendor string is not valid UTF-8")
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "nostd")]
|
||||
impl From<core::str::Utf8Error> for Error {
|
||||
fn from(_: core::str::Utf8Error) -> Error {
|
||||
// Vendor strings and Vorbis comments are the only place where UTF-8 is
|
||||
// parsed into a String.
|
||||
Error::FormatError("Vorbis comment or vendor string is not valid UTF-8")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A type for results generated by Claxon where the error type is hard-wired.
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
|
19
src/frame.rs
19
src/frame.rs
|
@ -7,8 +7,13 @@
|
|||
|
||||
//! The `frame` module deals with the frames that make up a FLAC stream.
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
use std::i32;
|
||||
|
||||
#[cfg(feature = "nostd")]
|
||||
type Vec<T> = heapless::Vec<T, heapless::consts::U256>; // TODO: wat size???
|
||||
//use heapless::Vec;
|
||||
|
||||
use crc::{Crc8Reader, Crc16Reader};
|
||||
use error::{Error, Result, fmt_err};
|
||||
use input::{Bitstream, ReadBytes};
|
||||
|
@ -416,7 +421,7 @@ impl Block {
|
|||
first_sample_number: time,
|
||||
block_size: bs,
|
||||
channels: buffer.len() as u32 / bs,
|
||||
buffer: buffer,
|
||||
buffer,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,7 +431,7 @@ impl Block {
|
|||
first_sample_number: 0,
|
||||
block_size: 0,
|
||||
channels: 0,
|
||||
buffer: Vec::with_capacity(0),
|
||||
buffer: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,6 +618,7 @@ pub type FrameResult = Result<Option<Block>>;
|
|||
/// be anything, it is assumed they will be overwritten anyway.
|
||||
///
|
||||
/// To use this function safely, the caller must overwrite all `new_len` bytes.
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
fn ensure_buffer_len(mut buffer: Vec<i32>, new_len: usize) -> Vec<i32> {
|
||||
if buffer.len() < new_len {
|
||||
// Previous data will be overwritten, so instead of resizing the
|
||||
|
@ -635,6 +641,15 @@ fn ensure_buffer_len(mut buffer: Vec<i32>, new_len: usize) -> Vec<i32> {
|
|||
}
|
||||
buffer
|
||||
}
|
||||
#[cfg(feature = "nostd")]
|
||||
fn ensure_buffer_len(mut buffer: Vec<i32>, new_len: usize) -> Vec<i32> {
|
||||
if buffer.len() < new_len {
|
||||
buffer.resize(new_len, 0);
|
||||
} else {
|
||||
buffer.truncate(new_len);
|
||||
}
|
||||
buffer
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_buffer_len_returns_buffer_with_new_len() {
|
||||
|
|
118
src/input.rs
118
src/input.rs
|
@ -12,8 +12,15 @@
|
|||
//! checksumming of the data read. There is also a bitstream which is used
|
||||
//! internally to read the bitstream.
|
||||
|
||||
use std::cmp;
|
||||
use core::cmp;
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
use std::io;
|
||||
#[cfg(feature = "nostd")]
|
||||
use genio as io;
|
||||
#[cfg(feature = "nostd")]
|
||||
use heapless::Vec;
|
||||
use error::{io_Result, io_Error};
|
||||
|
||||
/// Similar to `std::io::BufRead`, but more performant.
|
||||
///
|
||||
|
@ -26,7 +33,10 @@ pub struct BufferedReader<R: io::Read> {
|
|||
inner: R,
|
||||
|
||||
/// The buffer that holds data read from the inner reader.
|
||||
buf: Box<[u8]>,
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
buf: Vec<u8>,
|
||||
#[cfg(feature = "nostd")]
|
||||
buf: Vec<u8, heapless::consts::U256>,
|
||||
|
||||
/// The index of the first byte in the buffer which has not been consumed.
|
||||
pos: u32,
|
||||
|
@ -36,20 +46,22 @@ pub struct BufferedReader<R: io::Read> {
|
|||
}
|
||||
|
||||
impl<R: io::Read> BufferedReader<R> {
|
||||
|
||||
/// Wrap the reader in a new buffered reader.
|
||||
pub fn new(inner: R) -> BufferedReader<R> {
|
||||
// Use a large-ish buffer size, such that system call overhead is
|
||||
// negligible when replenishing the buffer. However, when fuzzing we
|
||||
// want to have small samples, and still trigger the case where we have
|
||||
// to replenish the buffer, so use a smaller buffer size there.
|
||||
#[cfg(not(fuzzing))]
|
||||
#[cfg(all(not(fuzzing), not(feature = "nostd")))]
|
||||
const CAPACITY: usize = 2048;
|
||||
|
||||
#[cfg(all(not(fuzzing), feature = "nostd"))]
|
||||
const CAPACITY: usize = 256;
|
||||
|
||||
#[cfg(fuzzing)]
|
||||
const CAPACITY: usize = 31;
|
||||
|
||||
let buf = vec![0; CAPACITY].into_boxed_slice();
|
||||
let buf = Vec::from_slice(&[0; CAPACITY]).unwrap();
|
||||
BufferedReader {
|
||||
inner: inner,
|
||||
buf: buf,
|
||||
|
@ -70,28 +82,28 @@ impl<R: io::Read> BufferedReader<R> {
|
|||
/// Provides convenience methods to make input less cumbersome.
|
||||
pub trait ReadBytes {
|
||||
/// Reads a single byte, failing on EOF.
|
||||
fn read_u8(&mut self) -> io::Result<u8>;
|
||||
fn read_u8(&mut self) -> io_Result<u8>;
|
||||
|
||||
/// Reads a single byte, not failing on EOF.
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>>;
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>>;
|
||||
|
||||
/// Reads until the provided buffer is full.
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io::Result<()>;
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io_Result<()>;
|
||||
|
||||
/// Skips over the specified number of bytes.
|
||||
///
|
||||
/// For a buffered reader, this can help a lot by just bumping a pointer.
|
||||
fn skip(&mut self, amount: u32) -> io::Result<()>;
|
||||
fn skip(&mut self, amount: u32) -> io_Result<()>;
|
||||
|
||||
/// Reads two bytes and interprets them as a big-endian 16-bit unsigned integer.
|
||||
fn read_be_u16(&mut self) -> io::Result<u16> {
|
||||
fn read_be_u16(&mut self) -> io_Result<u16> {
|
||||
let b0 = try!(self.read_u8()) as u16;
|
||||
let b1 = try!(self.read_u8()) as u16;
|
||||
Ok(b0 << 8 | b1)
|
||||
}
|
||||
|
||||
/// Reads two bytes and interprets them as a big-endian 16-bit unsigned integer.
|
||||
fn read_be_u16_or_eof(&mut self) -> io::Result<Option<u16>> {
|
||||
fn read_be_u16_or_eof(&mut self) -> io_Result<Option<u16>> {
|
||||
if let Some(b0) = try!(self.read_u8_or_eof()) {
|
||||
if let Some(b1) = try!(self.read_u8_or_eof()) {
|
||||
return Ok(Some((b0 as u16) << 8 | (b1 as u16)));
|
||||
|
@ -101,7 +113,7 @@ pub trait ReadBytes {
|
|||
}
|
||||
|
||||
/// Reads three bytes and interprets them as a big-endian 24-bit unsigned integer.
|
||||
fn read_be_u24(&mut self) -> io::Result<u32> {
|
||||
fn read_be_u24(&mut self) -> io_Result<u32> {
|
||||
let b0 = try!(self.read_u8()) as u32;
|
||||
let b1 = try!(self.read_u8()) as u32;
|
||||
let b2 = try!(self.read_u8()) as u32;
|
||||
|
@ -109,7 +121,7 @@ pub trait ReadBytes {
|
|||
}
|
||||
|
||||
/// Reads four bytes and interprets them as a big-endian 32-bit unsigned integer.
|
||||
fn read_be_u32(&mut self) -> io::Result<u32> {
|
||||
fn read_be_u32(&mut self) -> io_Result<u32> {
|
||||
let b0 = try!(self.read_u8()) as u32;
|
||||
let b1 = try!(self.read_u8()) as u32;
|
||||
let b2 = try!(self.read_u8()) as u32;
|
||||
|
@ -118,7 +130,7 @@ pub trait ReadBytes {
|
|||
}
|
||||
|
||||
/// Reads four bytes and interprets them as a little-endian 32-bit unsigned integer.
|
||||
fn read_le_u32(&mut self) -> io::Result<u32> {
|
||||
fn read_le_u32(&mut self) -> io_Result<u32> {
|
||||
let b0 = try!(self.read_u8()) as u32;
|
||||
let b1 = try!(self.read_u8()) as u32;
|
||||
let b2 = try!(self.read_u8()) as u32;
|
||||
|
@ -127,18 +139,20 @@ pub trait ReadBytes {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: io::Read> ReadBytes for BufferedReader<R>
|
||||
{
|
||||
impl<R: io::Read> ReadBytes for BufferedReader<R> {
|
||||
#[inline(always)]
|
||||
fn read_u8(&mut self) -> io::Result<u8> {
|
||||
fn read_u8(&mut self) -> io_Result<u8> {
|
||||
if self.pos == self.num_valid {
|
||||
// The buffer was depleted, replenish it first.
|
||||
self.pos = 0;
|
||||
self.num_valid = try!(self.inner.read(&mut self.buf)) as u32;
|
||||
self.num_valid = self.inner.read(&mut self.buf).map_err(|_| "read_u8")? as u32;
|
||||
|
||||
if self.num_valid == 0 {
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
||||
"Expected one more byte."))
|
||||
"Expected one more byte."));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("Expected one more byte.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,11 +164,11 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
Ok(byte)
|
||||
}
|
||||
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>> {
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>> {
|
||||
if self.pos == self.num_valid {
|
||||
// The buffer was depleted, try to replenish it first.
|
||||
self.pos = 0;
|
||||
self.num_valid = try!(self.inner.read(&mut self.buf)) as u32;
|
||||
self.num_valid = self.inner.read(&mut self.buf).map_err(|_| "read_u8_or_eof")? as u32;
|
||||
|
||||
if self.num_valid == 0 {
|
||||
return Ok(None);
|
||||
|
@ -164,7 +178,7 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
Ok(Some(try!(self.read_u8())))
|
||||
}
|
||||
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io::Result<()> {
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io_Result<()> {
|
||||
let mut bytes_left = buffer.len();
|
||||
|
||||
while bytes_left > 0 {
|
||||
|
@ -178,10 +192,13 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
if bytes_left > 0 {
|
||||
// Replenish the buffer if there is more to be read.
|
||||
self.pos = 0;
|
||||
self.num_valid = try!(self.inner.read(&mut self.buf)) as u32;
|
||||
self.num_valid = self.inner.read(&mut self.buf).map_err(|_| "read_into")? as u32;
|
||||
if self.num_valid == 0 {
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
||||
"Expected more bytes."))
|
||||
"Expected more bytes."));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("Expected more bytes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +206,7 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn skip(&mut self, mut amount: u32) -> io::Result<()> {
|
||||
fn skip(&mut self, mut amount: u32) -> io_Result<()> {
|
||||
while amount > 0 {
|
||||
let num_left = self.num_valid - self.pos;
|
||||
let read_now = cmp::min(amount, num_left);
|
||||
|
@ -199,11 +216,14 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
if amount > 0 {
|
||||
// If there is more to skip, refill the buffer first.
|
||||
self.pos = 0;
|
||||
self.num_valid = try!(self.inner.read(&mut self.buf)) as u32;
|
||||
self.num_valid = self.inner.read(&mut self.buf).map_err(|_| "skip")? as u32;
|
||||
|
||||
if self.num_valid == 0 {
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof,
|
||||
"Expected more bytes."))
|
||||
"Expected more bytes."));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("Expected more bytes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,36 +234,40 @@ impl<R: io::Read> ReadBytes for BufferedReader<R>
|
|||
impl<'r, R: ReadBytes> ReadBytes for &'r mut R {
|
||||
|
||||
#[inline(always)]
|
||||
fn read_u8(&mut self) -> io::Result<u8> {
|
||||
fn read_u8(&mut self) -> io_Result<u8> {
|
||||
(*self).read_u8()
|
||||
}
|
||||
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>> {
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>> {
|
||||
(*self).read_u8_or_eof()
|
||||
}
|
||||
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io::Result<()> {
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io_Result<()> {
|
||||
(*self).read_into(buffer)
|
||||
}
|
||||
|
||||
fn skip(&mut self, amount: u32) -> io::Result<()> {
|
||||
fn skip(&mut self, amount: u32) -> io_Result<()> {
|
||||
(*self).skip(amount)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
impl<T: AsRef<[u8]>> ReadBytes for io::Cursor<T> {
|
||||
|
||||
fn read_u8(&mut self) -> io::Result<u8> {
|
||||
fn read_u8(&mut self) -> io_Result<u8> {
|
||||
let pos = self.position();
|
||||
if pos < self.get_ref().as_ref().len() as u64 {
|
||||
self.set_position(pos + 1);
|
||||
Ok(self.get_ref().as_ref()[pos as usize])
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"))
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("unexpected eof");
|
||||
}
|
||||
}
|
||||
|
||||
fn read_u8_or_eof(&mut self) -> io::Result<Option<u8>> {
|
||||
fn read_u8_or_eof(&mut self) -> io_Result<Option<u8>> {
|
||||
let pos = self.position();
|
||||
if pos < self.get_ref().as_ref().len() as u64 {
|
||||
self.set_position(pos + 1);
|
||||
|
@ -253,7 +277,7 @@ impl<T: AsRef<[u8]>> ReadBytes for io::Cursor<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io::Result<()> {
|
||||
fn read_into(&mut self, buffer: &mut [u8]) -> io_Result<()> {
|
||||
let pos = self.position();
|
||||
if pos + buffer.len() as u64 <= self.get_ref().as_ref().len() as u64 {
|
||||
let start = pos as usize;
|
||||
|
@ -262,17 +286,23 @@ impl<T: AsRef<[u8]>> ReadBytes for io::Cursor<T> {
|
|||
self.set_position(pos + buffer.len() as u64);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"))
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("unexpected eof");
|
||||
}
|
||||
}
|
||||
|
||||
fn skip(&mut self, amount: u32) -> io::Result<()> {
|
||||
fn skip(&mut self, amount: u32) -> io_Result<()> {
|
||||
let pos = self.position();
|
||||
if pos + amount as u64 <= self.get_ref().as_ref().len() as u64 {
|
||||
self.set_position(pos + amount as u64);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"))
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof"));
|
||||
#[cfg(feature = "nostd")]
|
||||
return Err("unexpected eof");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +474,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
/// Reading a single bit can be done more efficiently than reading
|
||||
/// more than one bit, because a bit never straddles a byte boundary.
|
||||
#[inline(always)]
|
||||
pub fn read_bit(&mut self) -> io::Result<bool> {
|
||||
pub fn read_bit(&mut self) -> io_Result<bool> {
|
||||
|
||||
// If no bits are left, we will need to read the next byte.
|
||||
let result = if self.bits_left == 0 {
|
||||
|
@ -472,7 +502,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
/// Because the reader buffers a byte internally, reading unary can be done
|
||||
/// more efficiently than by just reading bit by bit.
|
||||
#[inline(always)]
|
||||
pub fn read_unary(&mut self) -> io::Result<u32> {
|
||||
pub fn read_unary(&mut self) -> io_Result<u32> {
|
||||
// Start initially with the number of zeros that are in the buffer byte
|
||||
// already (counting from the most significant bit).
|
||||
let mut n = self.data.leading_zeros();
|
||||
|
@ -512,7 +542,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
|
||||
/// Reads at most eight bits.
|
||||
#[inline(always)]
|
||||
pub fn read_leq_u8(&mut self, bits: u32) -> io::Result<u8> {
|
||||
pub fn read_leq_u8(&mut self, bits: u32) -> io_Result<u8> {
|
||||
// Of course we can read no more than 8 bits, but we do not want the
|
||||
// performance overhead of the assertion, so only do it in debug mode.
|
||||
debug_assert!(bits <= 8);
|
||||
|
@ -559,7 +589,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
|
||||
/// Read n bits, where 8 < n <= 16.
|
||||
#[inline(always)]
|
||||
pub fn read_gt_u8_leq_u16(&mut self, bits: u32) -> io::Result<u32> {
|
||||
pub fn read_gt_u8_leq_u16(&mut self, bits: u32) -> io_Result<u32> {
|
||||
debug_assert!((8 < bits) && (bits <= 16));
|
||||
|
||||
// The most significant bits of the current byte are valid. Shift them
|
||||
|
@ -603,7 +633,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
|
||||
/// Reads at most 16 bits.
|
||||
#[inline(always)]
|
||||
pub fn read_leq_u16(&mut self, bits: u32) -> io::Result<u16> {
|
||||
pub fn read_leq_u16(&mut self, bits: u32) -> io_Result<u16> {
|
||||
// As with read_leq_u8, this only makes sense if we read <= 16 bits.
|
||||
debug_assert!(bits <= 16);
|
||||
|
||||
|
@ -623,7 +653,7 @@ impl<R: ReadBytes> Bitstream<R> {
|
|||
|
||||
/// Reads at most 32 bits.
|
||||
#[inline(always)]
|
||||
pub fn read_leq_u32(&mut self, bits: u32) -> io::Result<u32> {
|
||||
pub fn read_leq_u32(&mut self, bits: u32) -> io_Result<u32> {
|
||||
// As with read_leq_u8, this only makes sense if we read <= 32 bits.
|
||||
debug_assert!(bits <= 32);
|
||||
|
||||
|
|
15
src/lib.rs
15
src/lib.rs
|
@ -68,10 +68,16 @@
|
|||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::path;
|
||||
#![cfg_attr(feature = "nostd", no_std)]
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
pub use std::{fs, io, path};
|
||||
|
||||
#[cfg(feature = "nostd")] extern crate genio;
|
||||
#[cfg(feature = "nostd")] extern crate heapless;
|
||||
#[cfg(feature = "nostd")] use genio as io;
|
||||
|
||||
use core::mem;
|
||||
use error::fmt_err;
|
||||
use frame::FrameReader;
|
||||
use input::{BufferedReader, ReadBytes};
|
||||
|
@ -419,6 +425,7 @@ impl<R: io::Read> FlacReader<R> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
impl FlacReader<fs::File> {
|
||||
/// Attempts to create a reader that reads from the specified file.
|
||||
///
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
|
||||
use error::{Error, Result, fmt_err};
|
||||
use input::ReadBytes;
|
||||
use std::str;
|
||||
use std::slice;
|
||||
use core::str;
|
||||
use core::slice;
|
||||
|
||||
#[cfg(feature = "nostd")]
|
||||
type String = heapless::String<heapless::consts::U256>;
|
||||
#[cfg(feature = "nostd")]
|
||||
type Vec<T> = heapless::Vec<T, heapless::consts::U256>; // TODO: wat sizes
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct MetadataBlockHeader {
|
||||
|
@ -195,7 +200,7 @@ impl<'a> Iterator for GetTag<'a> {
|
|||
fn next(&mut self) -> Option<&'a str> {
|
||||
// This import is actually required on Rust 1.13.
|
||||
#[allow(unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
//use std::ascii::AsciiExt;
|
||||
|
||||
while self.index < self.vorbis_comments.len() {
|
||||
let (ref comment, sep_idx) = self.vorbis_comments[self.index];
|
||||
|
@ -429,6 +434,9 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
|
|||
// 32-bit vendor string length, and comment count.
|
||||
let vendor_len = try!(input.read_le_u32());
|
||||
if vendor_len > length - 8 { return fmt_err("vendor string too long") }
|
||||
#[cfg(feature = "nostd")]
|
||||
let mut vendor_bytes = Vec::new();
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
let mut vendor_bytes = Vec::with_capacity(vendor_len as usize);
|
||||
|
||||
// We can safely set the lenght of the vector here; the uninitialized memory
|
||||
|
@ -446,6 +454,9 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
|
|||
if comments_len >= length / 4 {
|
||||
return fmt_err("too many entries for Vorbis comment block")
|
||||
}
|
||||
#[cfg(feature = "nostd")]
|
||||
let mut comments = Vec::new();
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
let mut comments = Vec::with_capacity(comments_len as usize);
|
||||
|
||||
let mut bytes_left = length - 8 - vendor_len;
|
||||
|
@ -470,6 +481,9 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
|
|||
}
|
||||
|
||||
// For the same reason as above, setting the length is safe here.
|
||||
#[cfg(feature = "nostd")]
|
||||
let mut comment_bytes = Vec::new();
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
let mut comment_bytes = Vec::with_capacity(comment_len as usize);
|
||||
unsafe { comment_bytes.set_len(comment_len as usize); }
|
||||
try!(input.read_into(&mut comment_bytes));
|
||||
|
@ -541,6 +555,9 @@ fn read_application_block<R: ReadBytes>(input: &mut R, length: u32) -> Result<(u
|
|||
// uninitialized memory is never exposed: read_into will either fill the
|
||||
// buffer completely, or return an err, in which case the memory is not
|
||||
// exposed.
|
||||
#[cfg(feature = "nostd")]
|
||||
let mut data = Vec::new();
|
||||
#[cfg(not(feature = "nostd"))]
|
||||
let mut data = Vec::with_capacity(length as usize - 4);
|
||||
unsafe { data.set_len(length as usize - 4); }
|
||||
try!(input.read_into(&mut data));
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
//! The `subframe` module deals with subframes that make up a frame of the FLAC stream.
|
||||
|
||||
use std::cmp;
|
||||
use std::num;
|
||||
use core::cmp;
|
||||
use core::num;
|
||||
use error::{Error, Result, fmt_err};
|
||||
use input::{Bitstream, ReadBytes};
|
||||
|
||||
|
|
Loading…
Reference in New Issue