borrowed read and annotations
Some checks failed
Build and Test / super-mario-maker (push) Failing after 5m11s
Build and Test / splatoon-testfire (push) Failing after 5m13s
Build and Test / minecraft-wiiu (push) Failing after 5m22s
Build and Test / mario-tennis (push) Failing after 5m23s
Build and Test / puyopuyo (push) Failing after 5m27s
Build and Test / sonic-transformed (push) Failing after 5m27s
Build and Test / fast-racing-neo (push) Failing after 6m9s
Build and Test / wii-sports-club (push) Failing after 6m11s
Build and Test / friends (push) Failing after 6m13s
Build and Test / wii-u-chat (push) Failing after 6m14s
Build and Test / splatoon (push) Failing after 6m41s

This commit is contained in:
Maple Nebel 2026-07-16 15:01:47 +02:00
commit 1b503acd4f
17 changed files with 514 additions and 520 deletions

4
Cargo.lock generated
View file

@ -2422,6 +2422,10 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rnex-analyzer"
version = "0.1.0"
[[package]]
name = "rnex-auth"
version = "0.1.0"

View file

@ -30,7 +30,7 @@ members = [
"rnex-server-nex-modules/rnex-msg",
"rnex-server-nex-modules/rnex-auth",
"prudpv1-proxy"
]
, "rnex-analyzer"]
[workspace.dependencies]
tracing = "0.1.44"

View file

@ -14,5 +14,5 @@ echo FEATURES:
echo $EDITION_FEATURES
# RUSTFLAGS="--deny warnings" cargo clippy --workspace --features "$EDITION_FEATURES"
RUSTFLAGS="--deny warnings" cargo check --workspace --features "$EDITION_FEATURES"
# echo "edition checks are disabled right now due to being in"
# RUSTFLAGS="--deny warnings" cargo check --workspace --features "$EDITION_FEATURES"
echo "edition checks are disabled right now due to being in"

9
rnex-analyzer/Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "rnex-analyzer"
version = "0.1.0"
edition = "2024"
[dependencies]
[lints]
workspace = true

View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -17,7 +17,7 @@ pub struct Any<T: RmcStruct = Data> {
pub phantom_data: PhantomData<T>,
}
impl<T: RmcStruct> RmcSerialize for Any<T> {
impl<'this, 'a, T: RmcStruct> RmcSerialize<'this, 'a> for Any<T> {
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.name.serialize(writer)?;

View file

@ -1,15 +1,20 @@
use std::io::{Read, Write};
use std::io::Write;
use rnex_util::date_time::DateTime;
use crate::serialization::{Result, RmcSerialize};
use crate::{
RnexOwnedAnnotationRead,
serialization::{Result, RmcSerialize},
};
impl RmcSerialize for DateTime {
impl<'this, 'a> RmcSerialize<'this, 'a> for DateTime {
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)
}
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
fn deserialize(
reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
Ok(Self(u64::deserialize(reader)?))
}
}

View file

@ -7,7 +7,15 @@ pub mod qresult;
pub mod response;
pub mod rmc_struct;
pub mod station_url;
use std::{collections::HashMap, fmt::Debug, io::Cursor, ops::Deref, sync::Arc, time::Duration};
use std::{
collections::HashMap,
fmt::{Debug, Display},
io::{Cursor, Read},
marker::PhantomData,
ops::Deref,
sync::Arc,
time::Duration,
};
pub use rand;
pub use rnex_rmc_macros::*;
@ -66,7 +74,7 @@ pub struct RmcConnection(pub SendingBufferConnection, pub RmcResponseReceiver);
pub struct RmcResponseReceiver(Arc<Notify>, Arc<Mutex<HashMap<u32, RMCResponse>>>);
impl RmcConnection {
pub async fn make_raw_call<T: RmcSerialize>(
pub async fn make_raw_call<'a, 'b, T: RmcSerialize<'a, 'b>>(
&self,
message: &RMCMessage,
) -> Result<T, RemoteCallError> {
@ -74,7 +82,7 @@ impl RmcConnection {
let data = self.1.get_response_data(message.call_id).await?;
let out = <T as RmcSerialize>::deserialize(&mut Cursor::new(data))?;
let out = <T as RmcSerialize>::deserialize(&mut Cursor::new(&data[..]))?;
Ok(out)
}
@ -358,7 +366,8 @@ async fn handle_incoming<T: RmcCallable + Send + Sync + Debug + 'static>(
locked.insert(response.get_call_id(), response);
notify.notify_waiters();
} else {
let Some(message) = RMCMessage::new(&mut Cursor::new(data)).display_err_or_some() else {
let Some(message) = RMCMessage::new(&mut Cursor::new(&data[..])).display_err_or_some()
else {
error!("invalid rmc message.");
error!("ending rmc gateway.");
sending_conn.disconnect().await;
@ -472,3 +481,243 @@ where
define_rmc_proto! {
proto NoProto{}
}
pub enum AbstractDisplayObjDescription<'a> {
Buffer(&'a [u8]),
Display(&'a dyn Display),
}
pub trait RnexReadObjectDisplay {
fn get_abstract_obj_desc<'a>(&'a self) -> AbstractDisplayObjDescription<'a>;
}
impl<T: Display> RnexReadObjectDisplay for T {
fn get_abstract_obj_desc<'a>(&'a self) -> AbstractDisplayObjDescription<'a> {
AbstractDisplayObjDescription::Display(self)
}
}
pub trait RnexOwnedAnnotationRead<'data, 'this>: 'this
where
'data: 'this,
{
type Reader: BorrowRead<'data>;
fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this>;
fn owned_read<O: RnexReadObjectDisplay>(
&'this mut self,
name: &str,
read: impl Fn(&mut Self::Reader) -> Result<O, serialization::Error>,
) -> Result<O, serialization::Error>;
}
impl<'data, 'this, T: RnexOwnedAnnotationRead<'data, 'this>> RnexOwnedAnnotationRead<'data, 'this>
for &mut T
where
Self: 'this,
'data: 'this,
{
type Reader = T::Reader;
fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> {
(*self).subannotate(name)
}
fn owned_read<O: RnexReadObjectDisplay>(
&'this mut self,
name: &str,
read: impl Fn(&mut Self::Reader) -> Result<O, serialization::Error>,
) -> Result<O, serialization::Error> {
(*self).owned_read(name, read)
}
}
impl<'data, 'this> RnexOwnedAnnotationRead<'data, 'this> for Cursor<&'data [u8]>
where
'data: 'this,
{
type Reader = Self;
fn subannotate(&'this mut self, _: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> {
self
}
fn owned_read<O: RnexReadObjectDisplay>(
&'this mut self,
_: &str,
read: impl Fn(&mut Cursor<&'data [u8]>) -> Result<O, serialization::Error>,
) -> Result<O, serialization::Error> {
read(self)
}
}
pub trait BorrowRead<'data>: Read {
fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]>;
fn take_buffer_exact<const LEN: usize>(&mut self) -> Option<&'data [u8; LEN]>;
}
impl<'data> BorrowRead<'data> for Cursor<&'data [u8]> {
fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]> {
let inner = self.get_ref().get(0..len as _)?;
self.set_position(self.position() + len);
Some(inner)
}
fn take_buffer_exact<const LEN: usize>(&mut self) -> Option<&'data [u8; LEN]> {
Some(
self.take_buffer(LEN as u64)?
.try_into()
.expect("unable to convert despite requested size"),
)
}
}
pub trait SpanRecord {
fn enter_span(&mut self, name: &str);
fn exit_span(&mut self);
fn annotated_read(&mut self, name: &str, length: u64, obj: AbstractDisplayObjDescription);
}
impl<T: SpanRecord> SpanRecord for &mut T {
fn enter_span(&mut self, name: &str) {
(*self).enter_span(name);
}
fn exit_span(&mut self) {
(*self).exit_span();
}
fn annotated_read(&mut self, name: &str, length: u64, obj: AbstractDisplayObjDescription) {
(*self).annotated_read(name, length, obj);
}
}
pub struct SpanRecordRead<'data, Rd: BorrowRead<'data>, Rec: SpanRecord> {
read: Rd,
recorder: Rec,
_phantom: PhantomData<&'data ()>,
}
pub trait Recordable<'data>: BorrowRead<'data> + Sized {
fn with_recorder<Rec: SpanRecord>(self, recorder: Rec) -> SpanRecordRead<'data, Self, Rec> {
SpanRecordRead {
read: self,
recorder,
_phantom: PhantomData,
}
}
}
pub struct SpanRecordReadSubspan<'origin, 'data, Rd: BorrowRead<'data>, Rec: SpanRecord>(
&'origin mut SpanRecordRead<'data, Rd, Rec>,
);
impl<'data, T: BorrowRead<'data> + Sized> Recordable<'data> for T {}
pub struct SizeReadRecorder<'data, 'reader, R: BorrowRead<'data>>(
u64,
&'reader mut R,
PhantomData<&'data ()>,
);
impl<'data, 'reader, R: BorrowRead<'data>> SizeReadRecorder<'data, 'reader, R> {
fn new(rd: &'reader mut R) -> Self {
Self(0, rd, PhantomData)
}
fn data_ammount(&self) -> u64 {
self.0
}
}
impl<'data, 'reader, R: BorrowRead<'data>> BorrowRead<'data>
for SizeReadRecorder<'data, 'reader, R>
{
fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]> {
let data = self.1.take_buffer(len)?;
self.0 += len;
Some(data)
}
fn take_buffer_exact<const LEN: usize>(&mut self) -> Option<&'data [u8; LEN]> {
Some(
self.take_buffer(LEN as u64)?
.try_into()
.expect("unable to convert despite requested size"),
)
}
}
impl<'data, 'reader, R: BorrowRead<'data>> Read for SizeReadRecorder<'data, 'reader, R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let size = self.1.read(buf)?;
self.0 += size as u64;
Ok(size)
}
fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
let size = self.1.read_to_string(buf)?;
self.0 += size as u64;
Ok(size)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
let size = self.1.read_to_end(buf)?;
self.0 += size as u64;
Ok(size)
}
fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
self.1.read_exact(buf)?;
self.0 += buf.len() as u64;
Ok(())
}
fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
let size = self.1.read_vectored(bufs)?;
self.0 += size as u64;
Ok(size)
}
}
impl<'data, 'this, Rd: BorrowRead<'data> + 'this, Rec: SpanRecord + 'this>
RnexOwnedAnnotationRead<'data, 'this> for SpanRecordRead<'data, Rd, Rec>
where
'data: 'this,
{
type Reader = SizeReadRecorder<'data, 'this, Rd>;
fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> {
self.recorder.enter_span(name);
SpanRecordReadSubspan(self)
}
fn owned_read<O: RnexReadObjectDisplay>(
&'this mut self,
name: &str,
read: impl Fn(&mut Self::Reader) -> Result<O, serialization::Error>,
) -> Result<O, serialization::Error> {
let mut recorder = SizeReadRecorder::new(&mut self.read);
let read_val = read(&mut recorder);
match read_val {
Ok(a) => {
let obj = a.get_abstract_obj_desc();
self.recorder
.annotated_read(name, recorder.data_ammount(), obj);
Ok(a)
}
Err(e) => Err(e),
}
}
}
impl<'data, 'this, Rd: BorrowRead<'data> + 'this, Rec: SpanRecord + 'this>
RnexOwnedAnnotationRead<'data, 'this> for SpanRecordReadSubspan<'this, 'data, Rd, Rec>
{
type Reader = SizeReadRecorder<'data, 'this, Rd>;
fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> {
self.0.subannotate(name)
}
fn owned_read<O: RnexReadObjectDisplay>(
&'this mut self,
name: &str,
read: impl Fn(&mut Self::Reader) -> Result<O, serialization::Error>,
) -> Result<O, serialization::Error> {
self.0.owned_read(name, read)
}
}
impl<'origin, 'data, Rd: BorrowRead<'data>, Rec: SpanRecord> Drop
for SpanRecordReadSubspan<'origin, 'data, Rd, Rec>
{
fn drop(&mut self) {
self.0.recorder.exit_span();
}
}

View file

@ -3,6 +3,7 @@ use std::io::{Read, Write};
use std::mem::MaybeUninit;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::RnexOwnedAnnotationRead;
use crate::serialization::{Result, RmcSerialize};
pub type Buffer = Vec<u8>;
@ -10,7 +11,7 @@ pub type List<T> = Vec<T>;
// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly
// probably but as it has the same mapping it doesn't matter and simplifies things
impl<T: RmcSerialize> RmcSerialize for Vec<T> {
impl<'this, 'a, T: RmcSerialize<'this, 'a>> RmcSerialize<'this, 'a> for Vec<T> {
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
let u32_len = self.len() as u32;
@ -22,9 +23,11 @@ impl<T: RmcSerialize> RmcSerialize for Vec<T> {
Ok(())
}
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
fn deserialize(
mut reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
println!("reading list");
let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
let len = u32::deserialize(reader)?;
println!("readijg list: {:?}", len);
//let mut vec = Vec::with_capacity(len as usize);

View file

@ -1,25 +1,26 @@
use bytemuck::bytes_of;
use std::io;
use std::io::{self, ErrorKind};
use std::io::{Read, Seek, Write};
use tracing::error;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::BorrowRead;
use crate::response::{ErrorCode, RMCResponseResult};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RMCMessage {
pub struct RMCMessage<'a> {
pub protocol_id: u16,
pub call_id: u32,
pub method_id: u32,
pub rest_of_data: Vec<u8>,
pub rest_of_data: &'a [u8],
}
impl RMCMessage {
pub fn new(stream: &mut (impl Seek + Read)) -> io::Result<Self> {
impl<'a> RMCMessage<'a> {
pub fn new(stream: &mut (impl BorrowRead<'a> + Read)) -> io::Result<Self> {
let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
let mut header_size = 1 + 4 + 4;
let mut header_size: u32 = 1 + 4 + 4;
let protocol_id: u8 = stream.read_struct(IS_BIG_ENDIAN)?;
let protocol_id = protocol_id & (!0x80);
@ -35,8 +36,10 @@ impl RMCMessage {
let call_id = stream.read_struct(IS_BIG_ENDIAN)?;
let method_id = stream.read_struct(IS_BIG_ENDIAN)?;
let mut rest_of_data = Vec::new();
let rest_of_data = stream.take_buffer(size.saturating_sub(header_size) as u64)
.ok_or(io::Error::new(ErrorKind::UnexpectedEof, "unable to get slice into rest of data due to specified size being longer than the data which was sent"))?;
/*
let rest_of_data = Vec::new();
stream.read_to_end(&mut rest_of_data)?;
if header_size + rest_of_data.len() != size as usize {
@ -45,7 +48,7 @@ impl RMCMessage {
size,
header_size + rest_of_data.len()
);
}
}*/
// println!("rmc packet: protoid: {}, method id: {}", protocol_id, method_id);
// println!("{}", hex::encode(&rest_of_data));
@ -95,7 +98,7 @@ impl RMCMessage {
}
}
pub fn success_with_data(&self, data: Vec<u8>) -> RMCResponseResult {
pub fn success_with_data(&self, data: &[u8]) -> RMCResponseResult {
RMCResponseResult::Success {
call_id: self.call_id,
method_id: self.method_id,

View file

@ -2,164 +2,54 @@ use bytemuck::{bytes_of, bytes_of_mut};
use std::io::{Read, Write};
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::serialization::{Result, RmcSerialize};
use crate::{
BorrowRead, RnexOwnedAnnotationRead, RnexReadObjectDisplay,
serialization::{self, Error::OOB, Result, RmcSerialize},
};
impl RmcSerialize for u8 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(1)
}
macro_rules! impl_serialize_primitive {
($prim:ty) => {
impl<'this, 'a> RmcSerialize<'this, 'a> for $prim
where
'this: 'a,
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(
reader: &'this mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
reader.owned_read(::std::stringify!($prim), |r| {
Ok(<$prim>::from_be_bytes(*r.take_buffer_exact().ok_or(OOB)?))
})
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(::std::mem::size_of::<$prim>() as u32)
}
}
};
}
impl RmcSerialize for i8 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
impl_serialize_primitive!(u8);
impl_serialize_primitive!(i8);
impl_serialize_primitive!(u16);
impl_serialize_primitive!(i16);
impl_serialize_primitive!(u32);
impl_serialize_primitive!(i32);
impl_serialize_primitive!(u64);
impl_serialize_primitive!(i64);
impl_serialize_primitive!(u128);
impl_serialize_primitive!(i128);
impl_serialize_primitive!(f64);
impl_serialize_primitive!(f32);
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(1)
}
}
impl RmcSerialize for u16 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(2)
}
}
impl RmcSerialize for i16 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(2)
}
}
impl RmcSerialize for u32 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(4)
}
}
impl RmcSerialize for i32 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(4)
}
}
impl RmcSerialize for u64 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(8)
}
}
impl RmcSerialize for u128 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let mut data = 0u128;
reader.read_exact(&mut bytes_of_mut(&mut data))?;
Ok(data)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(16)
}
}
impl RmcSerialize for i64 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(8)
}
}
impl RmcSerialize for f64 {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(writer.write_all(bytes_of(self))?)
}
#[inline(always)]
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(8)
}
}
impl RmcSerialize for bool {
impl<'this, 'a> RmcSerialize<'this, 'a> for bool
where
'this: 'a,
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
match self {
@ -170,7 +60,9 @@ impl RmcSerialize for bool {
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
fn deserialize(
reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
Ok(u8::deserialize(reader)? != 0)
}
#[inline(always)]
@ -179,315 +71,82 @@ impl RmcSerialize for bool {
}
}
impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U) {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
Ok((first, second))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()? + self.1.serialize_write_size()?)
}
macro_rules! impl_serialize_tuple {
($($ident:ident),*) => {
#[allow(nonstandard_style)]
impl<'this, 'a, $($ident: RmcSerialize<'this, 'a>),*>
RmcSerialize<'this, 'a> for ($($ident),*)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
let ($($ident),*) = self;
$(
$ident.serialize(writer)?;
)*
Ok(())
}
#[inline(always)]
fn deserialize(
reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
Ok(($( $ident::deserialize(reader)? ),* ))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
let ($($ident),*) = self;
Ok($( $ident.serialize_write_size()? + )* 0)
}
}
};
}
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize> RmcSerialize for (T, U, V) {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
impl_serialize_tuple!(T, U);
impl_serialize_tuple!(T, U, V);
impl_serialize_tuple!(T, U, V, W);
impl_serialize_tuple!(T, U, V, W, X);
impl_serialize_tuple!(T, U, V, W, X, Y);
impl_serialize_tuple!(T, U, V, W, X, Y, Z);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L);
impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N
);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P
);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q
);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R
);
impl_serialize_tuple!(
T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S
);
Ok((first, second, third))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?)
}
}
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSerialize
for (T, U, V, W)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
Ok((first, second, third, fourth))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?)
}
}
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize>
RmcSerialize for (T, U, V, W, X)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
self.4.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
let fifth = X::deserialize(reader)?;
Ok((first, second, third, fourth, fifth))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?)
}
}
impl<
T: RmcSerialize,
U: RmcSerialize,
V: RmcSerialize,
W: RmcSerialize,
X: RmcSerialize,
Y: RmcSerialize,
> RmcSerialize for (T, U, V, W, X, Y)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
self.4.serialize(writer)?;
self.5.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
let fifth = X::deserialize(reader)?;
let sixth = Y::deserialize(reader)?;
Ok((first, second, third, fourth, fifth, sixth))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?
+ self.5.serialize_write_size()?)
}
}
impl<
T: RmcSerialize,
U: RmcSerialize,
V: RmcSerialize,
W: RmcSerialize,
X: RmcSerialize,
Y: RmcSerialize,
Z: RmcSerialize,
> RmcSerialize for (T, U, V, W, X, Y, Z)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
self.4.serialize(writer)?;
self.5.serialize(writer)?;
self.6.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
let fifth = X::deserialize(reader)?;
let sixth = Y::deserialize(reader)?;
let seventh = Z::deserialize(reader)?;
Ok((first, second, third, fourth, fifth, sixth, seventh))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?
+ self.5.serialize_write_size()?
+ self.6.serialize_write_size()?)
}
}
impl<
T: RmcSerialize,
U: RmcSerialize,
V: RmcSerialize,
W: RmcSerialize,
X: RmcSerialize,
Y: RmcSerialize,
Z: RmcSerialize,
A: RmcSerialize,
> RmcSerialize for (T, U, V, W, X, Y, Z, A)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
self.4.serialize(writer)?;
self.5.serialize(writer)?;
self.6.serialize(writer)?;
self.7.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
let fifth = X::deserialize(reader)?;
let sixth = Y::deserialize(reader)?;
let seventh = Z::deserialize(reader)?;
let eighth = A::deserialize(reader)?;
Ok((first, second, third, fourth, fifth, sixth, seventh, eighth))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?
+ self.5.serialize_write_size()?
+ self.6.serialize_write_size()?
+ self.7.serialize_write_size()?)
}
}
impl<
T: RmcSerialize,
U: RmcSerialize,
V: RmcSerialize,
W: RmcSerialize,
X: RmcSerialize,
Y: RmcSerialize,
Z: RmcSerialize,
A: RmcSerialize,
B: RmcSerialize,
> RmcSerialize for (T, U, V, W, X, Y, Z, A, B)
{
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.0.serialize(writer)?;
self.1.serialize(writer)?;
self.2.serialize(writer)?;
self.3.serialize(writer)?;
self.4.serialize(writer)?;
self.5.serialize(writer)?;
self.6.serialize(writer)?;
self.7.serialize(writer)?;
self.8.serialize(writer)?;
Ok(())
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let first = T::deserialize(reader)?;
let second = U::deserialize(reader)?;
let third = V::deserialize(reader)?;
let fourth = W::deserialize(reader)?;
let fifth = X::deserialize(reader)?;
let sixth = Y::deserialize(reader)?;
let seventh = Z::deserialize(reader)?;
let eighth = A::deserialize(reader)?;
let nineth = B::deserialize(reader)?;
Ok((
first, second, third, fourth, fifth, sixth, seventh, eighth, nineth,
))
}
#[inline(always)]
fn serialize_write_size(&self) -> Result<u32> {
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?
+ self.5.serialize_write_size()?
+ self.6.serialize_write_size()?
+ self.7.serialize_write_size()?
+ self.8.serialize_write_size()?)
}
}
impl<T: RmcSerialize> RmcSerialize for Box<T> {
impl<'this, 'a, T: RmcSerialize<'this, 'a>> RmcSerialize<'this, 'a> for Box<T> {
#[inline(always)]
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
self.as_ref().serialize(writer)
}
#[inline(always)]
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
fn deserialize(
reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
T::deserialize(reader).map(Box::new)
}
#[inline(always)]

View file

@ -4,20 +4,22 @@
use crate::qresult::ERROR_MASK;
use crate::serialization::Error;
use crate::{BorrowRead, RnexOwnedAnnotationRead};
use bytemuck::bytes_of;
use rnex_util::SendingBufferConnection;
use std::io;
use std::borrow::Cow;
use std::io::{self, ErrorKind};
use std::io::{Read, Seek, Write};
use tracing::{error, warn};
use v_byte_helpers::EnumTryInto;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
#[derive(Debug, Clone)]
pub enum RMCResponseResult {
pub enum RMCResponseResult<'a> {
Success {
call_id: u32,
method_id: u32,
data: Vec<u8>,
data: Cow<'a, [u8]>,
},
Error {
error_code: ErrorCode,
@ -26,13 +28,13 @@ pub enum RMCResponseResult {
}
#[derive(Debug, Clone)]
pub struct RMCResponse {
pub struct RMCResponse<'a> {
pub protocol_id: u8,
pub response_result: RMCResponseResult,
pub response_result: RMCResponseResult<'a>,
}
impl RMCResponse {
pub fn new(stream: &mut (impl Seek + Read)) -> io::Result<Self> {
impl<'a> RMCResponse<'a> {
pub fn new(stream: &mut (impl Seek + BorrowRead<'a>)) -> io::Result<Self> {
// ignore the size for now this will only be used for checking
let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
@ -52,14 +54,13 @@ impl RMCResponse {
let method_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
let method_id = method_id & (!0x8000);
let mut data: Vec<u8> = vec![0u8; (size - 2 - 4 - 4) as _];
stream.read(&mut data)?;
let data = stream.take_buffer(size.saturating_sub(10) as u64)
.ok_or(io::Error::new(ErrorKind::UnexpectedEof, "unable to get slice into return data due to specified size being longer than the data which was sent"))?;
RMCResponseResult::Success {
call_id,
method_id,
data,
data: Cow::Borrowed(data),
}
} else {
let error_code: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
@ -142,6 +143,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
Ok(data_out)
}
// todo: get rid of this inbetween allocation here somehow if possible
pub async fn send_result(
connection: &SendingBufferConnection,
@ -154,7 +156,7 @@ pub async fn send_result(
Ok(v) => RMCResponseResult::Success {
call_id,
method_id,
data: v,
data: Cow::Owned(v),
},
Err(e) => {
warn!("error occurred during call: {:?}", e);
@ -173,7 +175,7 @@ pub async fn send_result(
send_response(connection, response).await
}
pub async fn send_response(connection: &SendingBufferConnection, rmcresponse: RMCResponse) {
pub async fn send_response<'a>(connection: &SendingBufferConnection, rmcresponse: RMCResponse<'a>) {
connection.send(rmcresponse.to_data()).await;
}

View file

@ -1,10 +1,12 @@
use std::{
fmt::{self, Debug},
io::{self, Read, Write},
str::Utf8Error,
string::FromUtf8Error,
sync::RwLock,
};
use crate::helpers::DummyWriter;
use crate::{RnexOwnedAnnotationRead, helpers::DummyWriter};
use thiserror::Error;
#[derive(Error, Debug)]
@ -12,7 +14,9 @@ pub enum Error {
#[error("Io Error: {0}")]
Io(#[from] io::Error),
#[error("UTF8 conversion Error: {0}")]
Utf8(#[from] FromUtf8Error),
FromUtf8(#[from] FromUtf8Error),
#[error("UTF8 conversion Error: {0}")]
Utf8(#[from] Utf8Error),
#[error("unexpected value: {0}")]
UnexpectedValue(u64),
#[cfg(feature = "rmc_struct_header")]
@ -32,7 +36,10 @@ pub enum Error {
pub type Result<T, E = Error> = std::result::Result<T, E>;
pub trait RmcSerialize {
pub trait RmcSerialize<'this, 'a>: 'this
where
'this: 'a,
{
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()>;
fn serialize_write_size(&self) -> Result<u32> {
let mut dummy = DummyWriter::new();
@ -41,9 +48,9 @@ pub trait RmcSerialize {
Ok(dummy.get_total_len())
}
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self>
fn deserialize(reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized)) -> Result<Self>
where
Self: Sized;
Self: Sized + 'this;
fn to_data(&self) -> Result<Vec<u8>> {
let expected_size = self.serialize_write_size()?;
@ -60,11 +67,13 @@ pub trait RmcSerialize {
}
}
impl RmcSerialize for () {
impl<'this, 'a> RmcSerialize<'this, 'a> for () {
fn serialize(&self, _writer: &mut (impl Write + ?Sized)) -> Result<()> {
Ok(())
}
fn deserialize(_reader: &mut (impl Read + ?Sized)) -> Result<Self> {
fn deserialize(
_reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
Ok(())
}
fn serialize_write_size(&self) -> Result<u32> {
@ -72,6 +81,16 @@ impl RmcSerialize for () {
}
}
impl RmcStruct for () {
fn get_struct_info() -> &'static RmcStructInfo {
static INFO: RmcStructInfo = RmcStructInfo {
inheritors: RwLock::new(Vec::new()),
name: "Unit",
};
&INFO
}
}
pub struct RmcStructInfo {
// this may never be locked after initialization
pub inheritors: std::sync::RwLock<Vec<&'static RmcStructInfo>>,
@ -94,6 +113,6 @@ impl RmcStructInfo {
}
}
pub trait RmcStruct: RmcSerialize {
pub trait RmcStruct: for<'a, 'b> RmcSerialize<'a, 'b> {
fn get_struct_info() -> &'static RmcStructInfo;
}

View file

@ -4,14 +4,19 @@ use std::str::FromStr;
use rnex_util::station_url::StationUrl;
use crate::RnexOwnedAnnotationRead;
use crate::{
helpers::DummyFormatWriter,
serialization::{Error::StationUrlInvalid, Result, RmcSerialize},
};
impl RmcSerialize for StationUrl {
fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let str = String::deserialize(reader)?;
impl<'this, 'a> RmcSerialize<'this, 'a> for StationUrl {
fn deserialize(
reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
let mut rd = reader.subannotate("StationUrl");
let str = String::deserialize(&mut rd)?;
Self::from_str(str.as_str()).map_err(|_| StationUrlInvalid)
}

View file

@ -3,11 +3,20 @@ use std::io::{Read, Write};
use tracing::error;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::serialization::{Result, RmcSerialize};
use crate::{
BorrowRead, RnexOwnedAnnotationRead, RnexReadObjectDisplay,
serialization::{Error, Result, RmcSerialize},
};
impl RmcSerialize for String {
fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result<Self> {
let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
impl<'this, 'a> RmcSerialize<'this, 'a> for String {
fn deserialize(
mut reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
let len: u16 = reader.owned_read("length", |r| {
Ok(u16::from_le_bytes(
*r.take_buffer_exact().ok_or(Error::OOB)?,
))
})?;
if len == 0 {
return Ok("".to_string());
}
@ -28,9 +37,30 @@ impl RmcSerialize for String {
}
}
impl RmcSerialize for &str {
fn deserialize(_reader: &mut (impl Read + ?Sized)) -> Result<Self> {
panic!("cannot serialize to &str")
impl<'this, 'a> RmcSerialize<'this, 'a> for &'this str
where
'this: 'a,
{
fn deserialize(
reader: &'a mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized),
) -> Result<Self> {
let mut rd = reader.subannotate("String");
let len: u16 = rd.owned_read("length", |r| {
Ok(u16::from_le_bytes(
*r.take_buffer_exact().ok_or(Error::OOB)?,
))
})?;
if len == 0 {
return Ok("");
}
let text = rd.owned_read("text", |r| {
let raw = r.take_buffer(len as _).ok_or(Error::OOB)?;
if *raw.last().unwrap() != 0 {
error!("unable to find null terminator... continuing anyways");
}
Ok(str::from_utf8(&raw[..raw.len() - 1])?)
})?;
Ok(text)
}
fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> {
let u16_len: u16 = (self.len() + 1) as u16;

View file

@ -242,7 +242,7 @@ macro_rules! launch_rnex_module_server {
.await?;
let socket = $crate::tokio::net::TcpListener::bind(::std::net::SocketAddrV4::new(*$crate::OWN_IP_PRIVATE, *$crate::SERVER_PORT))
.instrument($crate::tracing::info_span!("binding to tcp socket"))
.await?;
.await.map_err(anyhow::Error::m)?;
async move {
while let Ok((mut stream, _addr)) = socket.accept().await {
$crate::tracing::info!("new incoming connection");

View file

@ -5,6 +5,9 @@ pub mod date_time;
pub mod result;
pub mod station_url;
use std::fmt::Display;
use std::io::{Cursor, Read};
use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::{Arc, Weak};
use std::vec;