use std::mem;
use Result;
use tape::{Tape, Value, ValueExt};
pub type GlyphID = u16;
pub type OffsetSize = u8;
pub type StringID = u16;
macro_rules! fill(
($tape:ident, $count:expr, $buffer:ident) => (
if try!(::std::io::Read::read($tape, &mut $buffer)) != $count {
return raise!("failed to read as much as needed");
}
);
);
macro_rules! read(
($tape:ident, $size:expr) => (unsafe {
let mut buffer: [u8; $size] = mem::uninitialized();
fill!($tape, $size, buffer);
mem::transmute(buffer)
});
);
macro_rules! implement {
($name:ident, 1) => (impl Value for $name {
fn read<T: Tape>(tape: &mut T) -> Result<Self> {
Ok(read!(tape, 1))
}
});
($name:ident, $size:expr) => (impl Value for $name {
fn read<T: Tape>(tape: &mut T) -> Result<Self> {
Ok($name::from_be(read!(tape, $size)))
}
});
}
implement!(u8, 1);
implement!(u16, 2);
implement!(u32, 4);
impl ValueExt<usize> for Vec<u8> {
fn read<T: Tape>(tape: &mut T, count: usize) -> Result<Self> {
let mut values = Vec::with_capacity(count);
unsafe { values.set_len(count) };
fill!(tape, count, values);
Ok(values)
}
}
mod number;
mod offset;
pub use self::number::Number;
pub use self::offset::Offset;