Skip to content

Commit

Permalink
Refactor iter and table methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Dunne committed Jun 6, 2016
1 parent 4a2ea62 commit 9c1234c
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 155 deletions.
26 changes: 13 additions & 13 deletions include/flatbuffers/idl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ namespace flatbuffers {
// Additionally, Parser::ParseType assumes bool..string is a contiguous range
// of type tokens.
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,byte, bool, bool, bool) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, u8, u8) \
TD(SHORT, "short", int16_t, short, int16, short, i16, i16) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, u16, u16) \
TD(INT, "int", int32_t, int, int32, int, i32, i32) \
TD(UINT, "uint", uint32_t, int, uint32, uint, u32, u32) \
TD(LONG, "long", int64_t, long, int64, long, i64, i64) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, u64, u64) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, f32, f32) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, f64, f64) /* end float/scalar */
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,byte, bool, bool, bool) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8) \
TD(SHORT, "short", int16_t, short, int16, short, int16, i16) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16) \
TD(INT, "int", int32_t, int, int32, int, int32, i32) \
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32) \
TD(LONG, "long", int64_t, long, int64, long, int64, i64) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, float32, f32) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, float64, f64) /* end float/scalar */
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, i32) \
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, i32) \
Expand Down
2 changes: 1 addition & 1 deletion rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "flatbuffers"
version = "0.2.0"
version = "0.2.1"
authors = ["Joseph Dunne <jd@lambda.tech>"]
description = "Memory Efficient Serialization Library. Flatbuffers runtime for Rust."
keywords = ["flatbuffers", "serialization", "deserialization"]
Expand Down
1 change: 0 additions & 1 deletion rust/src/bin/test/MyGame/Example/.#Color.rs

This file was deleted.

22 changes: 16 additions & 6 deletions rust/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,14 @@ impl Builder {

/// pad places zeros at the current offset.
pub fn pad(&mut self, n: usize) {
for _ in 0..n {
self.space -= 1;
let pos = self.space;
self.place_u8(pos, 0)
use std::ptr;
unsafe {
let mut ptr = self.bytes.as_mut_ptr().offset(self.space as isize);
for _ in 0..n {
self.space -= 1;
ptr = ptr.offset(-1);
ptr::write(ptr, 0);
}
}
}
}
Expand Down Expand Up @@ -542,15 +546,21 @@ impl Builder {
pub fn add_slot_struct(&mut self, o: usize, value: UOffsetT, d: UOffsetT) {
if value != d {
self.assert_nested();
assert!(value == self.offset() as u32, "Inline data write outside of object");
assert!(value == self.offset() as u32, "Inline data write outside of object.\
Write the slot_struct immediatly after \
writing the struct slot.");
self.slot(o)
}
}

/// Place a `u8` at `pos` relative to the beginning
/// of the underlaying buffer.
pub fn place_u8(&mut self, pos: usize, value: u8) {
self.bytes[pos] = value;
use std::ptr;
unsafe {
let ptr = self.bytes.as_mut_ptr().offset(pos as isize);
ptr::write(ptr,value)
}
}

/// Place a `u32` with `LittleEndian` encoding at `pos`
Expand Down
173 changes: 72 additions & 101 deletions rust/src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
use std::fmt::Debug;
use std::iter;
use std::mem;
use std::marker::PhantomData;
use byteorder::{ByteOrder, LittleEndian};

use table;
use table::Table;

/// A trait for Structs and Tables to implement.
pub trait VectorItem {
/// Table Objects require indirection. Structs do not.
fn indirect_lookup() -> bool;
/// The size of the object in the vector.
fn inline_size() -> usize;
}
use table::{Table,TableObject};

/// An iterator over flatbuffer vectors.
#[derive(Debug)]
Expand All @@ -32,86 +24,6 @@ pub trait LittleEndianReader<'a> {
fn size() -> usize;
}

impl<'a> LittleEndianReader<'a>for u8 {
fn read(buffer: &[u8], index: usize) -> u8 { buffer[index] }
fn size() -> usize { 1 }
}

impl<'a> LittleEndianReader<'a>for i8 {
fn read(buffer: &[u8], index: usize) -> i8 { buffer[index] as i8 }
fn size() -> usize { 1 }
}

impl<'a> LittleEndianReader<'a>for bool {
fn read(buffer: &[u8], index: usize) -> bool { buffer[index] == 0 }
fn size() -> usize { 1 }
}

impl<'a> LittleEndianReader<'a>for u16 {
fn read(buffer: &[u8], index: usize) -> u16 { LittleEndian::read_u16(&buffer[index..]) }
fn size() -> usize { 2 }
}

impl<'a> LittleEndianReader<'a>for i16 {
fn read(buffer: &[u8], index: usize) -> i16 { LittleEndian::read_i16(&buffer[index..]) }
fn size() -> usize { 2 }
}

impl<'a> LittleEndianReader<'a>for u32 {
fn read(buffer: &[u8], index: usize) -> u32 { LittleEndian::read_u32(&buffer[index..]) }
fn size() -> usize { 4 }
}

impl<'a> LittleEndianReader<'a>for i32 {
fn read(buffer: &[u8], index: usize) -> i32 { LittleEndian::read_i32(&buffer[index..]) }
fn size() -> usize { 4 }
}

impl<'a> LittleEndianReader<'a>for u64 {
fn read(buffer: &[u8], index: usize) -> u64 { LittleEndian::read_u64(&buffer[index..]) }
fn size() -> usize { 8 }
}

impl<'a> LittleEndianReader<'a>for i64 {
fn read(buffer: &[u8], index: usize) -> i64 { LittleEndian::read_i64(&buffer[index..]) }
fn size() -> usize { 8 }
}

impl<'a> LittleEndianReader<'a>for f32 {
fn read(buffer: &[u8], index: usize) -> f32 { LittleEndian::read_f32(&buffer[index..]) }
fn size() -> usize { 4 }
}

impl<'a> LittleEndianReader<'a>for f64 {
fn read(buffer: &[u8], index: usize) -> f64 { LittleEndian::read_f64(&buffer[index..]) }
fn size() -> usize { 8 }
}

impl<'a> LittleEndianReader<'a>for &'a str {
fn read(buffer: &[u8], index:usize) -> &str {
use std::str;
let offset = LittleEndian::read_u32(&buffer[index..]) as usize + index;
let start = offset as usize + 4;
let length = table::read_uoffset(buffer, offset as usize) as usize;
let s = &buffer[start..start+length];
unsafe { str::from_utf8_unchecked(s) }
}
fn size() -> usize { 4 }
}


impl<'a, T: From<Table<'a>> + VectorItem> LittleEndianReader<'a>for T {
fn read(buffer: &'a [u8], index: usize) -> T {
let table = if T::indirect_lookup() {
Table::from_offset(buffer, index as usize)
} else {
Table::with_pos(&buffer, index as usize)
};
table.into()
}
fn size() -> usize { T::inline_size() }
}

impl<'a, T: LittleEndianReader<'a>> iter::Iterator for Iterator<'a, T> {
type Item = T;

Expand All @@ -129,12 +41,26 @@ impl<'a, T: LittleEndianReader<'a>> iter::Iterator for Iterator<'a, T> {
}
}

impl<'a, T: LittleEndianReader<'a> + Debug> ExactSizeIterator for Iterator<'a, T> {
impl<'a, T: LittleEndianReader<'a>> ExactSizeIterator for Iterator<'a, T> {
fn len(&self) -> usize {
self.len
}
}

impl<'a, T> Iterator<'a, T> {
/// Create a new Iterator for type `T` starting at `index` with
/// a length of `len` items of size `T`.
pub fn new(buffer: &[u8], index: usize, len: usize) -> Iterator<T> {
Iterator {
buffer: buffer,
index: index,
len: len,
i: 0,
_marker: PhantomData
}
}
}

impl<'a, T> Default for Iterator<'a, T> {
fn default() -> Iterator<'a, T> {
Iterator {
Expand All @@ -147,16 +73,61 @@ impl<'a, T> Default for Iterator<'a, T> {
}
}

impl<'a, T> Iterator<'a, T> {
/// Create a new Iterator for type `T` starting at `index` with
/// a length of `len` items of size `T`.
pub fn new(buffer: &[u8], index: usize, len: usize) -> Iterator<T> {
Iterator {
buffer: buffer,
index: index,
len: len,
i: 0,
_marker: PhantomData
macro_rules! little_reader {
($ty:ty) => {
impl<'a> LittleEndianReader<'a> for $ty {
fn read(buffer: &[u8], index: usize) -> $ty { buffer[index] as $ty }
fn size() -> usize { mem::size_of::<$ty>() }
}
};
($ty:ty, $fun:ident) => {
impl<'a> LittleEndianReader<'a> for $ty {
fn read(buffer: &[u8], index: usize) -> $ty { LittleEndian::$fun(&buffer[index..]) }
fn size() -> usize { mem::size_of::<$ty>() }
}
}
}

little_reader!(u8);
little_reader!(i8);
little_reader!(u16, read_u16);
little_reader!(i16, read_i16);
little_reader!(u32, read_u32);
little_reader!(i32, read_i32);
little_reader!(u64, read_u64);
little_reader!(i64, read_i64);
little_reader!(f32, read_f32);
little_reader!(f64, read_f64);

impl<'a> LittleEndianReader<'a> for bool {
fn read(buffer: &[u8], index: usize) -> bool { buffer[index] == 0 }
fn size() -> usize { 1 }
}

impl<'a> LittleEndianReader<'a> for &'a str {
fn read(buffer: &[u8], index:usize) -> &str {
use std::str;
let offset = LittleEndian::read_u32(&buffer[index..]) as usize + index;
let start = offset as usize + 4;
let length = table::read_uoffset(buffer, offset as usize) as usize;
let s = &buffer[start..start+length];
unsafe { str::from_utf8_unchecked(s) }
}
fn size() -> usize { 4 }
}


impl<'a, T: TableObject<'a>> LittleEndianReader<'a> for T {
fn read(buffer: &'a [u8], index: usize) -> T {
let table = if T::is_struct() {
Table::with_pos(&buffer, index as usize)
} else {
Table::from_offset(buffer, index as usize)
};
table.into()
}
fn size() -> usize { T::inline_size() }
}



2 changes: 1 addition & 1 deletion rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub mod macros;

pub use self::builder::Builder;
pub use self::types::{UOffsetT, VOffsetT, SOffsetT};
pub use self::table::Table;
pub use self::table::*;
pub use self::iter::*;


Loading

0 comments on commit 9c1234c

Please sign in to comment.