add debug logging to ticket generation for debugging
This commit is contained in:
parent
b6b7d2559d
commit
4ad883a54d
10 changed files with 223 additions and 127 deletions
|
|
@ -2,17 +2,18 @@
|
|||
// attributes but this gets it to not complain anymore
|
||||
#![allow(unused_parens)]
|
||||
|
||||
use std::io;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use std::mem::transmute;
|
||||
use bytemuck::bytes_of;
|
||||
use log::error;
|
||||
use v_byte_helpers::EnumTryInto;
|
||||
use v_byte_helpers::{ReadExtensions, IS_BIG_ENDIAN};
|
||||
use crate::rmc::response::ErrorCode::Core_Exception;
|
||||
use crate::rmc::structures::qresult::ERROR_MASK;
|
||||
use crate::util::SendingBufferConnection;
|
||||
use bytemuck::bytes_of;
|
||||
use log::error;
|
||||
use std::io;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use std::mem::transmute;
|
||||
use v_byte_helpers::EnumTryInto;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RMCResponseResult {
|
||||
Success {
|
||||
call_id: u32,
|
||||
|
|
@ -25,13 +26,14 @@ pub enum RMCResponseResult {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RMCResponse {
|
||||
pub protocol_id: u8,
|
||||
pub response_result: RMCResponseResult,
|
||||
}
|
||||
|
||||
impl RMCResponse {
|
||||
pub fn new(stream: &mut (impl Seek + Read)) -> io::Result<Self>{
|
||||
pub fn new(stream: &mut (impl Seek + Read)) -> io::Result<Self> {
|
||||
// ignore the size for now this will only be used for checking
|
||||
let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ impl RMCResponse {
|
|||
|
||||
let is_success: u8 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let response_result = if is_success == 0x01{
|
||||
let response_result = if is_success == 0x01 {
|
||||
let call_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
let method_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
let method_id = method_id & (!0x8000);
|
||||
|
|
@ -55,11 +57,10 @@ impl RMCResponse {
|
|||
|
||||
stream.read(&mut data)?;
|
||||
|
||||
|
||||
RMCResponseResult::Success {
|
||||
call_id,
|
||||
method_id,
|
||||
data
|
||||
data,
|
||||
}
|
||||
} else {
|
||||
let error_code: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
|
@ -68,7 +69,7 @@ impl RMCResponse {
|
|||
|
||||
RMCResponseResult::Error {
|
||||
error_code: {
|
||||
match ErrorCode::try_from(error_code){
|
||||
match ErrorCode::try_from(error_code) {
|
||||
Ok(v) => v,
|
||||
Err(()) => {
|
||||
error!("invalid error code {:#010x}", error_code);
|
||||
|
|
@ -77,36 +78,35 @@ impl RMCResponse {
|
|||
}
|
||||
},
|
||||
call_id,
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self{
|
||||
Ok(Self {
|
||||
protocol_id,
|
||||
response_result
|
||||
response_result,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_call_id(&self) -> u32{
|
||||
match &self.response_result{
|
||||
RMCResponseResult::Success { call_id, ..} => *call_id,
|
||||
RMCResponseResult::Error { call_id, .. } => *call_id
|
||||
pub fn get_call_id(&self) -> u32 {
|
||||
match &self.response_result {
|
||||
RMCResponseResult::Success { call_id, .. } => *call_id,
|
||||
RMCResponseResult::Error { call_id, .. } => *call_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_data(self) -> Vec<u8> {
|
||||
generate_response(self.protocol_id, self.response_result).expect("failed to generate response")
|
||||
generate_response(self.protocol_id, self.response_result)
|
||||
.expect("failed to generate response")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Result<Vec<u8>> {
|
||||
let size = 1 + 1 + match &response {
|
||||
RMCResponseResult::Success {
|
||||
data,
|
||||
..
|
||||
} => 4 + 4 + data.len(),
|
||||
RMCResponseResult::Error { .. } => 4 + 4,
|
||||
};
|
||||
let size = 1
|
||||
+ 1
|
||||
+ match &response {
|
||||
RMCResponseResult::Success { data, .. } => 4 + 4 + data.len(),
|
||||
RMCResponseResult::Error { .. } => 4 + 4,
|
||||
};
|
||||
|
||||
let mut data_out = Vec::with_capacity(size + 4);
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
|
|||
RMCResponseResult::Success {
|
||||
call_id,
|
||||
method_id,
|
||||
data
|
||||
data,
|
||||
} => {
|
||||
data_out.push(1);
|
||||
data_out.write_all(bytes_of(&call_id))?;
|
||||
|
|
@ -129,7 +129,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
|
|||
}
|
||||
RMCResponseResult::Error {
|
||||
call_id,
|
||||
error_code
|
||||
error_code,
|
||||
} => {
|
||||
data_out.push(0);
|
||||
let error_code_val: u32 = error_code.into();
|
||||
|
|
@ -151,23 +151,21 @@ pub async fn send_result(
|
|||
method_id: u32,
|
||||
call_id: u32,
|
||||
) {
|
||||
|
||||
let response_result = match result {
|
||||
Ok(v) => RMCResponseResult::Success {
|
||||
call_id,
|
||||
method_id,
|
||||
data: v
|
||||
data: v,
|
||||
},
|
||||
Err(e) => RMCResponseResult::Error {
|
||||
call_id,
|
||||
error_code: e.into(),
|
||||
},
|
||||
Err(e) =>
|
||||
RMCResponseResult::Error {
|
||||
call_id,
|
||||
error_code: e.into()
|
||||
}
|
||||
};
|
||||
|
||||
let response = RMCResponse{
|
||||
let response = RMCResponse {
|
||||
response_result,
|
||||
protocol_id
|
||||
protocol_id,
|
||||
};
|
||||
|
||||
send_response(connection, response).await
|
||||
|
|
@ -177,7 +175,6 @@ pub async fn send_response(connection: &SendingBufferConnection, rmcresponse: RM
|
|||
connection.send(rmcresponse.to_data()).await;
|
||||
}
|
||||
|
||||
|
||||
//taken from kinnays error list directly
|
||||
#[allow(nonstandard_style)]
|
||||
#[repr(u32)]
|
||||
|
|
@ -464,25 +461,23 @@ impl Into<u32> for ErrorCode {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hmac::digest::consts::U5;
|
||||
use hmac::digest::KeyInit;
|
||||
use rc4::{Rc4, StreamCipher};
|
||||
use crate::rmc::response::ErrorCode;
|
||||
use hmac::digest::KeyInit;
|
||||
use hmac::digest::consts::U5;
|
||||
use rc4::{Rc4, StreamCipher};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let data_orig = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 69, 4, 20];
|
||||
let mut data = data_orig;
|
||||
|
||||
let mut rc4: Rc4<U5> =
|
||||
Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key");
|
||||
let mut rc4: Rc4<U5> = Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key");
|
||||
|
||||
rc4.apply_keystream(&mut data);
|
||||
|
||||
assert_ne!(data_orig, data);
|
||||
|
||||
let mut rc4: Rc4<U5> =
|
||||
Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key");
|
||||
let mut rc4: Rc4<U5> = Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key");
|
||||
|
||||
rc4.apply_keystream(&mut data);
|
||||
|
||||
|
|
@ -494,4 +489,4 @@ mod test {
|
|||
let val: u32 = ErrorCode::Core_Unknown.into();
|
||||
assert_eq!(val, 0x00010001)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
use crate::rmc::structures::RmcSerialize;
|
||||
use bytemuck::bytes_of;
|
||||
use std::io::{Read, Write};
|
||||
use std::mem::MaybeUninit;
|
||||
use bytemuck::bytes_of;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
|
||||
|
||||
// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly
|
||||
// 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<T: RmcSerialize> RmcSerialize for Vec<T> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
let u32_len = self.len() as u32;
|
||||
|
||||
writer.write_all(bytes_of(&u32_len))?;
|
||||
for e in self{
|
||||
for e in self {
|
||||
e.serialize(writer)?;
|
||||
}
|
||||
|
||||
|
|
@ -21,27 +19,31 @@ impl<T: RmcSerialize> RmcSerialize for Vec<T>{
|
|||
}
|
||||
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
println!("reading list");
|
||||
let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
println!("readijg list: {:?}", len);
|
||||
//let mut vec = Vec::with_capacity(len as usize);
|
||||
|
||||
let vec = (0..len).map(|_| T::deserialize(reader)).collect::<Result<Vec<_>, _>>()?;
|
||||
let vec: Vec<T> = (0..len)
|
||||
.map(|_| T::deserialize(reader))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
let mut val = 0u32;
|
||||
for i in self{
|
||||
for i in self {
|
||||
val += i.serialize_write_size()?;
|
||||
}
|
||||
Ok(4 + val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
|
||||
impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN] {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
for i in 0..LEN{
|
||||
for i in 0..LEN {
|
||||
self[i].serialize(writer)?;
|
||||
}
|
||||
|
||||
|
|
@ -51,20 +53,20 @@ impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
|
|||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let mut arr = [const { MaybeUninit::<T>::uninit() }; LEN];
|
||||
|
||||
for i in 0..LEN{
|
||||
for i in 0..LEN {
|
||||
arr[i] = MaybeUninit::new(T::deserialize(reader)?);
|
||||
}
|
||||
|
||||
// all of the elements are now initialized so it is safe to assume they are initialized
|
||||
|
||||
let arr = arr.map(|v| unsafe{ v.assume_init() });
|
||||
let arr = arr.map(|v| unsafe { v.assume_init() });
|
||||
|
||||
Ok(arr)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
let mut val = 0u32;
|
||||
for i in self{
|
||||
for i in self {
|
||||
val += i.serialize_write_size()?;
|
||||
}
|
||||
Ok(val)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::{fmt, io};
|
||||
use crate::rmc::structures::helpers::DummyWriter;
|
||||
use std::io::{Read, Write};
|
||||
use std::string::FromUtf8Error;
|
||||
use std::{fmt, io};
|
||||
use thiserror::Error;
|
||||
use crate::rmc::structures::helpers::DummyWriter;
|
||||
//ideas for the future: make a proc macro library which allows generation of struct reads
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error{
|
||||
pub enum Error {
|
||||
#[error("Io Error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
#[error("UTF8 conversion Error: {0}")]
|
||||
|
|
@ -18,51 +18,52 @@ pub enum Error{
|
|||
#[error("an error occurred reading the station url")]
|
||||
StationUrlInvalid,
|
||||
#[error("error formatting text: {0}")]
|
||||
FormatError(#[from] fmt::Error)
|
||||
FormatError(#[from] fmt::Error),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub mod string;
|
||||
pub mod any;
|
||||
pub mod qresult;
|
||||
pub mod buffer;
|
||||
pub mod connection_data;
|
||||
pub mod rmc_struct;
|
||||
pub mod list;
|
||||
pub mod qbuffer;
|
||||
pub mod primitives;
|
||||
pub mod matchmake;
|
||||
pub mod variant;
|
||||
pub mod ranking;
|
||||
pub mod networking;
|
||||
pub mod helpers;
|
||||
pub mod list;
|
||||
pub mod matchmake;
|
||||
pub mod networking;
|
||||
pub mod primitives;
|
||||
pub mod qbuffer;
|
||||
pub mod qresult;
|
||||
pub mod ranking;
|
||||
pub mod rmc_struct;
|
||||
pub mod string;
|
||||
pub mod variant;
|
||||
|
||||
pub trait RmcSerialize{
|
||||
pub trait RmcSerialize {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()>;
|
||||
fn serialize_write_size(&self) -> Result<u32>{
|
||||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
let mut dummy = DummyWriter::new();
|
||||
|
||||
self.serialize(&mut dummy)?;
|
||||
|
||||
Ok(dummy.get_total_len())
|
||||
}
|
||||
fn deserialize(reader: &mut impl Read) -> Result<Self> where Self: Sized;
|
||||
fn deserialize(reader: &mut impl Read) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn to_data(&self) -> Result<Vec<u8>>{
|
||||
let mut data = Vec::with_capacity(
|
||||
self.serialize_write_size()? as usize
|
||||
);
|
||||
fn to_data(&self) -> Result<Vec<u8>> {
|
||||
let expected_size = self.serialize_write_size()?;
|
||||
let mut data = Vec::with_capacity(expected_size as usize);
|
||||
|
||||
self.serialize(&mut data)?;
|
||||
|
||||
debug_assert_eq!(self.serialize_write_size().unwrap(), data.len() as u32);
|
||||
debug_assert_eq!(expected_size, data.len() as u32);
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for (){
|
||||
impl RmcSerialize for () {
|
||||
fn serialize(&self, _writer: &mut impl Write) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -72,6 +73,4 @@ impl RmcSerialize for (){
|
|||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
Ok(self.0.serialize_write_size()?
|
||||
+ self.1.serialize_write_size()?
|
||||
+ self.2.serialize_write_size()?
|
||||
+ self.2.serialize_write_size()?
|
||||
+ self.3.serialize_write_size()?)
|
||||
+ self.3.serialize_write_size()?
|
||||
+ self.4.serialize_write_size()?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +1,42 @@
|
|||
use crate::rmc::response::ErrorCode;
|
||||
use crate::rmc::structures::{Result, RmcSerialize};
|
||||
use bytemuck::{Pod, Zeroable, bytes_of};
|
||||
use std::io::{Read, Write};
|
||||
use bytemuck::{bytes_of, Pod, Zeroable};
|
||||
use v_byte_helpers::SwapEndian;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::response::ErrorCode;
|
||||
use crate::rmc::structures::{RmcSerialize, Result};
|
||||
|
||||
pub const ERROR_MASK: u32 = 1 << 31;
|
||||
pub const ERROR_MASK: u32 = 1 << 31;
|
||||
|
||||
#[derive(Pod, Zeroable, Copy, Clone, SwapEndian, Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct QResult(u32);
|
||||
|
||||
impl QResult{
|
||||
pub fn success(error_code: ErrorCode) -> Self{
|
||||
impl QResult {
|
||||
pub fn success(error_code: ErrorCode) -> Self {
|
||||
let val: u32 = error_code.into();
|
||||
|
||||
Self(val & (!ERROR_MASK))
|
||||
}
|
||||
|
||||
pub fn error(error_code: ErrorCode) -> Self{
|
||||
pub fn error(error_code: ErrorCode) -> Self {
|
||||
let val: u32 = error_code.into();
|
||||
|
||||
Self(val | ERROR_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for QResult{
|
||||
impl RmcSerialize for QResult {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
writer.write(bytes_of(self))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut impl Read) -> Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
let result: Self = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
println!("reading qresult: {:x}", result.0);
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
Ok(4)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
|
||||
use crate::rmc::structures::Result;
|
||||
use std::cmp::max;
|
||||
use std::fmt::Arguments;
|
||||
use std::io;
|
||||
use std::io::{ErrorKind, IoSlice, Read, Write};
|
||||
use crate::rmc::structures::Result;
|
||||
|
||||
|
||||
#[repr(C, packed)]
|
||||
struct StructureHeader{
|
||||
struct StructureHeader {
|
||||
version: u8,
|
||||
length: u32
|
||||
length: u32,
|
||||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
|
|
@ -38,7 +36,12 @@ impl Write for OnlyWriteVec<'_> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
pub fn write_struct<T: Write>(
|
||||
writer: &mut T,
|
||||
version: u8,
|
||||
inner_size: u32,
|
||||
pred: impl FnOnce(&mut T) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
use bytemuck::bytes_of;
|
||||
|
||||
writer.write_all(&[version])?;
|
||||
|
|
@ -50,29 +53,31 @@ pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, _version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
pub fn write_struct<T: Write>(
|
||||
writer: &mut T,
|
||||
_version: u8,
|
||||
_inner_size: u32,
|
||||
pred: impl FnOnce(&mut T) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
pred(writer)
|
||||
}
|
||||
|
||||
|
||||
pub struct SubRead<'a, T: Read>{
|
||||
pub struct SubRead<'a, T: Read> {
|
||||
left_to_read: usize,
|
||||
origin: &'a mut T
|
||||
origin: &'a mut T,
|
||||
}
|
||||
|
||||
impl<'a, T: Read> SubRead<'a, T>{
|
||||
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{
|
||||
Self{
|
||||
impl<'a, T: Read> SubRead<'a, T> {
|
||||
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self {
|
||||
Self {
|
||||
left_to_read,
|
||||
origin
|
||||
origin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Read> Read for SubRead<'_, T>{
|
||||
impl<T: Read> Read for SubRead<'_, T> {
|
||||
#[inline(always)]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let max_read = max(self.left_to_read, buf.len());
|
||||
|
|
@ -83,8 +88,11 @@ impl<T: Read> Read for SubRead<'_, T>{
|
|||
|
||||
#[inline(always)]
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||
if buf.len() > self.left_to_read{
|
||||
return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead"));
|
||||
if buf.len() > self.left_to_read {
|
||||
return Err(io::Error::new(
|
||||
ErrorKind::UnexpectedEof,
|
||||
"Would run over end of SubRead",
|
||||
));
|
||||
}
|
||||
self.left_to_read -= buf.len();
|
||||
self.origin.read_exact(buf)
|
||||
|
|
@ -92,10 +100,14 @@ impl<T: Read> Read for SubRead<'_, T>{
|
|||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn read_struct<T: Sized, R: Read>(reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead<R>) -> Result<T>) -> Result<T> {
|
||||
pub fn read_struct<T: Sized, R: Read>(
|
||||
reader: &mut R,
|
||||
version: u8,
|
||||
pred: impl FnOnce(&mut SubRead<R>) -> Result<T>,
|
||||
) -> Result<T> {
|
||||
use crate::rmc::structures::Error::VersionMismatch;
|
||||
use v_byte_helpers::ReadExtensions;
|
||||
use v_byte_helpers::IS_BIG_ENDIAN;
|
||||
use v_byte_helpers::ReadExtensions;
|
||||
let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
if ver != version {
|
||||
|
|
@ -108,6 +120,10 @@ pub fn read_struct<T: Sized, R: Read>(reader: &mut R, version: u8, pred: impl Fn
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, _version: u8, pred: impl FnOnce(&mut R) -> Result<T>) -> Result<T> {
|
||||
pub fn read_struct<T: Sized, R: Read>(
|
||||
mut reader: &mut R,
|
||||
_version: u8,
|
||||
pred: impl FnOnce(&mut R) -> Result<T>,
|
||||
) -> Result<T> {
|
||||
Ok(pred(&mut reader)?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
use std::io::{Read, Write};
|
||||
use super::{Result, RmcSerialize};
|
||||
use bytemuck::bytes_of;
|
||||
use log::error;
|
||||
use std::io::{Read, Write};
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use super::{Result, RmcSerialize};
|
||||
|
||||
impl RmcSerialize for String{
|
||||
impl RmcSerialize for String {
|
||||
fn deserialize(reader: &mut impl Read) -> Result<Self> {
|
||||
let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
if len == 0{
|
||||
if len == 0 {
|
||||
return Ok("".to_string());
|
||||
}
|
||||
let mut data = vec![0; len as usize];
|
||||
reader.read_exact(&mut data)?;
|
||||
if *data.last().unwrap() != 0{
|
||||
if *data.last().unwrap() != 0 {
|
||||
error!("unable to find null terminator... continuing anyways");
|
||||
}
|
||||
data.pop();
|
||||
|
|
@ -27,7 +27,7 @@ impl RmcSerialize for String{
|
|||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for &str{
|
||||
impl RmcSerialize for &str {
|
||||
fn deserialize(_reader: &mut impl Read) -> Result<Self> {
|
||||
panic!("cannot serialize to &str")
|
||||
}
|
||||
|
|
@ -45,4 +45,3 @@ impl RmcSerialize for &str{
|
|||
Ok(2 + self.as_bytes().len() as u32 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue