From e2fc1a997ce1ebf5232c494ebf3a753e92098f09 Mon Sep 17 00:00:00 2001 From: AlaaZorkane Date: Thu, 30 Dec 2021 00:53:55 +0100 Subject: [PATCH 1/5] add `serialize_into_slice_without_len()` function --- quick-protobuf/src/writer.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/quick-protobuf/src/writer.rs b/quick-protobuf/src/writer.rs index 35dbe591..0164ae59 100644 --- a/quick-protobuf/src/writer.rs +++ b/quick-protobuf/src/writer.rs @@ -207,7 +207,7 @@ impl Writer { self.write_bytes(bytes) } - /// Writes a message which implements `MessageWrite` + /// Writes a message which implements `MessageWrite` prefixed with a `varint` length #[cfg_attr(std, inline)] pub fn write_message(&mut self, m: &M) -> Result<()> { let len = m.get_size(); @@ -215,6 +215,12 @@ impl Writer { m.write_message(self) } + /// Writes a message which implements `MessageWrite` without adding the length prefix + #[cfg_attr(std, inline)] + pub fn write_message_without_len(&mut self, m: &M) -> Result<()> { + m.write_message(self) + } + /// Writes another item prefixed with tag #[cfg_attr(std, inline)] pub fn write_with_tag(&mut self, tag: u32, mut write: F) -> Result<()> @@ -318,7 +324,7 @@ pub fn serialize_into_vec(message: &M) -> Result> { Ok(v) } -/// Serialize a `MessageWrite` into a byte slice +/// Serialize a `MessageWrite` into a byte slice with a length prefix pub fn serialize_into_slice(message: &M, out: &mut [u8]) -> Result<()> { let len = message.get_size(); if out.len() < len { @@ -332,6 +338,23 @@ pub fn serialize_into_slice(message: &M, out: &mut [u8]) -> Res Ok(()) } +/// Serialize a `MessageWrite` into a byte slice without a length prefix +pub fn serialize_into_slice_without_len( + message: &M, + out: &mut [u8], +) -> Result<()> { + let len = message.get_size(); + if out.len() < len { + return Err(Error::OutputBufferTooSmall); + } + { + let mut writer = Writer::new(BytesWriter::new(out)); + writer.write_message_without_len(message)?; + } + + Ok(()) +} + /// Writer backend abstraction pub trait WriterBackend { /// Write a u8 From 05c5d61a0b5278fa3b2a9effe81f66af79bcf5ab Mon Sep 17 00:00:00 2001 From: AlaaZorkane Date: Thu, 30 Dec 2021 00:54:38 +0100 Subject: [PATCH 2/5] add `deserialize_from_slice_without_len()` function --- quick-protobuf/src/reader.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/quick-protobuf/src/reader.rs b/quick-protobuf/src/reader.rs index 51297bc1..91afe8d5 100644 --- a/quick-protobuf/src/reader.rs +++ b/quick-protobuf/src/reader.rs @@ -411,6 +411,18 @@ impl BytesReader { self.read_len_varint(bytes, M::from_reader) } + /// Reads a nested message + /// + /// The length is computed from the size of the message `bytes` + #[cfg_attr(std, inline)] + pub fn read_message_without_len<'a, M>(&mut self, bytes: &'a [u8]) -> Result + where + M: MessageRead<'a>, + { + let len = bytes.len(); + self.read_len(bytes, M::from_reader, len) + } + /// Reads a nested message /// /// Reads just the message and does not try to read it's size first. @@ -600,11 +612,19 @@ impl Reader { } /// Deserialize a `MessageRead from a `&[u8]` +/// +/// Must be prefixed with the length of the message pub fn deserialize_from_slice<'a, M: MessageRead<'a>>(bytes: &'a [u8]) -> Result { let mut reader = BytesReader::from_bytes(&bytes); reader.read_message::(&bytes) } +/// Deserialize a `MessageRead from a `&[u8]` without a length prefix +pub fn deserialize_from_slice_without_len<'a, M: MessageRead<'a>>(bytes: &'a [u8]) -> Result { + let mut reader = BytesReader::from_bytes(&bytes); + reader.read_message_without_len::(&bytes) +} + #[test] fn test_varint() { let data = [0x96, 0x01]; From 612f0703cbbd2b3ec0150a9233abb606002feaf4 Mon Sep 17 00:00:00 2001 From: AlaaZorkane Date: Thu, 30 Dec 2021 00:55:30 +0100 Subject: [PATCH 3/5] declare `without_len` reader/writer in lib --- quick-protobuf/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quick-protobuf/src/lib.rs b/quick-protobuf/src/lib.rs index f5105d7c..000b07f3 100644 --- a/quick-protobuf/src/lib.rs +++ b/quick-protobuf/src/lib.rs @@ -14,8 +14,10 @@ pub mod writer; pub use crate::errors::{Error, Result}; pub use crate::message::{MessageInfo, MessageRead, MessageWrite}; -pub use crate::reader::{deserialize_from_slice, BytesReader}; -pub use crate::writer::{serialize_into_slice, BytesWriter, Writer, WriterBackend}; +pub use crate::reader::{deserialize_from_slice, deserialize_from_slice_without_len, BytesReader}; +pub use crate::writer::{ + serialize_into_slice, serialize_into_slice_without_len, BytesWriter, Writer, WriterBackend, +}; #[cfg(feature = "std")] pub use crate::reader::Reader; From 7a96af00b6aa937a4bc0bc45066757ddee6be4e2 Mon Sep 17 00:00:00 2001 From: AlaaZorkane Date: Thu, 30 Dec 2021 00:56:11 +0100 Subject: [PATCH 4/5] add `without_len` read/write tests --- quick-protobuf/tests/write_read.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/quick-protobuf/tests/write_read.rs b/quick-protobuf/tests/write_read.rs index cdf1c139..99207d5c 100644 --- a/quick-protobuf/tests/write_read.rs +++ b/quick-protobuf/tests/write_read.rs @@ -1,7 +1,10 @@ extern crate quick_protobuf; use quick_protobuf::sizeofs::*; -use quick_protobuf::{deserialize_from_slice, serialize_into_slice, serialize_into_vec}; +use quick_protobuf::{ + deserialize_from_slice, deserialize_from_slice_without_len, serialize_into_slice, + serialize_into_slice_without_len, serialize_into_vec, +}; use quick_protobuf::{ BytesReader, MessageRead, MessageWrite, Reader, Result, Writer, WriterBackend, }; @@ -166,6 +169,21 @@ fn wr_message_slice() { assert_eq!(v, deserialize_from_slice(&buf).unwrap()); } +#[test] +fn wr_message_slice_without_len() { + let original = TestMessage { + id: Some(63), + val: vec![53, 5, 76, 743, 23, 753], + }; + + let len = original.get_size(); + let mut serialized = vec![0u8; len]; + serialize_into_slice_without_len(&original, &mut serialized).unwrap(); + + let deserialized = deserialize_from_slice_without_len(&serialized).unwrap(); + assert_eq!(original, deserialized); +} + #[derive(PartialEq, Eq, Debug, Clone, Default)] struct TestMessageBorrow<'a> { id: Option, From efc772af18a41d119638164125fca4fdf3db2d72 Mon Sep 17 00:00:00 2001 From: AlaaZorkane Date: Thu, 13 Jan 2022 10:09:26 +0100 Subject: [PATCH 5/5] add return encoded length to non-delimited serialization --- quick-protobuf/src/writer.rs | 4 ++-- quick-protobuf/tests/write_read.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/quick-protobuf/src/writer.rs b/quick-protobuf/src/writer.rs index 0164ae59..5399fa1e 100644 --- a/quick-protobuf/src/writer.rs +++ b/quick-protobuf/src/writer.rs @@ -342,7 +342,7 @@ pub fn serialize_into_slice(message: &M, out: &mut [u8]) -> Res pub fn serialize_into_slice_without_len( message: &M, out: &mut [u8], -) -> Result<()> { +) -> Result { let len = message.get_size(); if out.len() < len { return Err(Error::OutputBufferTooSmall); @@ -352,7 +352,7 @@ pub fn serialize_into_slice_without_len( writer.write_message_without_len(message)?; } - Ok(()) + Ok(len) } /// Writer backend abstraction diff --git a/quick-protobuf/tests/write_read.rs b/quick-protobuf/tests/write_read.rs index 99207d5c..f9befdbe 100644 --- a/quick-protobuf/tests/write_read.rs +++ b/quick-protobuf/tests/write_read.rs @@ -178,9 +178,10 @@ fn wr_message_slice_without_len() { let len = original.get_size(); let mut serialized = vec![0u8; len]; - serialize_into_slice_without_len(&original, &mut serialized).unwrap(); + let serialized_len = serialize_into_slice_without_len(&original, &mut serialized).unwrap(); let deserialized = deserialize_from_slice_without_len(&serialized).unwrap(); + assert_eq!(len, serialized_len); assert_eq!(original, deserialized); }