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..014c790 --- /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; 4]; + 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;