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 5, 2016
1 parent 4a2ea62 commit 8cc4b08
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 150 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.

4 changes: 3 additions & 1 deletion rust/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,9 @@ 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)
}
}
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::*;


52 changes: 23 additions & 29 deletions rust/src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! TODO
//! Macros to generate code for Flatbuffer objects.
#[macro_export]
macro_rules! table_fn {
Expand Down Expand Up @@ -93,11 +93,17 @@ macro_rules! struct_get_fn {
}

#[macro_export]
macro_rules! table_struct {
macro_rules! basic_struct_def {
($name:ident) => {
#[derive(Debug)]
pub struct $name<'a>($crate::Table<'a>);

impl<'a> $name<'a> {
pub fn new(table: $crate::Table) -> $name {
$name ( table )
}
}

impl<'a> From<$crate::Table<'a>> for $name<'a> {
fn from(table: $crate::Table) -> $name {
$name(table)
Expand All @@ -107,10 +113,10 @@ macro_rules! table_struct {
}

#[macro_export]
macro_rules! vector_item {
macro_rules! table_object_trait {
($name:ident, $indirect:expr, $inline_size:expr) => {
impl<'a> $crate::VectorItem for $name<'a> {
fn indirect_lookup() -> bool {
impl<'a> $crate::TableObject<'a> for $name<'a> {
fn is_struct() -> bool {
$indirect
}

Expand All @@ -124,35 +130,32 @@ macro_rules! vector_item {
#[macro_export]
macro_rules! table_object {
($name:ident, $inline_size:expr, [ $( $f:tt ),* ]) => {
table_struct!{$name}

basic_struct_def!{$name}
impl<'a> $name<'a> {
pub fn new(table: $crate::Table) -> $name {
$name ( table )
}
$( table_get_fn!{$f} )*
}
vector_item!{ $name, true, $inline_size }
table_object_trait!{ $name, false, $inline_size }
}
}

#[macro_export]
macro_rules! struct_object {
($name:ident, $inline_size:expr, [ $( $f:tt ),* ]) => {
table_struct!{$name}

basic_struct_def!{$name}
impl<'a> $name<'a> {
pub fn new(table: $crate::Table) -> $name {
$name ( table )
}
$( struct_get_fn!{$f} )*
}
vector_item!{ $name, false, $inline_size }
table_object_trait!{ $name, true, $inline_size }
}
}

#[macro_export]
macro_rules! simple_enum {
($type_name:ident, $repr:ident,
[ $( ($e_name:ident, $value:expr) ),+ ]) => {

#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
#[repr($repr)]
pub enum $type_name {
Expand All @@ -172,7 +175,11 @@ macro_rules! simple_enum {

#[macro_export]
macro_rules! union {
($name:ident, $type_name:ident, $repr:ident, [ $( ($e_name:ident, $value:expr, $ty:ty) ),+ ]) => {
($name:ident,
$type_name:ident,
$repr:ident,
[ $( ($e_name:ident, $value:expr, $ty:ty) ),+ ]) => {

#[derive(Debug)]
pub enum $name<'a> {
None,
Expand All @@ -191,16 +198,3 @@ macro_rules! union {
simple_enum!($type_name, $repr, [ $( ($e_name, $value) ),+ ]);
};
}

// union!{Any, AnyType, u8, [(Monster, 1, Monster<'a>)]}


// table!{Monster, [ (get_u16, u16, hp, 8, 150),
// (get_i16, i16, mana, 10, 150),
// (byte_vector, u8, test, 11),
// (ibyte_vector, i8, test2, 11),
// (bool_vector, bool, test3, 11)
// ]}

// simple_struct!{Vec3, BuildVec3, build_vec3, [ (get_u16, u16, hp, 8, 150),
// (get_i16, i16, mana, 10, 150)]}
Loading

0 comments on commit 8cc4b08

Please sign in to comment.