diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2024-03-21 10:56:02 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2024-03-21 10:56:02 +0100 |
commit | 09fd6fd12fb3055c9d1ba3f1eeba95eb3b2fb50b (patch) | |
tree | b55587107391cad44cc8c9c9ed3612fae87a6228 | |
parent | 5a351647178c336e0da6c277961e9bbb713763bc (diff) |
Implement write_variable_u32
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | mqtt-format/src/v5/integers.rs | 52 |
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); + } + } } |