2016-09-19 10:19:04 -07:00
|
|
|
use crypto::checksum;
|
|
|
|
use ser::{
|
2016-09-20 06:31:33 -07:00
|
|
|
Deserializable, Reader, Error as ReaderError,
|
|
|
|
Serializable, Stream, serialize
|
2016-09-19 10:19:04 -07:00
|
|
|
};
|
2016-09-20 06:31:33 -07:00
|
|
|
use {MessageHeader, Payload};
|
2016-09-19 10:19:04 -07:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct Message {
|
2016-09-20 06:31:33 -07:00
|
|
|
pub header: MessageHeader,
|
|
|
|
pub payload: Payload,
|
2016-09-19 10:19:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Message {
|
2016-09-20 06:31:33 -07:00
|
|
|
pub fn new(magic: u32, payload: Payload) -> Message {
|
|
|
|
let serialized = serialize(&payload);
|
|
|
|
Message {
|
|
|
|
header: MessageHeader {
|
|
|
|
magic: magic,
|
|
|
|
command: payload.command(),
|
|
|
|
len: serialized.len() as u32,
|
|
|
|
checksum: checksum(&serialized),
|
|
|
|
},
|
|
|
|
payload: payload,
|
|
|
|
}
|
2016-09-19 10:19:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Serializable for Message {
|
|
|
|
fn serialize(&self, stream: &mut Stream) {
|
|
|
|
stream
|
2016-09-20 06:31:33 -07:00
|
|
|
.append(&self.header)
|
|
|
|
.append(&self.payload);
|
2016-09-19 10:19:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserializable for Message {
|
|
|
|
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
|
2016-09-20 06:31:33 -07:00
|
|
|
let header: MessageHeader = try!(reader.read());
|
|
|
|
let payload = try!(reader.read_slice(header.len as usize));
|
2016-09-19 10:19:04 -07:00
|
|
|
|
2016-09-20 06:31:33 -07:00
|
|
|
if header.checksum != checksum(payload) {
|
2016-09-19 10:19:04 -07:00
|
|
|
return Err(ReaderError::MalformedData);
|
|
|
|
}
|
|
|
|
|
2016-09-20 06:31:33 -07:00
|
|
|
let mut payload_reader = Reader::new(payload);
|
|
|
|
let payload = try!(Payload::deserialize_payload(&mut payload_reader, &header.command));
|
|
|
|
|
2016-09-19 10:19:04 -07:00
|
|
|
let message = Message {
|
2016-09-20 06:31:33 -07:00
|
|
|
header: header,
|
|
|
|
payload: payload,
|
2016-09-19 10:19:04 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2016-09-20 03:49:04 -07:00
|
|
|
use bytes::Bytes;
|
|
|
|
use ser::{serialize, deserialize};
|
2016-09-20 06:31:33 -07:00
|
|
|
use {Version, Payload};
|
2016-09-20 03:49:04 -07:00
|
|
|
use super::Message;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_message_serialization() {
|
|
|
|
let expected: Bytes = "f9beb4d976657273696f6e000000000064000000358d493262ea0000010000000000000011b2d05000000000010000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000ffff0000000000003b2eb35d8ce617650f2f5361746f7368693a302e372e322fc03e0300".into();
|
2016-09-20 06:31:33 -07:00
|
|
|
let version: Version = "62ea0000010000000000000011b2d05000000000010000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000ffff0000000000003b2eb35d8ce617650f2f5361746f7368693a302e372e322fc03e0300".into();
|
|
|
|
let magic = 0xd9b4bef9;
|
|
|
|
let message = Message::new(magic, Payload::Version(version));
|
2016-09-20 03:49:04 -07:00
|
|
|
assert_eq!(serialize(&message), expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_message_deserialization() {
|
|
|
|
let raw: Bytes = "f9beb4d976657273696f6e000000000064000000358d493262ea0000010000000000000011b2d05000000000010000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000ffff0000000000003b2eb35d8ce617650f2f5361746f7368693a302e372e322fc03e0300".into();
|
2016-09-20 06:31:33 -07:00
|
|
|
let version: Version = "62ea0000010000000000000011b2d05000000000010000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000ffff0000000000003b2eb35d8ce617650f2f5361746f7368693a302e372e322fc03e0300".into();
|
|
|
|
let magic = 0xd9b4bef9;
|
|
|
|
let expected = Message::new(magic, Payload::Version(version));
|
2016-09-20 03:49:04 -07:00
|
|
|
assert_eq!(expected, deserialize(&raw).unwrap());
|
|
|
|
}
|
2016-09-19 10:19:04 -07:00
|
|
|
}
|