read from bytes finished

This commit is contained in:
Nikolay Volf 2016-04-20 23:02:29 +03:00
parent a61ab6d40f
commit ffc10fec8b
2 changed files with 161 additions and 11 deletions

View File

@ -108,8 +108,7 @@ fn serialize_item(
}
fn from_bytes(buffer: &[u8]) -> Result<Self, BinaryConvertError> {
//$read_expr
Err(::ipc::BinaryConvertError)
$read_expr
}
}
).unwrap())
@ -164,6 +163,7 @@ fn binary_expr_struct(
ty: P<ast::Ty>,
fields: &[ast::StructField],
value_ident: Option<ast::Ident>,
instance_ident: Option<ast::Ident>,
) -> Result<BinaryExpressions, Error> {
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
let index_ident = builder.id(format!("__field{}", index));
@ -182,6 +182,11 @@ fn binary_expr_struct(
let mut write_stmts = Vec::<ast::Stmt>::new();
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).unwrap());
let mut map_stmts = Vec::<ast::Stmt>::new();
let field_amount = builder.id(&format!("{}",fields.len()));
map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).unwrap());
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap());
for (index, field) in fields.iter().enumerate() {
let size_expr = &size_exprs[index];
write_stmts.push(quote_stmt!(cx, let next_line = offset + $size_expr; ).unwrap());
@ -198,12 +203,26 @@ fn binary_expr_struct(
}
}
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
let field_index = builder.id(&format!("{}", index));
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty));
map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap());
map_stmts.push(quote_stmt!(cx, total = total + mem::size_of::<$field_type_ident>();).unwrap());
};
let read_expr = if value_ident.is_some() {
let instance_create = named_fields_sequence(cx, &ty, fields);
quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) })
}
else {
let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self"))));
quote_expr!(cx, { $map_stmts; Ok($map_variant) })
};
Ok(BinaryExpressions {
size: total_size_expr,
write: quote_expr!(cx, { $write_stmts; Ok(()) } ),
read: quote_expr!(cx, Err(::ipc::BinaryConvertError)),
read: read_expr,
})
}
@ -223,6 +242,7 @@ fn binary_expr_item_struct(
ty,
fields,
Some(builder.id("self")),
None,
)
}
ast::VariantData::Struct(ref fields, _) => {
@ -232,6 +252,7 @@ fn binary_expr_item_struct(
ty,
fields,
Some(builder.id("self")),
None,
)
},
_ => {
@ -270,15 +291,17 @@ fn binary_expr_enum(
.collect()
);
let (size_arms, write_arms, read_arms) = (
let (size_arms, write_arms, mut read_arms) = (
arms.iter().map(|x| x.size.clone()).collect::<Vec<ast::Arm>>(),
arms.iter().map(|x| x.write.clone()).collect::<Vec<ast::Arm>>(),
arms.iter().map(|x| x.read.clone()).collect::<Vec<ast::Arm>>());
read_arms.push(quote_arm!(cx, _ => { Err(BinaryConvertError) } ));
Ok(BinaryExpressions {
size: quote_expr!(cx, 1usize + match *self { $size_arms }),
write: quote_expr!(cx, match *self { $write_arms }; ),
read: quote_expr!(cx, match *self { $read_arms }),
read: quote_expr!(cx, match buffer[0] { $read_arms }),
})
}
@ -288,6 +311,132 @@ struct BinaryArm {
read: ast::Arm,
}
fn fields_sequence(
ext_cx: &ExtCtxt,
ty: &P<ast::Ty>,
fields: &[ast::StructField],
variant_ident: &ast::Ident,
) -> ast::Expr {
use syntax::parse::token;
use syntax::ast::TokenTree::Token;
::quasi::parse_expr_panic(&mut ::syntax::parse::new_parser_from_tts(
ext_cx.parse_sess(),
ext_cx.cfg(),
{
let _sp = ext_cx.call_site();
let mut tt = ::std::vec::Vec::new();
tt.push(Token(_sp, token::Ident(variant_ident.clone(), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
for (idx, field) in fields.iter().enumerate() {
if field.ident.is_some() {
tt.push(Token(_sp, token::Ident(field.ident.clone().unwrap(), token::Plain)));
tt.push(Token(_sp, token::Colon));
}
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
tt.push(Token(
_sp,
token::Ident(
ext_cx.ident_of(&::syntax::print::pprust::ty_to_string(&field.ty)),
token::Plain)));
tt.push(Token(_sp, token::ModSep));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
tt.push(Token(_sp, token::BinOp(token::And)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)), token::Plain)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::DotDot));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
tt.push(Token(_sp, token::Comma));
}
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
tt
})
).unwrap()
}
fn named_fields_sequence(
ext_cx: &ExtCtxt,
ty: &P<ast::Ty>,
fields: &[ast::StructField],
) -> ast::Stmt {
use syntax::parse::token;
use syntax::ast::TokenTree::Token;
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
ext_cx.parse_sess(),
ext_cx.cfg(),
{
let _sp = ext_cx.call_site();
let mut tt = ::std::vec::Vec::new();
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("let"), token::Plain)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("result"), token::Plain)));
tt.push(Token(_sp, token::Eq));
tt.push(Token(
_sp,
token::Ident(
ext_cx.ident_of(&::syntax::print::pprust::ty_to_string(ty)),
token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Brace)));
for (idx, field) in fields.iter().enumerate() {
tt.push(Token(_sp, token::Ident(field.ident.clone().unwrap(), token::Plain)));
tt.push(Token(_sp, token::Colon));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
tt.push(Token(
_sp,
token::Ident(
ext_cx.ident_of(&::syntax::print::pprust::ty_to_string(&field.ty)),
token::Plain)));
tt.push(Token(_sp, token::ModSep));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
tt.push(Token(_sp, token::BinOp(token::And)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)), token::Plain)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::DotDot));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
tt.push(Token(_sp, token::Comma));
}
tt.push(Token(_sp, token::CloseDelim(token::Brace)));
tt
})
).unwrap()
}
fn binary_expr_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
@ -309,10 +458,12 @@ fn binary_expr_variant(
.id(type_ident).id(variant_ident)
.build();
let variant_val = builder.id(format!("{}::{}", type_ident, variant_ident));
Ok(BinaryArm {
size: quote_arm!(cx, $pat => { 0usize } ),
write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; Ok(()) } ),
read: quote_arm!(cx, $pat => { } ),
read: quote_arm!(cx, $variant_index_ident => { Ok($variant_val) } ),
})
},
ast::VariantData::Tuple(ref fields, _) => {
@ -334,6 +485,7 @@ fn binary_expr_variant(
ty,
fields,
None,
Some(builder.id(format!("{}::{}", type_ident, variant_ident))),
));
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
@ -345,7 +497,7 @@ fn binary_expr_variant(
let buffer = &mut buffer[1..];
$write_expr
}),
read: quote_arm!(cx, $pat => { $read_expr } ),
read: quote_arm!(cx, $variant_index_ident => { $read_expr } ),
})
}
ast::VariantData::Struct(ref fields, _) => {
@ -368,6 +520,7 @@ fn binary_expr_variant(
ty,
fields,
None,
Some(builder.id(format!("{}::{}", type_ident, variant_ident))),
));
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);

View File

@ -15,15 +15,12 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ipc::*;
use std::mem;
#[derive(Binary)]
enum Root {
Top,
Middle(u32, u64),
Bottom {
number1: u32,
number2: u64,
},
}
#[derive(Binary)]