mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +02:00
remove some slice indexing
This commit is contained in:
parent
e0ec7db236
commit
1d71aa8ba6
9 changed files with 42 additions and 33 deletions
|
|
@ -14,6 +14,8 @@ impl ConstFnvHash {
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < bytes.len() {
|
while i < bytes.len() {
|
||||||
|
// can't use better method in const fns
|
||||||
|
#[allow(clippy::indexing_slicing)]
|
||||||
let byte = bytes[i];
|
let byte = bytes[i];
|
||||||
hash ^= byte as u64;
|
hash ^= byte as u64;
|
||||||
hash = hash.wrapping_mul(0x100000001b3);
|
hash = hash.wrapping_mul(0x100000001b3);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
use std::convert::TryInto;
|
|
||||||
|
|
||||||
pub fn decompress(input: &[u8], output: &mut Vec<u8>) {
|
pub fn decompress(input: &[u8], output: &mut Vec<u8>) {
|
||||||
decompress_(input, output);
|
decompress_(input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// inner fn that returns an option so we can use ? for short circuiting return
|
/// inner fn that returns an option so we can use ? for short circuiting return
|
||||||
fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> {
|
fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> {
|
||||||
let target_len = u32::from_le_bytes(input[0..4].try_into().unwrap()) as usize;
|
let mut len_bytes = [0; 4];
|
||||||
|
len_bytes.copy_from_slice(input.get(0..4)?);
|
||||||
|
let target_len = u32::from_le_bytes(len_bytes) as usize;
|
||||||
|
|
||||||
let mut read_pos = 4;
|
let mut read_pos = 4;
|
||||||
let mut read_byte = move || {
|
let mut read_byte = move || {
|
||||||
|
|
@ -35,7 +35,7 @@ fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> {
|
||||||
let start = output.len() - pos - 1;
|
let start = output.len() - pos - 1;
|
||||||
// can't do extend_from_within since it start + count can be larger than output.len
|
// can't do extend_from_within since it start + count can be larger than output.len
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
output.push(output[start + i]);
|
output.push(*output.get(start + i)?);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output.push(read_byte()?);
|
output.push(read_byte()?);
|
||||||
|
|
|
||||||
|
|
@ -197,12 +197,15 @@ impl PacketEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_baseline_props<'a>(&self, parser_state: &'a ParserState) -> Cow<'a, [SendProp]> {
|
pub fn get_baseline_props<'a>(&self, parser_state: &'a ParserState) -> Cow<'a, [SendProp]> {
|
||||||
|
let Some(send_table) = parser_state.send_tables.get(usize::from(self.server_class)) else {
|
||||||
|
return Cow::default();
|
||||||
|
};
|
||||||
parser_state
|
parser_state
|
||||||
.get_baseline(
|
.get_baseline(
|
||||||
self.baseline_index,
|
self.baseline_index,
|
||||||
self.entity_index,
|
self.entity_index,
|
||||||
self.server_class,
|
self.server_class,
|
||||||
&parser_state.send_tables[usize::from(self.server_class)],
|
send_table,
|
||||||
self.delta.is_some(),
|
self.delta.is_some(),
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
|
|
||||||
|
|
@ -613,7 +613,13 @@ fn write_table_entry(
|
||||||
if let Some((history_index, history_count)) = history_item {
|
if let Some((history_index, history_count)) = history_item {
|
||||||
history_index.write_sized(stream, 5)?;
|
history_index.write_sized(stream, 5)?;
|
||||||
history_count.write_sized(stream, 5)?;
|
history_count.write_sized(stream, 5)?;
|
||||||
let diff_bytes = &text.as_bytes()[history_count..];
|
let diff_bytes =
|
||||||
|
text.as_bytes()
|
||||||
|
.get(history_count..)
|
||||||
|
.ok_or(BitError::IndexOutOfBounds {
|
||||||
|
pos: history_count,
|
||||||
|
size: text.len(),
|
||||||
|
})?;
|
||||||
stream.write_bytes(diff_bytes)?;
|
stream.write_bytes(diff_bytes)?;
|
||||||
0u8.write(stream)?; // writing the string as bytes doesn't add the null terminator
|
0u8.write(stream)?; // writing the string as bytes doesn't add the null terminator
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,10 @@ impl ParseBitSkip<'_> for TempEntitiesMessage {
|
||||||
|
|
||||||
impl Encode for TempEntitiesMessage {
|
impl Encode for TempEntitiesMessage {
|
||||||
fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
|
fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
|
||||||
let count = if self.events.len() == 1 {
|
let count = match (self.events.len(), self.events.first()) {
|
||||||
if self.events[0].reliable {
|
(1, Some(event)) if event.reliable => 0,
|
||||||
0
|
(1, _) => 1,
|
||||||
} else {
|
(len, _) => len as u8,
|
||||||
1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.events.len() as u8
|
|
||||||
};
|
};
|
||||||
count.write(stream)?;
|
count.write(stream)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,7 @@ impl ParseSendTable {
|
||||||
// sort often changed props before the others
|
// sort often changed props before the others
|
||||||
let mut start = 0;
|
let mut start = 0;
|
||||||
for i in 0..flat.len() {
|
for i in 0..flat.len() {
|
||||||
|
#[allow(clippy::indexing_slicing)]
|
||||||
if flat[i].parse_definition.changes_often() {
|
if flat[i].parse_definition.changes_often() {
|
||||||
if i != start {
|
if i != start {
|
||||||
flat.swap(i, start);
|
flat.swap(i, start);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ use serde::de::Error;
|
||||||
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ops::{Index, IndexMut};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct ChatMessage {
|
pub struct ChatMessage {
|
||||||
|
|
@ -169,6 +168,18 @@ impl ClassList {
|
||||||
classes.sort_by(|a, b| a.1.cmp(&b.1).reverse());
|
classes.sort_by(|a, b| a.1.cmp(&b.1).reverse());
|
||||||
classes.into_iter()
|
classes.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, class: Class) -> u8 {
|
||||||
|
// class number is always in bounds
|
||||||
|
#[allow(clippy::indexing_slicing)]
|
||||||
|
self.0[class as u8 as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, class: Class) -> &mut u8 {
|
||||||
|
// class number is always in bounds
|
||||||
|
#[allow(clippy::indexing_slicing)]
|
||||||
|
&mut self.0[class as u8 as usize]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -180,22 +191,6 @@ fn test_classlist_sorted() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<Class> for ClassList {
|
|
||||||
type Output = u8;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
|
|
||||||
fn index(&self, class: Class) -> &Self::Output {
|
|
||||||
&self.0[class as u8 as usize]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IndexMut<Class> for ClassList {
|
|
||||||
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
|
|
||||||
fn index_mut(&mut self, class: Class) -> &mut Self::Output {
|
|
||||||
&mut self.0[class as u8 as usize]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for ClassList {
|
impl Serialize for ClassList {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
|
|
@ -218,7 +213,7 @@ impl From<HashMap<Class, u8>> for ClassList {
|
||||||
let mut classes = ClassList::default();
|
let mut classes = ClassList::default();
|
||||||
|
|
||||||
for (class, count) in map.into_iter() {
|
for (class, count) in map.into_iter() {
|
||||||
classes[class] = count;
|
*classes.get_mut(class) = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
classes
|
classes
|
||||||
|
|
@ -505,7 +500,7 @@ impl Analyser {
|
||||||
GameEvent::PlayerSpawn(event) => {
|
GameEvent::PlayerSpawn(event) => {
|
||||||
let spawn = Spawn::from_event(event, tick);
|
let spawn = Spawn::from_event(event, tick);
|
||||||
if let Some(user_state) = self.state.users.get_mut(&spawn.user) {
|
if let Some(user_state) = self.state.users.get_mut(&spawn.user) {
|
||||||
user_state.classes[spawn.class] += 1;
|
*user_state.classes.get_mut(spawn.class) += 1;
|
||||||
user_state.team = spawn.team;
|
user_state.team = spawn.team;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,7 @@ impl GameState {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[allow(clippy::indexing_slicing)]
|
||||||
&mut self.players[index]
|
&mut self.players[index]
|
||||||
}
|
}
|
||||||
pub fn get_or_create_building(
|
pub fn get_or_create_building(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
#![cfg_attr(not(test), deny(clippy::unwrap_used))]
|
||||||
|
#![cfg_attr(not(test), deny(clippy::expect_used))]
|
||||||
|
#![cfg_attr(not(test), deny(clippy::indexing_slicing))]
|
||||||
|
#![cfg_attr(not(test), deny(clippy::panic))]
|
||||||
|
|
||||||
pub use bitbuffer::Result as ReadResult;
|
pub use bitbuffer::Result as ReadResult;
|
||||||
|
|
||||||
pub use crate::demo::{
|
pub use crate::demo::{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue