summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2024-03-21 10:56:02 +0100
committerMatthias Beyer <mail@beyermatthias.de>2024-03-21 10:56:02 +0100
commit09fd6fd12fb3055c9d1ba3f1eeba95eb3b2fb50b (patch)
treeb55587107391cad44cc8c9c9ed3612fae87a6228
parent5a351647178c336e0da6c277961e9bbb713763bc (diff)
Implement write_variable_u32
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--mqtt-format/src/v5/integers.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/mqtt-format/src/v5/integers.rs b/mqtt-format/src/v5/integers.rs
index 734bcb0..ed86681 100644
--- a/mqtt-format/src/v5/integers.rs
+++ b/mqtt-format/src/v5/integers.rs
@@ -75,6 +75,44 @@ pub fn parse_variable_u32(input: &mut &Bytes) -> MResult<u32> {
.parse_next(input)
}
+pub async fn write_variable_u32<W: WriteMqttPacket>(buffer: &mut W, u: u32) -> WResult<W> {
+ match u {
+ 0..=127 => {
+ buffer.write_byte(u as u8).await?;
+ }
+ len @ 128..=16383 => {
+ let first = len % 128 | 0b1000_0000;
+ let second = len / 128;
+ buffer.write_byte(first as u8).await?;
+ buffer.write_byte(second as u8).await?;
+ }
+ len @ 16384..=2_097_151 => {
+ let first = len % 128 | 0b1000_0000;
+ let second = (len / 128) % 128 | 0b1000_0000;
+ let third = len / (128 * 128);
+
+ buffer.write_byte(first as u8).await?;
+ buffer.write_byte(second as u8).await?;
+ buffer.write_byte(third as u8).await?;
+ }
+ len @ 2_097_152..=268_435_455 => {
+ let first = len % 128 | 0b1000_0000;
+ let second = (len / 128) % 128 | 0b1000_0000;
+ let third = (len / (128 * 128)) % 128 | 0b1000_0000;
+ let fourth = len / (128 * 128 * 128);
+
+ buffer.write_byte(first as u8).await?;
+ buffer.write_byte(second as u8).await?;
+ buffer.write_byte(third as u8).await?;
+ buffer.write_byte(fourth as u8).await?;
+ }
+ _size => {
+ return Err(super::write::MqttWriteError::Invariant.into());
+ }
+ }
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
use winnow::Bytes;
@@ -82,6 +120,7 @@ mod tests {
use crate::v5::integers::parse_u16;
use crate::v5::integers::parse_u32;
use crate::v5::integers::parse_variable_u32;
+ use crate::v5::integers::write_variable_u32;
use crate::v5::test::TestWriter;
use crate::v5::write::WriteMqttPacket;
@@ -159,4 +198,17 @@ mod tests {
assert_eq!(writer.buffer, &[0x00, 0x00, 0x00, 0x01]);
}
+
+ #[tokio::test]
+ async fn test_write_variable_u32() {
+ // step by some prime number
+ for i in (0..268_435_455).step_by(271) {
+ let mut writer = TestWriter { buffer: Vec::new() };
+
+ write_variable_u32(&mut writer, i).await.unwrap();
+
+ let out = parse_variable_u32(&mut Bytes::new(&writer.buffer)).unwrap();
+ assert_eq!(out, i);
+ }
+ }
}