mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-05-23 20:51:33 +00:00
Introduce io module
This commit is contained in:
parent
bfa0b6c156
commit
eec09f24f3
@ -1,6 +1,6 @@
|
|||||||
use std::io;
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use super::{Deserialize, Serialize, Error, VarUint7, VarUint32};
|
use super::{Deserialize, Serialize, Error, VarUint7, VarUint32};
|
||||||
|
use io;
|
||||||
|
|
||||||
/// Internal reference of the exported entry.
|
/// Internal reference of the exported entry.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use super::{
|
use super::{
|
||||||
Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes,
|
Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use super::{Deserialize, Serialize, Error, GlobalType, InitExpr};
|
use super::{Deserialize, Serialize, Error, GlobalType, InitExpr};
|
||||||
|
|
||||||
/// Global entry in the module.
|
/// Global entry in the module.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use super::{
|
use super::{
|
||||||
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1,
|
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::iter::{FromIterator, IntoIterator};
|
use std::iter::{FromIterator, IntoIterator};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
use io;
|
||||||
|
|
||||||
use super::{Deserialize, Error, Serialize, VarUint32};
|
use super::{Deserialize, Error, Serialize, VarUint32};
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ impl<T> IndexMap<T> {
|
|||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<IndexMap<T>, Error>
|
) -> Result<IndexMap<T>, Error>
|
||||||
where
|
where
|
||||||
R: Read,
|
R: io::Read,
|
||||||
F: Fn(u32, &mut R) -> Result<T, Error>,
|
F: Fn(u32, &mut R) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
let len: u32 = VarUint32::deserialize(rdr)?.into();
|
let len: u32 = VarUint32::deserialize(rdr)?.into();
|
||||||
@ -326,7 +326,7 @@ where
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Self::Error> {
|
||||||
VarUint32::from(self.len()).serialize(wtr)?;
|
VarUint32::from(self.len()).serialize(wtr)?;
|
||||||
for (idx, value) in self {
|
for (idx, value) in self {
|
||||||
VarUint32::from(idx).serialize(wtr)?;
|
VarUint32::from(idx).serialize(wtr)?;
|
||||||
@ -344,7 +344,7 @@ where
|
|||||||
/// Deserialize a map containing simple values that support `Deserialize`.
|
/// Deserialize a map containing simple values that support `Deserialize`.
|
||||||
/// We will allocate an underlying array no larger than `max_entry_space` to
|
/// We will allocate an underlying array no larger than `max_entry_space` to
|
||||||
/// hold the data, so the maximum index must be less than `max_entry_space`.
|
/// hold the data, so the maximum index must be less than `max_entry_space`.
|
||||||
pub fn deserialize<R: Read>(
|
pub fn deserialize<R: io::Read>(
|
||||||
max_entry_space: usize,
|
max_entry_space: usize,
|
||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
@ -357,7 +357,7 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::io;
|
use io;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
//! Elements of the WebAssembly binary format.
|
//! Elements of the WebAssembly binary format.
|
||||||
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ macro_rules! buffered_read {
|
|||||||
let mut buf = [0u8; $buffer_size];
|
let mut buf = [0u8; $buffer_size];
|
||||||
while total_read < $length {
|
while total_read < $length {
|
||||||
let next_to_read = if $length - total_read > $buffer_size { $buffer_size } else { $length - total_read };
|
let next_to_read = if $length - total_read > $buffer_size { $buffer_size } else { $length - total_read };
|
||||||
$reader.read_exact(&mut buf[0..next_to_read])?;
|
$reader.read(&mut buf[0..next_to_read])?;
|
||||||
vec_buf.extend_from_slice(&buf[0..next_to_read]);
|
vec_buf.extend_from_slice(&buf[0..next_to_read]);
|
||||||
total_read += next_to_read;
|
total_read += next_to_read;
|
||||||
}
|
}
|
||||||
@ -177,7 +176,8 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for Error {
|
#[cfg(feature = "std")]
|
||||||
|
impl ::std::error::Error for Error {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Error::UnexpectedEof => "Unexpected end of input",
|
Error::UnexpectedEof => "Unexpected end of input",
|
||||||
@ -212,7 +212,7 @@ impl error::Error for Error {
|
|||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(err: io::Error) -> Self {
|
fn from(err: io::Error) -> Self {
|
||||||
Error::HeapOther(format!("I/O Error: {}", err))
|
Error::HeapOther(format!("I/O Error: {:?}", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ impl Deserialize for Unparsed {
|
|||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let len = VarUint32::deserialize(reader)?.into();
|
let len = VarUint32::deserialize(reader)?.into();
|
||||||
let mut vec = vec![0u8; len];
|
let mut vec = vec![0u8; len];
|
||||||
reader.read_exact(&mut vec[..])?;
|
reader.read(&mut vec[..])?;
|
||||||
Ok(Unparsed(vec))
|
Ok(Unparsed(vec))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,22 +236,14 @@ impl From<Unparsed> for Vec<u8> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize module from file.
|
|
||||||
pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
let mut contents = Vec::new();
|
|
||||||
::std::fs::File::open(p)?.read_to_end(&mut contents)?;
|
|
||||||
|
|
||||||
deserialize_buffer(&contents)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deserialize deserializable type from buffer.
|
/// Deserialize deserializable type from buffer.
|
||||||
pub fn deserialize_buffer<T: Deserialize>(contents: &[u8]) -> Result<T, T::Error> {
|
pub fn deserialize_buffer<T: Deserialize>(contents: &[u8]) -> Result<T, T::Error> {
|
||||||
let mut reader = io::Cursor::new(contents);
|
let mut reader = io::Cursor::new(contents);
|
||||||
let result = T::deserialize(&mut reader)?;
|
let result = T::deserialize(&mut reader)?;
|
||||||
if reader.position() != contents.len() as u64 {
|
if reader.position() != contents.len() {
|
||||||
return Err(io::Error::from(io::ErrorKind::InvalidData).into())
|
// It's a TrailingData, since if there is not enough data then
|
||||||
|
// UnexpectedEof must have been returned earlier in T::deserialize.
|
||||||
|
return Err(io::Error::TrailingData.into())
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@ -263,9 +255,33 @@ pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> {
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize module to the file
|
/// Deserialize module from file.
|
||||||
pub fn serialize_to_file<P: AsRef<::std::path::Path>>(p: P, module: Module) -> Result<(), Error>
|
#[cfg(feature = "std")]
|
||||||
{
|
pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
|
||||||
let mut io = ::std::fs::File::create(p)?;
|
use std::io::Read;
|
||||||
module.serialize(&mut io)
|
|
||||||
|
let mut contents = Vec::new();
|
||||||
|
|
||||||
|
::std::fs::File::open(p)
|
||||||
|
.and_then(|mut f| f.read_to_end(&mut contents))
|
||||||
|
.map_err(|e| Error::HeapOther(format!("Can't read from the file: {:?}", e)))?;
|
||||||
|
|
||||||
|
deserialize_buffer(&contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serialize module to the file
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn serialize_to_file<P: AsRef<::std::path::Path>>(p: P, module: Module) -> Result<(), Error> {
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
let mut io = ::std::fs::File::create(p)
|
||||||
|
.map_err(|e| Error::HeapOther(format!("Can't create the file: {:?}", e)))?;
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
|
module.serialize(&mut buf)?;
|
||||||
|
|
||||||
|
io.write_all(&buf)
|
||||||
|
.map_err(|e| Error::HeapOther(format!("Can't write to the file: {:?}", e)))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use byteorder::{LittleEndian, ByteOrder};
|
use byteorder::{LittleEndian, ByteOrder};
|
||||||
|
|
||||||
@ -310,8 +310,8 @@ impl Module {
|
|||||||
Ok(reloc_section) => reloc_section,
|
Ok(reloc_section) => reloc_section,
|
||||||
Err(e) => { parse_errors.push((i, e)); continue; }
|
Err(e) => { parse_errors.push((i, e)); continue; }
|
||||||
};
|
};
|
||||||
if rdr.position() != custom.payload().len() as u64 {
|
if rdr.position() != custom.payload().len() {
|
||||||
parse_errors.push((i, io::Error::from(io::ErrorKind::InvalidData).into()));
|
parse_errors.push((i, io::Error::InvalidData.into()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Some(Section::Reloc(reloc_section))
|
Some(Section::Reloc(reloc_section))
|
||||||
@ -448,17 +448,17 @@ struct PeekSection<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> io::Read for PeekSection<'a> {
|
impl<'a> io::Read for PeekSection<'a> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||||
let available = ::std::cmp::min(buf.len(), self.region.len() - self.cursor);
|
let available = ::std::cmp::min(buf.len(), self.region.len() - self.cursor);
|
||||||
if available < buf.len() {
|
if available < buf.len() {
|
||||||
return Err(::std::io::Error::from(::std::io::ErrorKind::UnexpectedEof));
|
return Err(io::Error::UnexpectedEof);
|
||||||
}
|
}
|
||||||
|
|
||||||
let range = self.cursor..self.cursor + buf.len();
|
let range = self.cursor..self.cursor + buf.len();
|
||||||
buf.copy_from_slice(&self.region[range]);
|
buf.copy_from_slice(&self.region[range]);
|
||||||
|
|
||||||
self.cursor += available;
|
self.cursor += available;
|
||||||
Ok(available)
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io::{Read, Write};
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ pub enum NameSection {
|
|||||||
|
|
||||||
impl NameSection {
|
impl NameSection {
|
||||||
/// Deserialize a name section.
|
/// Deserialize a name section.
|
||||||
pub fn deserialize<R: Read>(
|
pub fn deserialize<R: io::Read>(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<NameSection, Error> {
|
) -> Result<NameSection, Error> {
|
||||||
@ -44,7 +44,7 @@ impl NameSection {
|
|||||||
NAME_TYPE_LOCAL => NameSection::Local(LocalNameSection::deserialize(module, rdr)?),
|
NAME_TYPE_LOCAL => NameSection::Local(LocalNameSection::deserialize(module, rdr)?),
|
||||||
_ => {
|
_ => {
|
||||||
let mut name_payload = vec![0u8; name_payload_len as usize];
|
let mut name_payload = vec![0u8; name_payload_len as usize];
|
||||||
rdr.read_exact(&mut name_payload)?;
|
rdr.read(&mut name_payload)?;
|
||||||
NameSection::Unparsed {
|
NameSection::Unparsed {
|
||||||
name_type,
|
name_type,
|
||||||
name_payload,
|
name_payload,
|
||||||
@ -58,7 +58,7 @@ impl NameSection {
|
|||||||
impl Serialize for NameSection {
|
impl Serialize for NameSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
let (name_type, name_payload) = match self {
|
let (name_type, name_payload) = match self {
|
||||||
NameSection::Module(mod_name) => {
|
NameSection::Module(mod_name) => {
|
||||||
let mut buffer = vec![];
|
let mut buffer = vec![];
|
||||||
@ -82,7 +82,7 @@ impl Serialize for NameSection {
|
|||||||
};
|
};
|
||||||
VarUint7::from(name_type).serialize(wtr)?;
|
VarUint7::from(name_type).serialize(wtr)?;
|
||||||
VarUint32::from(name_payload.len()).serialize(wtr)?;
|
VarUint32::from(name_payload.len()).serialize(wtr)?;
|
||||||
wtr.write_all(&name_payload)?;
|
wtr.write(&name_payload)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ impl ModuleNameSection {
|
|||||||
impl Serialize for ModuleNameSection {
|
impl Serialize for ModuleNameSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
self.name.serialize(wtr)
|
self.name.serialize(wtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ impl Serialize for ModuleNameSection {
|
|||||||
impl Deserialize for ModuleNameSection {
|
impl Deserialize for ModuleNameSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn deserialize<R: Read>(rdr: &mut R) -> Result<ModuleNameSection, Error> {
|
fn deserialize<R: io::Read>(rdr: &mut R) -> Result<ModuleNameSection, Error> {
|
||||||
let name = String::deserialize(rdr)?;
|
let name = String::deserialize(rdr)?;
|
||||||
Ok(ModuleNameSection { name })
|
Ok(ModuleNameSection { name })
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ impl FunctionNameSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize names, making sure that all names correspond to functions.
|
/// Deserialize names, making sure that all names correspond to functions.
|
||||||
pub fn deserialize<R: Read>(
|
pub fn deserialize<R: io::Read>(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<FunctionNameSection, Error> {
|
) -> Result<FunctionNameSection, Error> {
|
||||||
@ -157,7 +157,7 @@ impl FunctionNameSection {
|
|||||||
impl Serialize for FunctionNameSection {
|
impl Serialize for FunctionNameSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
self.names.serialize(wtr)
|
self.names.serialize(wtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ impl LocalNameSection {
|
|||||||
|
|
||||||
/// Deserialize names, making sure that all names correspond to local
|
/// Deserialize names, making sure that all names correspond to local
|
||||||
/// variables.
|
/// variables.
|
||||||
pub fn deserialize<R: Read>(
|
pub fn deserialize<R: io::Read>(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<LocalNameSection, Error> {
|
) -> Result<LocalNameSection, Error> {
|
||||||
@ -221,7 +221,7 @@ impl LocalNameSection {
|
|||||||
impl Serialize for LocalNameSection {
|
impl Serialize for LocalNameSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
self.local_names.serialize(wtr)
|
self.local_names.serialize(wtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::{io, fmt};
|
use std::fmt;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
|
use io;
|
||||||
use super::{
|
use super::{
|
||||||
Serialize, Deserialize, Error,
|
Serialize, Deserialize, Error,
|
||||||
Uint8, VarUint32, CountedList, BlockType,
|
Uint8, VarUint32, CountedList, BlockType,
|
||||||
@ -613,7 +614,7 @@ impl Deserialize for Opcode {
|
|||||||
macro_rules! op {
|
macro_rules! op {
|
||||||
($writer: expr, $byte: expr) => ({
|
($writer: expr, $byte: expr) => ({
|
||||||
let b: u8 = $byte;
|
let b: u8 = $byte;
|
||||||
$writer.write_all(&[b])?;
|
$writer.write(&[b])?;
|
||||||
});
|
});
|
||||||
($writer: expr, $byte: expr, $s: block) => ({
|
($writer: expr, $byte: expr, $s: block) => ({
|
||||||
op!($writer, $byte);
|
op!($writer, $byte);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use byteorder::{LittleEndian, ByteOrder};
|
use byteorder::{LittleEndian, ByteOrder};
|
||||||
@ -44,7 +44,7 @@ impl Deserialize for VarUint32 {
|
|||||||
loop {
|
loop {
|
||||||
if shift > 31 { return Err(Error::InvalidVarUint32); }
|
if shift > 31 { return Err(Error::InvalidVarUint32); }
|
||||||
|
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
let b = u8buf[0] as u32;
|
let b = u8buf[0] as u32;
|
||||||
res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint32)?;
|
res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint32)?;
|
||||||
shift += 7;
|
shift += 7;
|
||||||
@ -71,7 +71,7 @@ impl Serialize for VarUint32 {
|
|||||||
if v > 0 {
|
if v > 0 {
|
||||||
buf[0] |= 0b1000_0000;
|
buf[0] |= 0b1000_0000;
|
||||||
}
|
}
|
||||||
writer.write_all(&buf[..])?;
|
writer.write(&buf[..])?;
|
||||||
if v == 0 { break; }
|
if v == 0 { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ impl Deserialize for VarUint64 {
|
|||||||
loop {
|
loop {
|
||||||
if shift > 63 { return Err(Error::InvalidVarUint64); }
|
if shift > 63 { return Err(Error::InvalidVarUint64); }
|
||||||
|
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
let b = u8buf[0] as u64;
|
let b = u8buf[0] as u64;
|
||||||
res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint64)?;
|
res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint64)?;
|
||||||
shift += 7;
|
shift += 7;
|
||||||
@ -127,7 +127,7 @@ impl Serialize for VarUint64 {
|
|||||||
if v > 0 {
|
if v > 0 {
|
||||||
buf[0] |= 0b1000_0000;
|
buf[0] |= 0b1000_0000;
|
||||||
}
|
}
|
||||||
writer.write_all(&buf[..])?;
|
writer.write(&buf[..])?;
|
||||||
if v == 0 { break; }
|
if v == 0 { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ impl Deserialize for VarUint7 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut u8buf = [0u8; 1];
|
let mut u8buf = [0u8; 1];
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
Ok(VarUint7(u8buf[0]))
|
Ok(VarUint7(u8buf[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ impl Serialize for VarUint7 {
|
|||||||
|
|
||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
// todo check range?
|
// todo check range?
|
||||||
writer.write_all(&[self.0])?;
|
writer.write(&[self.0])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ impl Deserialize for VarInt7 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut u8buf = [0u8; 1];
|
let mut u8buf = [0u8; 1];
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
|
|
||||||
// check if number is not continued!
|
// check if number is not continued!
|
||||||
if u8buf[0] & 0b1000_0000 != 0 {
|
if u8buf[0] & 0b1000_0000 != 0 {
|
||||||
@ -219,7 +219,7 @@ impl Serialize for VarInt7 {
|
|||||||
// todo check range?
|
// todo check range?
|
||||||
let mut b: u8 = self.0 as u8;
|
let mut b: u8 = self.0 as u8;
|
||||||
if self.0 < 0 { b |= 0b0100_0000; b &= 0b0111_1111; }
|
if self.0 < 0 { b |= 0b0100_0000; b &= 0b0111_1111; }
|
||||||
writer.write_all(&[b])?;
|
writer.write(&[b])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ impl Deserialize for Uint8 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut u8buf = [0u8; 1];
|
let mut u8buf = [0u8; 1];
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
Ok(Uint8(u8buf[0]))
|
Ok(Uint8(u8buf[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ impl Serialize for Uint8 {
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
writer.write_all(&[self.0])?;
|
writer.write(&[self.0])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ impl Deserialize for VarInt32 {
|
|||||||
let mut u8buf = [0u8; 1];
|
let mut u8buf = [0u8; 1];
|
||||||
loop {
|
loop {
|
||||||
if shift > 31 { return Err(Error::InvalidVarInt32); }
|
if shift > 31 { return Err(Error::InvalidVarInt32); }
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
let b = u8buf[0];
|
let b = u8buf[0];
|
||||||
|
|
||||||
res |= ((b & 0x7f) as i32).checked_shl(shift).ok_or(Error::InvalidVarInt32)?;
|
res |= ((b & 0x7f) as i32).checked_shl(shift).ok_or(Error::InvalidVarInt32)?;
|
||||||
@ -327,7 +327,7 @@ impl Serialize for VarInt32 {
|
|||||||
buf[0] |= 0b1000_0000
|
buf[0] |= 0b1000_0000
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.write_all(&buf[..])?;
|
writer.write(&buf[..])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -360,7 +360,7 @@ impl Deserialize for VarInt64 {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
if shift > 63 { return Err(Error::InvalidVarInt64); }
|
if shift > 63 { return Err(Error::InvalidVarInt64); }
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
let b = u8buf[0];
|
let b = u8buf[0];
|
||||||
|
|
||||||
res |= ((b & 0x7f) as i64).checked_shl(shift).ok_or(Error::InvalidVarInt64)?;
|
res |= ((b & 0x7f) as i64).checked_shl(shift).ok_or(Error::InvalidVarInt64)?;
|
||||||
@ -399,7 +399,7 @@ impl Serialize for VarInt64 {
|
|||||||
buf[0] |= 0b1000_0000
|
buf[0] |= 0b1000_0000
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.write_all(&buf[..])?;
|
writer.write(&buf[..])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -415,7 +415,7 @@ impl Deserialize for Uint32 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read(&mut buf)?;
|
||||||
// todo check range
|
// todo check range
|
||||||
Ok(Uint32(LittleEndian::read_u32(&buf)))
|
Ok(Uint32(LittleEndian::read_u32(&buf)))
|
||||||
}
|
}
|
||||||
@ -433,7 +433,7 @@ impl Serialize for Uint32 {
|
|||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
LittleEndian::write_u32(&mut buf, self.0);
|
LittleEndian::write_u32(&mut buf, self.0);
|
||||||
writer.write_all(&buf)?;
|
writer.write(&buf)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,7 +451,7 @@ impl Deserialize for Uint64 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read(&mut buf)?;
|
||||||
// todo check range
|
// todo check range
|
||||||
Ok(Uint64(LittleEndian::read_u64(&buf)))
|
Ok(Uint64(LittleEndian::read_u64(&buf)))
|
||||||
}
|
}
|
||||||
@ -463,7 +463,7 @@ impl Serialize for Uint64 {
|
|||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
LittleEndian::write_u64(&mut buf, self.0);
|
LittleEndian::write_u64(&mut buf, self.0);
|
||||||
writer.write_all(&buf)?;
|
writer.write(&buf)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,7 +500,7 @@ impl Deserialize for VarUint1 {
|
|||||||
|
|
||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let mut u8buf = [0u8; 1];
|
let mut u8buf = [0u8; 1];
|
||||||
reader.read_exact(&mut u8buf)?;
|
reader.read(&mut u8buf)?;
|
||||||
match u8buf[0] {
|
match u8buf[0] {
|
||||||
0 => Ok(VarUint1(false)),
|
0 => Ok(VarUint1(false)),
|
||||||
1 => Ok(VarUint1(true)),
|
1 => Ok(VarUint1(true)),
|
||||||
@ -513,7 +513,7 @@ impl Serialize for VarUint1 {
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
writer.write_all(&[
|
writer.write(&[
|
||||||
if self.0 { 1u8 } else { 0u8 }
|
if self.0 { 1u8 } else { 0u8 }
|
||||||
])?;
|
])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -539,7 +539,7 @@ impl Serialize for String {
|
|||||||
|
|
||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Error> {
|
||||||
VarUint32::from(self.len()).serialize(writer)?;
|
VarUint32::from(self.len()).serialize(writer)?;
|
||||||
writer.write_all(&self.into_bytes()[..])?;
|
writer.write(&self.into_bytes()[..])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -589,24 +589,15 @@ impl<'a, W: 'a + io::Write> CountedWriter<'a, W> {
|
|||||||
let data = self.data;
|
let data = self.data;
|
||||||
VarUint32::from(data.len())
|
VarUint32::from(data.len())
|
||||||
.serialize(writer)
|
.serialize(writer)
|
||||||
.map_err(
|
.map_err(|_| io::Error::InvalidData)?;
|
||||||
|_| io::Error::new(
|
writer.write(&data[..])?;
|
||||||
io::ErrorKind::Other,
|
|
||||||
"Length serialization error",
|
|
||||||
)
|
|
||||||
)?;
|
|
||||||
writer.write_all(&data[..])?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
|
impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||||
self.data.extend(buf.to_vec());
|
self.data.extend(buf.to_vec());
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io::{Read, Write};
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ impl RelocSection {
|
|||||||
|
|
||||||
impl RelocSection {
|
impl RelocSection {
|
||||||
/// Deserialize a reloc section.
|
/// Deserialize a reloc section.
|
||||||
pub fn deserialize<R: Read>(
|
pub fn deserialize<R: io::Read>(
|
||||||
name: String,
|
name: String,
|
||||||
rdr: &mut R,
|
rdr: &mut R,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
@ -101,7 +101,7 @@ impl RelocSection {
|
|||||||
impl Serialize for RelocSection {
|
impl Serialize for RelocSection {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
let mut counted_writer = CountedWriter::new(wtr);
|
let mut counted_writer = CountedWriter::new(wtr);
|
||||||
|
|
||||||
self.name.serialize(&mut counted_writer)?;
|
self.name.serialize(&mut counted_writer)?;
|
||||||
@ -209,7 +209,7 @@ pub enum RelocationEntry {
|
|||||||
impl Deserialize for RelocationEntry {
|
impl Deserialize for RelocationEntry {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(rdr: &mut R) -> Result<Self, Self::Error> {
|
||||||
match VarUint7::deserialize(rdr)?.into() {
|
match VarUint7::deserialize(rdr)?.into() {
|
||||||
FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb {
|
FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb {
|
||||||
offset: VarUint32::deserialize(rdr)?.into(),
|
offset: VarUint32::deserialize(rdr)?.into(),
|
||||||
@ -262,7 +262,7 @@ impl Deserialize for RelocationEntry {
|
|||||||
impl Serialize for RelocationEntry {
|
impl Serialize for RelocationEntry {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
|
fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
|
||||||
match self {
|
match self {
|
||||||
RelocationEntry::FunctionIndexLeb { offset, index } => {
|
RelocationEntry::FunctionIndexLeb { offset, index } => {
|
||||||
VarUint7::from(FUNCTION_INDEX_LEB).serialize(wtr)?;
|
VarUint7::from(FUNCTION_INDEX_LEB).serialize(wtr)?;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use super::{
|
use super::{
|
||||||
@ -145,7 +145,7 @@ impl Serialize for Section {
|
|||||||
},
|
},
|
||||||
Section::Unparsed { id, payload } => {
|
Section::Unparsed { id, payload } => {
|
||||||
VarUint7::from(id).serialize(writer)?;
|
VarUint7::from(id).serialize(writer)?;
|
||||||
writer.write_all(&payload[..])?;
|
writer.write(&payload[..])?;
|
||||||
},
|
},
|
||||||
Section::Type(type_section) => {
|
Section::Type(type_section) => {
|
||||||
VarUint7::from(0x01).serialize(writer)?;
|
VarUint7::from(0x01).serialize(writer)?;
|
||||||
@ -250,12 +250,12 @@ impl SectionReader {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(self) -> Result<(), ::elements::Error> {
|
pub fn close(self) -> Result<(), io::Error> {
|
||||||
let cursor = self.cursor;
|
let cursor = self.cursor;
|
||||||
let buf_length = self.declared_length;
|
let buf_length = self.declared_length;
|
||||||
|
|
||||||
if cursor.position() != buf_length as u64 {
|
if cursor.position() != buf_length {
|
||||||
Err(io::Error::from(io::ErrorKind::InvalidData).into())
|
Err(io::Error::InvalidData)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -263,8 +263,9 @@ impl SectionReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for SectionReader {
|
impl io::Read for SectionReader {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||||
self.cursor.read(buf)
|
self.cursor.read(buf)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +314,7 @@ impl Deserialize for CustomSection {
|
|||||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||||
let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
|
let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
|
||||||
let buf = buffered_read!(16384, section_length, reader);
|
let buf = buffered_read!(16384, section_length, reader);
|
||||||
let mut cursor = ::std::io::Cursor::new(&buf[..]);
|
let mut cursor = io::Cursor::new(&buf[..]);
|
||||||
let name = String::deserialize(&mut cursor)?;
|
let name = String::deserialize(&mut cursor)?;
|
||||||
let payload = buf[cursor.position() as usize..].to_vec();
|
let payload = buf[cursor.position() as usize..].to_vec();
|
||||||
Ok(CustomSection { name: name, payload: payload })
|
Ok(CustomSection { name: name, payload: payload })
|
||||||
@ -324,11 +325,11 @@ impl Serialize for CustomSection {
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||||
use std::io::Write;
|
use io::Write;
|
||||||
|
|
||||||
let mut counted_writer = CountedWriter::new(writer);
|
let mut counted_writer = CountedWriter::new(writer);
|
||||||
self.name.serialize(&mut counted_writer)?;
|
self.name.serialize(&mut counted_writer)?;
|
||||||
counted_writer.write_all(&self.payload[..])?;
|
counted_writer.write(&self.payload[..])?;
|
||||||
counted_writer.done()?;
|
counted_writer.done()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use io;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter};
|
use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter};
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ impl Serialize for DataSegment {
|
|||||||
|
|
||||||
let value = self.value;
|
let value = self.value;
|
||||||
VarUint32::from(value.len()).serialize(writer)?;
|
VarUint32::from(value.len()).serialize(writer)?;
|
||||||
writer.write_all(&value[..])?;
|
writer.write(&value[..])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{io, fmt};
|
use io;
|
||||||
|
use std::fmt;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use super::{
|
use super::{
|
||||||
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList,
|
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList,
|
||||||
|
102
src/io.rs
Normal file
102
src/io.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//! Simple abstractions for the IO operations.
|
||||||
|
//!
|
||||||
|
//! Basically it just a replacement for the std::io that is usable from
|
||||||
|
//! the `no_std` environment.
|
||||||
|
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
/// IO specific error.
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Some unexpected data left in the buffer after reading all data.
|
||||||
|
TrailingData,
|
||||||
|
|
||||||
|
/// Unexpected End-Of-File
|
||||||
|
UnexpectedEof,
|
||||||
|
|
||||||
|
/// Invalid data is encountered.
|
||||||
|
InvalidData,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// IO specific Result.
|
||||||
|
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
pub trait Write {
|
||||||
|
/// Write a buffer of data into this write.
|
||||||
|
///
|
||||||
|
/// All data is written at once.
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Read {
|
||||||
|
/// Read a data from this read to a buffer.
|
||||||
|
///
|
||||||
|
/// If there is not enough data in this read then `UnexpectedEof` will be returned.
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for Vec<u8> {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<()> {
|
||||||
|
self.extend(buf);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reader that saves the last position.
|
||||||
|
pub struct Cursor<T> {
|
||||||
|
inner: T,
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Cursor<T> {
|
||||||
|
pub fn new(inner: T) -> Cursor<T> {
|
||||||
|
Cursor {
|
||||||
|
inner,
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> usize {
|
||||||
|
self.pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<()> {
|
||||||
|
let slice = self.inner.as_ref();
|
||||||
|
let remainder = slice.len() - self.pos;
|
||||||
|
let requested = buf.len();
|
||||||
|
if requested > remainder {
|
||||||
|
return Err(Error::UnexpectedEof);
|
||||||
|
}
|
||||||
|
buf.copy_from_slice(&slice[self.pos..(self.pos + requested)]);
|
||||||
|
self.pos += requested;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cursor() {
|
||||||
|
let mut cursor = Cursor::new(vec![0xFFu8, 0x7Fu8]);
|
||||||
|
assert_eq!(cursor.position(), 0);
|
||||||
|
|
||||||
|
let mut buf = [0u8];
|
||||||
|
assert!(cursor.read(&mut buf[..]).is_ok());
|
||||||
|
assert_eq!(cursor.position(), 1);
|
||||||
|
assert_eq!(buf[0], 0xFFu8);
|
||||||
|
assert!(cursor.read(&mut buf[..]).is_ok());
|
||||||
|
assert_eq!(buf[0], 0x7Fu8);
|
||||||
|
assert_eq!(cursor.position(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overflow_in_cursor() {
|
||||||
|
let mut cursor = Cursor::new(vec![0u8]);
|
||||||
|
let mut buf = [0, 1, 2];
|
||||||
|
assert!(cursor.read(&mut buf[..]).is_err());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user