From 4686f2e0385c3f9f3ded6b3d32e363fa33a77676 Mon Sep 17 00:00:00 2001 From: Michiel De Backker Date: Wed, 28 Jan 2026 09:42:06 +0100 Subject: [PATCH 1/2] Move encode/decode type key functions to openscreen-common Closes #15 --- openscreen-application/src/messages.rs | 38 ++---------------- openscreen-common/src/lib.rs | 2 + openscreen-common/src/type_key.rs | 53 ++++++++++++++++++++++++++ openscreen-network/src/messages.rs | 36 +---------------- 4 files changed, 59 insertions(+), 70 deletions(-) create mode 100644 openscreen-common/src/type_key.rs diff --git a/openscreen-application/src/messages.rs b/openscreen-application/src/messages.rs index be3f6fa..0d68da2 100644 --- a/openscreen-application/src/messages.rs +++ b/openscreen-application/src/messages.rs @@ -21,11 +21,11 @@ //! //! Reference: ref/w3c_ref/messages_appendix.cddl -use bytes::Buf; use heapless::Vec; use minicbor::{Decoder, Encoder}; -use openscreen_common::quinn_varint::{Codec, VarInt}; -use openscreen_common::{MessageError, MAX_STRING_LENGTH, MAX_URLS}; +use openscreen_common::{ + decode_type_key, encode_type_key, MessageError, MAX_STRING_LENGTH, MAX_URLS, +}; /// A wrapper around heapless::Vec that implements minicbor's Write trait struct VecWriter<'a, const N: usize> { @@ -48,38 +48,6 @@ impl<'a, const N: usize> minicbor::encode::Write for VecWriter<'a, N> { } } -/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec -fn encode_type_key( - type_key: u16, - buf: &mut Vec, -) -> Result<(), MessageError> { - let varint = VarInt::from(type_key); - let size = varint.size(); - - // Ensure we have space - if buf.len() + size > N { - return Err(MessageError::BufferFull); - } - - // Encode varint to a small stack buffer, then copy - let mut temp = [0u8; 8]; - let mut slice = &mut temp[..]; - varint.encode(&mut slice); - buf.extend_from_slice(&temp[..size]) - .map_err(|_| MessageError::BufferFull) -} - -/// Decode a type key as RFC 9000 variable-length integer from a byte slice. -/// Returns the type key and the number of bytes consumed. -fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> { - let mut cursor = data; - let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?; - let consumed = data.len() - cursor.remaining(); - let value = varint.into_inner(); - let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?; - Ok((type_key, consumed)) -} - /// Maximum size for a single CBOR message pub const MAX_MESSAGE_SIZE: usize = 1024; diff --git a/openscreen-common/src/lib.rs b/openscreen-common/src/lib.rs index 0ed5e36..f10a82d 100644 --- a/openscreen-common/src/lib.rs +++ b/openscreen-common/src/lib.rs @@ -21,7 +21,9 @@ mod error; pub mod quinn_varint; +mod type_key; mod types; pub use error::*; +pub use type_key::*; pub use types::*; diff --git a/openscreen-common/src/type_key.rs b/openscreen-common/src/type_key.rs new file mode 100644 index 0000000..095b599 --- /dev/null +++ b/openscreen-common/src/type_key.rs @@ -0,0 +1,53 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Type key encoding/decoding using RFC 9000 variable-length integers. + +use bytes::Buf; +use heapless::Vec; + +use crate::error::MessageError; +use crate::quinn_varint::{Codec, VarInt}; + +/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec +pub fn encode_type_key( + type_key: u16, + buf: &mut Vec, +) -> Result<(), MessageError> { + let varint = VarInt::from(type_key); + let size = varint.size(); + + // Ensure we have space + if buf.len() + size > N { + return Err(MessageError::BufferFull); + } + + // Encode varint to a small stack buffer, then copy + let mut temp = [0u8; 8]; + let mut slice = &mut temp[..]; + varint.encode(&mut slice); + buf.extend_from_slice(&temp[..size]) + .map_err(|_| MessageError::BufferFull) +} + +/// Decode a type key as RFC 9000 variable-length integer from a byte slice. +/// Returns the type key and the number of bytes consumed. +pub fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> { + let mut cursor = data; + let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?; + let consumed = data.len() - cursor.remaining(); + let value = varint.into_inner(); + let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?; + Ok((type_key, consumed)) +} diff --git a/openscreen-network/src/messages.rs b/openscreen-network/src/messages.rs index d3f8809..dd37715 100644 --- a/openscreen-network/src/messages.rs +++ b/openscreen-network/src/messages.rs @@ -23,11 +23,9 @@ //! //! Reference: ref/w3c_ref/messages_appendix.cddl -use bytes::Buf; use heapless::Vec; use minicbor::{Decoder, Encoder}; -use openscreen_common::quinn_varint::{Codec, VarInt}; -use openscreen_common::MessageError; +use openscreen_common::{decode_type_key, encode_type_key, MessageError}; /// A wrapper around heapless::Vec that implements minicbor's Write trait /// This allows us to encode directly into the Vec without stack allocations @@ -51,38 +49,6 @@ impl<'a, const N: usize> minicbor::encode::Write for VecWriter<'a, N> { } } -/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec -fn encode_type_key( - type_key: u16, - buf: &mut Vec, -) -> Result<(), MessageError> { - let varint = VarInt::from(type_key); - let size = varint.size(); - - // Ensure we have space - if buf.len() + size > N { - return Err(MessageError::BufferFull); - } - - // Encode varint to a small stack buffer, then copy - let mut temp = [0u8; 8]; - let mut slice = &mut temp[..]; - varint.encode(&mut slice); - buf.extend_from_slice(&temp[..size]) - .map_err(|_| MessageError::BufferFull) -} - -/// Decode a type key as RFC 9000 variable-length integer from a byte slice. -/// Returns the type key and the number of bytes consumed. -fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> { - let mut cursor = data; - let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?; - let consumed = data.len() - cursor.remaining(); - let value = varint.into_inner(); - let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?; - Ok((type_key, consumed)) -} - /// Maximum size for a single CBOR message pub const MAX_MESSAGE_SIZE: usize = 1024; From 5f675e054b293df7474d21c8c090ea1246c84cc3 Mon Sep 17 00:00:00 2001 From: Kaido Kert Date: Thu, 29 Jan 2026 21:26:07 -0800 Subject: [PATCH 2/2] Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- openscreen-common/src/type_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openscreen-common/src/type_key.rs b/openscreen-common/src/type_key.rs index 095b599..014c790 100644 --- a/openscreen-common/src/type_key.rs +++ b/openscreen-common/src/type_key.rs @@ -34,7 +34,7 @@ pub fn encode_type_key( } // Encode varint to a small stack buffer, then copy - let mut temp = [0u8; 8]; + let mut temp = [0u8; 4]; let mut slice = &mut temp[..]; varint.encode(&mut slice); buf.extend_from_slice(&temp[..size])