diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 1f0aef7..faf2a56 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -994,13 +994,13 @@ impl<'raw_data> PusTcReader<'raw_data> { /// Application data slice. #[inline] - pub fn app_data(&self) -> &[u8] { - self.user_data() + pub fn app_data(&self) -> &'raw_data [u8] { + self.app_data } /// Full raw data slice. #[inline] - pub fn raw_data(&self) -> &[u8] { + pub fn raw_data(&self) -> &'raw_data [u8] { self.raw_data } diff --git a/src/ecss/tc_pus_a.rs b/src/ecss/tc_pus_a.rs index 74d28c5..9fc68b8 100644 --- a/src/ecss/tc_pus_a.rs +++ b/src/ecss/tc_pus_a.rs @@ -791,13 +791,13 @@ impl<'raw_data> PusTcReader<'raw_data> { /// Application data slice. #[inline] - pub fn app_data(&self) -> &[u8] { - self.user_data() + pub fn app_data(&self) -> &'raw_data [u8] { + self.app_data } /// Full raw data slice. #[inline] - pub fn raw_data(&self) -> &[u8] { + pub fn raw_data(&self) -> &'raw_data [u8] { self.raw_data } diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index 91c9d2e..752cd61 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -1127,8 +1127,8 @@ impl<'raw_data> PusTmReader<'raw_data> { /// Source data slice. #[inline] - pub fn source_data(&self) -> &[u8] { - self.user_data() + pub fn source_data(&self) -> &'raw_data [u8] { + self.source_data } /// Service type ID. @@ -1157,7 +1157,7 @@ impl<'raw_data> PusTmReader<'raw_data> { /// Raw timestamp slice. #[inline] - pub fn timestamp(&self) -> &[u8] { + pub fn timestamp(&self) -> &'raw_data [u8] { self.sec_header.timestamp } @@ -1169,7 +1169,7 @@ impl<'raw_data> PusTmReader<'raw_data> { /// This function will return the slice [Self] was constructed from. #[inline] - pub fn raw_data(&self) -> &[u8] { + pub fn raw_data(&self) -> &'raw_data [u8] { self.raw_data } } diff --git a/src/ecss/tm_pus_a.rs b/src/ecss/tm_pus_a.rs index 8daa07e..8d0abfa 100644 --- a/src/ecss/tm_pus_a.rs +++ b/src/ecss/tm_pus_a.rs @@ -871,13 +871,13 @@ impl<'raw_data> PusTmReader<'raw_data> { /// Raw source data slice. #[inline] - pub fn source_data(&self) -> &[u8] { - self.user_data() + pub fn source_data(&self) -> &'raw_data [u8] { + self.source_data } /// Raw timestamp slice. #[inline] - pub fn timestamp(&self) -> &[u8] { + pub fn timestamp(&self) -> &'raw_data [u8] { self.sec_header.timestamp } @@ -889,7 +889,7 @@ impl<'raw_data> PusTmReader<'raw_data> { /// This function will return the slice [Self] was constructed from. #[inline] - pub fn raw_data(&self) -> &[u8] { + pub fn raw_data(&self) -> &'raw_data [u8] { self.raw_data } } diff --git a/src/lib.rs b/src/lib.rs index 40588a3..92671b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1631,34 +1631,6 @@ impl CcsdsPacketReader<'_> { self.sp_header.packet_id.packet_type } - /// Full raw data. - #[inline] - pub fn raw_data(&self) -> &[u8] { - self.raw_data - } - - /// Read-only access to the full packet data field. - /// - /// This might also include the checksum but does not include the raw [SpacePacketHeader]. - /// [Self::user_data] can be used to only retrieve the user data slice without the checksum - /// part. - #[inline] - pub fn packet_data(&self) -> &[u8] { - self.raw_data[CCSDS_HEADER_LEN..self.raw_data.len()].as_ref() - } - - /// Read-only access to the user data field. - /// - /// This is the [Self::packet_data] without the checksum, if the packet has one. - #[inline] - pub fn user_data(&self) -> &[u8] { - if self.checksum.is_some() { - self.packet_data()[0..self.packet_data().len() - 2].as_ref() - } else { - self.packet_data() - } - } - /// 11-bit Application Process ID field. #[inline] pub fn apid(&self) -> u11 { @@ -1696,6 +1668,36 @@ impl CcsdsPacketReader<'_> { } } +impl<'buf> CcsdsPacketReader<'buf> { + /// Full raw data. + #[inline] + pub fn raw_data(&self) -> &'buf [u8] { + self.raw_data + } + + /// Read-only access to the full packet data field. + /// + /// This might also include the checksum but does not include the raw [SpacePacketHeader]. + /// [Self::user_data] can be used to only retrieve the user data slice without the checksum + /// part. + #[inline] + pub fn packet_data(&self) -> &'buf [u8] { + self.raw_data[CCSDS_HEADER_LEN..self.raw_data.len()].as_ref() + } + + /// Read-only access to the user data field. + /// + /// This is the [Self::packet_data] without the checksum, if the packet has one. + #[inline] + pub fn user_data(&self) -> &'buf [u8] { + if self.checksum.is_some() { + self.packet_data()[0..self.packet_data().len() - 2].as_ref() + } else { + self.packet_data() + } + } +} + impl CcsdsPacket for CcsdsPacketReader<'_> { /// CCSDS version field. #[inline] @@ -3011,4 +3013,31 @@ pub(crate) mod tests { assert_eq!(reader.apid(), MAX_APID); assert_eq!(reader.seq_count(), u14::new(0x42)); } + + #[test] + fn test_reader_data_outlives_reader() { + fn slices_from_local_reader(buf: &[u8]) -> (&[u8], &[u8], &[u8]) { + let reader = CcsdsPacketReader::new(buf, Some(ChecksumType::WithCrc16)).unwrap(); + (reader.raw_data(), reader.packet_data(), reader.user_data()) + } + + let mut buf: [u8; 32] = [0; 32]; + let data = [1, 2, 3, 4, 5]; + let mut packet_creator = CcsdsPacketCreatorWithReservedData::new( + SpacePacketHeader::new_from_apid(u11::new(0x1)), + PacketType::Tc, + data.len(), + &mut buf, + Some(ChecksumType::WithCrc16), + ) + .unwrap(); + packet_creator.user_data_mut().copy_from_slice(&data); + let packet_len = packet_creator.packet_len(); + packet_creator.finish(); + + let (raw_data, packet_data, user_data) = slices_from_local_reader(&buf[0..packet_len]); + assert_eq!(raw_data, &buf[0..packet_len]); + assert_eq!(packet_data.len(), data.len() + 2); + assert_eq!(user_data, &data); + } }