summaryrefslogtreecommitdiff
path: root/src/message.rs
diff options
context:
space:
mode:
authorStuart Stock <stuart@int08h.com>2017-06-19 22:01:46 -0500
committerStuart Stock <stuart@int08h.com>2017-06-19 22:01:46 -0500
commitdc17df4885cef546ed44d14a291ba782b82d93ed (patch)
tree8a593164f7d678fcae4501945891eb8bfcb3cfa6 /src/message.rs
parent13d53fec92fddae9c312d323db81bbcb97adbe21 (diff)
downloadroughenough-dc17df4885cef546ed44d14a291ba782b82d93ed.zip
begin work on server
Diffstat (limited to 'src/message.rs')
-rw-r--r--src/message.rs56
1 files changed, 40 insertions, 16 deletions
diff --git a/src/message.rs b/src/message.rs
index 4e7e84b..73db76a 100644
--- a/src/message.rs
+++ b/src/message.rs
@@ -1,9 +1,13 @@
+
use std::io::Write;
use byteorder::{LittleEndian, WriteBytesExt};
use tag::Tag;
use error::Error;
+///
+/// A Roughtime protocol message; a map of u32 tags to arbitrary byte-strings.
+///
#[derive(Debug)]
pub struct RtMessage<'a> {
tags: Vec<Tag>,
@@ -11,13 +15,29 @@ pub struct RtMessage<'a> {
}
impl<'a> RtMessage<'a> {
+
+ /// Construct a new RtMessage
+ ///
+ /// ## Arguments
+ ///
+ /// * `num_fields` - Reserve space for this many fields.
+ ///
pub fn new(num_fields: u8) -> Self {
RtMessage {
tags: Vec::with_capacity(num_fields as usize),
- values: Vec::with_capacity(num_fields as usize)
+ values: Vec::with_capacity(num_fields as usize),
}
}
+ /// Add a field to this `RtMessage`
+ ///
+ /// ## Arguments
+ ///
+ /// * `tag` - The [`Tag`](enum.Tag.html) to add. Tags must be added in **strictly increasing order**,
+ /// violating this will result in a [`Error::TagNotStrictlyIncreasing`](enum.Error.html).
+ ///
+ /// * `value` - Value for the tag.
+ ///
pub fn add_field(&mut self, tag: Tag, value: &'a [u8]) -> Result<(), Error> {
if let Some(last_tag) = self.tags.last() {
if tag <= *last_tag {
@@ -31,10 +51,12 @@ impl<'a> RtMessage<'a> {
Ok(())
}
+ /// Returns the number of tag/value pairs in the message
pub fn num_fields(&self) -> u32 {
self.tags.len() as u32
}
+ /// Encode this message into its on-the-wire representation.
pub fn encode(&self) -> Result<Vec<u8>, Error> {
let num_tags = self.tags.len();
let mut out = Vec::with_capacity(self.encoded_size());
@@ -52,7 +74,7 @@ impl<'a> RtMessage<'a> {
}
}
- // write tags
+ // write tags
for tag in &self.tags {
out.write_all(tag.wire_value())?;
}
@@ -68,6 +90,7 @@ impl<'a> RtMessage<'a> {
Ok(out)
}
+ /// Returns the length in bytes of this message's on-the-wire representation.
pub fn encoded_size(&self) -> usize {
let num_tags = self.tags.len();
let tags_size = 4 * num_tags;
@@ -111,11 +134,11 @@ mod test {
msg.add_field(Tag::PAD, "abcd".as_bytes()).unwrap();
assert_eq!(msg.num_fields(), 2);
- // Two tag message
- // 4 num_tags
- // 8 (NONC, PAD) tags
- // 4 PAD offset
- // 8 values
+ // Two tag message
+ // 4 num_tags
+ // 8 (NONC, PAD) tags
+ // 4 PAD offset
+ // 8 values
assert_eq!(msg.encoded_size(), 24);
}
@@ -163,24 +186,25 @@ mod test {
msg.add_field(Tag::MAXT, &maxt_value).unwrap();
let mut encoded = Cursor::new(msg.encode().unwrap());
- // Wire encoding
- // 4 num_tags
- // 8 (DELE, MAXT) tags
- // 4 MAXT offset
- // 24 DELE value
- // 32 MAXT value
+ // Wire encoding
+ // 4 num_tags
+ // 8 (DELE, MAXT) tags
+ // 4 MAXT offset
+ // 24 DELE value
+ // 32 MAXT value
// num tags
assert_eq!(encoded.read_u32::<LittleEndian>().unwrap(), 2);
// Offset past DELE value to start of MAXT value
- assert_eq!(encoded.read_u32::<LittleEndian>().unwrap(), dele_value.len() as u32);
+ assert_eq!(encoded.read_u32::<LittleEndian>().unwrap(),
+ dele_value.len() as u32);
// DELE tag
let mut dele = [0u8; 4];
encoded.read_exact(&mut dele).unwrap();
assert_eq!(dele, Tag::DELE.wire_value());
-
+
// MAXT tag
let mut maxt = [0u8; 4];
encoded.read_exact(&mut maxt).unwrap();
@@ -190,7 +214,7 @@ mod test {
let mut read_dele_val = vec![0u8; 24];
encoded.read_exact(&mut read_dele_val).unwrap();
assert_eq!(dele_value, read_dele_val);
-
+
// MAXT value
let mut read_maxt_val = vec![0u8; 32];
encoded.read_exact(&mut read_maxt_val).unwrap();