Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/ntfs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Finck <colin@reactos.org>2021-08-07 11:19:49 +0300
committerColin Finck <colin@reactos.org>2021-08-07 11:19:49 +0300
commit5ab4c082936ebc6163e7a5995840244964fe596d (patch)
tree7ac1323ad86869ec9d8660cb95a043344686aadf
parent6210c625de3f617b0553ae8176f2483133517161 (diff)
Use `ArrayVec` over heap-allocated `Vec` for some structured values.
This greatly reduces the number of heap allocations when traversing an index.
-rw-r--r--Cargo.toml3
-rw-r--r--src/structured_values/file_name.rs12
-rw-r--r--src/structured_values/volume_name.rs8
3 files changed, 15 insertions, 8 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 90cfc1a..047e301 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+arrayvec = { version = "0.7.1", default-features = false }
binread = { version = "2.1.1", features = ["const_generics"], default-features = false }
byteorder = { version = "1.4.3", default-features = false }
bitflags = "1.2.1"
@@ -17,4 +18,4 @@ memoffset = "0.6.4"
[features]
default = ["std"]
-std = ["binread/std", "byteorder/std"]
+std = ["arrayvec/std", "binread/std", "byteorder/std"]
diff --git a/src/structured_values/file_name.rs b/src/structured_values/file_name.rs
index 0fdac97..24dbbde 100644
--- a/src/structured_values/file_name.rs
+++ b/src/structured_values/file_name.rs
@@ -10,7 +10,7 @@ use crate::structured_values::{
NtfsFileAttributeFlags, NtfsStructuredValue, NtfsStructuredValueFromSlice,
};
use crate::time::NtfsTime;
-use alloc::vec::Vec;
+use arrayvec::ArrayVec;
use binread::io::Cursor;
use binread::{BinRead, BinReaderExt};
use core::mem;
@@ -22,6 +22,10 @@ const FILE_NAME_HEADER_SIZE: usize = 66;
/// The smallest FileName attribute has a name containing just a single character.
const FILE_NAME_MIN_SIZE: usize = FILE_NAME_HEADER_SIZE + mem::size_of::<u16>();
+/// The "name" stored in the FileName attribute has an `u8` length field specifying the number of UTF-16 code points.
+/// Hence, the name occupies up to 510 bytes.
+const NAME_MAX_SIZE: usize = (u8::MAX as usize) * mem::size_of::<u16>();
+
#[allow(unused)]
#[derive(BinRead, Clone, Debug)]
struct FileNameHeader {
@@ -50,7 +54,7 @@ pub enum NtfsFileNamespace {
#[derive(Clone, Debug)]
pub struct NtfsFileName {
header: FileNameHeader,
- name: Vec<u8>,
+ name: ArrayVec<u8, NAME_MAX_SIZE>,
}
impl NtfsFileName {
@@ -104,7 +108,7 @@ impl NtfsFileName {
debug_assert!(self.name.is_empty());
let start = FILE_NAME_HEADER_SIZE;
let end = start + self.name_length();
- self.name.extend_from_slice(&data[start..end]);
+ self.name.try_extend_from_slice(&data[start..end]).unwrap();
}
fn validate_name_length(&self, data_size: usize, position: u64) -> Result<()> {
@@ -154,7 +158,7 @@ impl<'s> NtfsStructuredValueFromSlice<'s> for NtfsFileName {
let mut file_name = Self {
header,
- name: Vec::new(),
+ name: ArrayVec::new(),
};
file_name.validate_name_length(slice.len(), position)?;
file_name.validate_namespace(position)?;
diff --git a/src/structured_values/volume_name.rs b/src/structured_values/volume_name.rs
index 77b2c8e..91ca1a2 100644
--- a/src/structured_values/volume_name.rs
+++ b/src/structured_values/volume_name.rs
@@ -5,7 +5,7 @@ use crate::attribute::NtfsAttributeType;
use crate::error::{NtfsError, Result};
use crate::string::NtfsString;
use crate::structured_values::{NtfsStructuredValue, NtfsStructuredValueFromSlice};
-use alloc::vec::Vec;
+use arrayvec::ArrayVec;
use core::mem;
/// The smallest VolumeName attribute has a name containing just a single character.
@@ -16,7 +16,7 @@ const VOLUME_NAME_MAX_SIZE: usize = 128 * mem::size_of::<u16>();
#[derive(Clone, Debug)]
pub struct NtfsVolumeName {
- name: Vec<u8>,
+ name: ArrayVec<u8, VOLUME_NAME_MAX_SIZE>,
}
impl NtfsVolumeName {
@@ -55,7 +55,9 @@ impl<'s> NtfsStructuredValueFromSlice<'s> for NtfsVolumeName {
});
}
- let name = slice.to_vec();
+ let mut name = ArrayVec::new();
+ name.try_extend_from_slice(slice).unwrap();
+
Ok(Self { name })
}
}