refactored to new serialization

This commit is contained in:
Nikolay Volf 2016-04-23 18:15:50 +03:00
parent dcb7546d6d
commit fb82d185c7
3 changed files with 112 additions and 102 deletions

View File

@ -66,14 +66,14 @@ impl<T> BinaryConvertable for Option<T> where T: BinaryConvertable {
impl<E: BinaryConvertable> BinaryConvertable for Result<(), E> { impl<E: BinaryConvertable> BinaryConvertable for Result<(), E> {
fn size(&self) -> usize { fn size(&self) -> usize {
1usize + match *self { 1usize + match *self {
Ok(ref r) => 0, Ok(_) => 0,
Err(ref e) => e.size(), Err(ref e) => e.size(),
} }
} }
fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque<usize>) -> Result<(), BinaryConvertError> { fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque<usize>) -> Result<(), BinaryConvertError> {
match *self { match *self {
Ok(ref r) => Ok(()), Ok(_) => Ok(()),
Err(ref e) => Ok(try!(e.to_bytes(buffer, length_stack))), Err(ref e) => Ok(try!(e.to_bytes(buffer, length_stack))),
} }
} }
@ -239,6 +239,16 @@ pub fn deserialize_from<T, R>(r: &mut R) -> Result<T, BinaryConvertError>
T: BinaryConvertable T: BinaryConvertable
{ {
let mut fake_stack = VecDeque::new(); let mut fake_stack = VecDeque::new();
match T::len_params() {
0 => {
let fixed_size = mem::size_of::<T>();
let mut payload_buffer = Vec::with_capacity(fixed_size);
unsafe { payload_buffer.set_len(fixed_size); }
try!(r.read(&mut payload_buffer).map_err(|_| BinaryConvertError));
T::from_bytes(&payload_buffer[..], &mut fake_stack)
},
_ => {
let mut length_stack = VecDeque::<usize>::new(); let mut length_stack = VecDeque::<usize>::new();
let mut size_buffer = [0u8; 8]; let mut size_buffer = [0u8; 8];
try!(r.read(&mut size_buffer[..]).map_err(|_| BinaryConvertError)); try!(r.read(&mut size_buffer[..]).map_err(|_| BinaryConvertError));
@ -263,6 +273,8 @@ pub fn deserialize_from<T, R>(r: &mut R) -> Result<T, BinaryConvertError>
T::from_bytes(&data[..], &mut length_stack) T::from_bytes(&data[..], &mut length_stack)
} }
}
}
pub fn deserialize<T: BinaryConvertable>(buffer: &[u8]) -> Result<T, BinaryConvertError> { pub fn deserialize<T: BinaryConvertable>(buffer: &[u8]) -> Result<T, BinaryConvertError> {
use std::io::Cursor; use std::io::Cursor;
@ -274,8 +286,19 @@ pub fn serialize_into<T, W>(t: &T, w: &mut W) -> Result<(), BinaryConvertError>
where W: ::std::io::Write, where W: ::std::io::Write,
T: BinaryConvertable T: BinaryConvertable
{ {
let mut length_stack = VecDeque::<usize>::new();
let mut fake_stack = VecDeque::new(); let mut fake_stack = VecDeque::new();
match T::len_params() {
0 => {
let fixed_size = mem::size_of::<T>();
let mut buffer = Vec::with_capacity(fixed_size);
unsafe { buffer.set_len(fixed_size); }
try!(t.to_bytes(&mut buffer[..], &mut fake_stack));
try!(w.write(&buffer[..]).map_err(|_| BinaryConvertError));
Ok(())
},
_ => {
let mut length_stack = VecDeque::<usize>::new();
let mut size_buffer = [0u8; 8]; let mut size_buffer = [0u8; 8];
let size = t.size(); let size = t.size();
@ -308,6 +331,8 @@ pub fn serialize_into<T, W>(t: &T, w: &mut W) -> Result<(), BinaryConvertError>
Ok(()) Ok(())
} }
}
}
pub fn serialize<T: BinaryConvertable>(t: &T) -> Result<Vec<u8>, BinaryConvertError> { pub fn serialize<T: BinaryConvertable>(t: &T) -> Result<Vec<u8>, BinaryConvertError> {
use std::io::Cursor; use std::io::Cursor;

View File

@ -27,7 +27,11 @@ mod tests {
#[test] #[test]
fn call_service() { fn call_service() {
// method_num = 0, f = 10 (method Service::commit) // method_num = 0, f = 10 (method Service::commit)
let mut socket = TestSocket::new_ready(vec![0, 16, 0, 0, 0, 10]); let mut socket = TestSocket::new_ready(vec![
0, 16,
0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0]);
let service = Service::new(); let service = Service::new();
assert_eq!(0, *service.commits.read().unwrap()); assert_eq!(0, *service.commits.read().unwrap());
@ -42,13 +46,13 @@ mod tests {
fn call_service_handshake() { fn call_service_handshake() {
let mut socket = TestSocket::new_ready(vec![0, 0, let mut socket = TestSocket::new_ready(vec![0, 0,
// part count = 3 // part count = 3
0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0,
// part sizes // part sizes
0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0,
// total payload length // total payload length
0, 0, 0, 0, 0, 0, 0, 70, 70, 0, 0, 0, 0, 0, 0, 0,
// protocol version // protocol version
b'1', b'.', b'0', b'.', b'0', b'1', b'.', b'0', b'.', b'0',
// api version // api version
@ -72,24 +76,34 @@ mod tests {
#[test] #[test]
fn call_service_client() { fn call_service_client() {
let mut socket = TestSocket::new(); let mut socket = TestSocket::new();
socket.read_buffer = vec![0, 0, 0, 10]; socket.read_buffer = vec![10, 0, 0, 0];
let service_client = ServiceClient::init(socket); let service_client = ServiceClient::init(socket);
let result = service_client.commit(5); let result = service_client.commit(5);
assert_eq!(vec![0, 16, 0, 0, 0, 5], service_client.socket().borrow().write_buffer.clone()); assert_eq!(
vec![0, 16,
0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0,
5, 0, 0, 0],
service_client.socket().borrow().write_buffer.clone());
assert_eq!(10, result); assert_eq!(10, result);
} }
#[test] #[test]
fn call_service_client_optional() { fn call_service_client_optional() {
let mut socket = TestSocket::new(); let mut socket = TestSocket::new();
socket.read_buffer = vec![0, 0, 0, 10]; socket.read_buffer = vec![10, 0, 0, 0];
let service_client = ServiceClient::init(socket); let service_client = ServiceClient::init(socket);
let result = service_client.rollback(Some(5), 10); let result = service_client.rollback(Some(5), 10);
assert_eq!(vec![0, 17, 1, 0, 0, 0, 5, 0, 0, 0, 10], service_client.socket().borrow().write_buffer.clone()); assert_eq!(vec![
0, 17,
1, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().borrow().write_buffer.clone());
assert_eq!(10, result); assert_eq!(10, result);
} }
@ -123,9 +137,12 @@ mod tests {
assert_eq!(vec![ assert_eq!(vec![
// message num.. // message num..
0, 18, 0, 18,
// payload length // variable size length-s
0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0,
// structure raw bytes (bigendians :( ) 16, 0, 0, 0, 0, 0, 0, 0,
// total length
16, 0, 0, 0, 0, 0, 0, 0,
// items
3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
11, 0, 0, 0, 0, 0, 0, 0], 11, 0, 0, 0, 0, 0, 0, 0],
service_client.socket().borrow().write_buffer.clone()); service_client.socket().borrow().write_buffer.clone());
@ -135,13 +152,19 @@ mod tests {
#[test] #[test]
fn can_invoke_generic_service() { fn can_invoke_generic_service() {
let mut socket = TestSocket::new(); let mut socket = TestSocket::new();
socket.read_buffer = vec![0, 0, 0, 0]; socket.read_buffer = vec![
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0,
];
let db_client = DBClient::<u64, _>::init(socket); let db_client = DBClient::<u64, _>::init(socket);
let result = db_client.write(vec![0u8; 100]); let result = db_client.write(vec![0u8; 100]);
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test] #[test]
fn can_handshake_generic_service() { fn can_handshake_generic_service() {
let mut socket = TestSocket::new(); let mut socket = TestSocket::new();

View File

@ -20,7 +20,7 @@ mod tests {
use super::super::service::*; use super::super::service::*;
use nanoipc; use nanoipc;
use std::sync::Arc; use std::sync::Arc;
use std::io::{Write, Read}; use std::io::Write;
use std::sync::atomic::{Ordering, AtomicBool}; use std::sync::atomic::{Ordering, AtomicBool};
fn dummy_write(addr: &str, buf: &[u8]) -> (::nanomsg::Socket, ::nanomsg::Endpoint) { fn dummy_write(addr: &str, buf: &[u8]) -> (::nanomsg::Socket, ::nanomsg::Endpoint) {
@ -67,42 +67,4 @@ mod tests {
worker_should_exit.store(true, Ordering::Relaxed); worker_should_exit.store(true, Ordering::Relaxed);
assert!(hs.is_ok()); assert!(hs.is_ok());
} }
#[test]
fn can_receive_dummy_writes_in_thread() {
let url = "ipc:///tmp/parity-test-nano-30.ipc";
let worker_should_exit = Arc::new(AtomicBool::new(false));
let worker_is_ready = Arc::new(AtomicBool::new(false));
let c_worker_should_exit = worker_should_exit.clone();
let c_worker_is_ready = worker_is_ready.clone();
::std::thread::spawn(move || {
let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed);
}
});
while !worker_is_ready.load(Ordering::Relaxed) { }
let (mut _s, _e) = dummy_write(url, &vec![0, 0,
// protocol version
0, 0, 0, 0, 0, 0, 0, 5, b'1', b'.', b'0', b'.', b'0',
// api version
0, 0, 0, 0, 0, 0, 0, 5, b'1', b'.', b'0', b'.', b'0',
// reserved
0, 0, 0, 0, 0, 0, 0, 64,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
let mut buf = vec![0u8;1];
_s.read(&mut buf).unwrap();
assert_eq!(1, buf.len());
assert_eq!(1, buf[0]);
worker_should_exit.store(true, Ordering::Relaxed);
}
} }