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:
Diffstat (limited to 'src/string.rs')
-rw-r--r--src/string.rs77
1 files changed, 64 insertions, 13 deletions
diff --git a/src/string.rs b/src/string.rs
index ce0109b..2d6d4a9 100644
--- a/src/string.rs
+++ b/src/string.rs
@@ -1,10 +1,11 @@
// Copyright 2021 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: GPL-2.0-or-later
+use crate::ntfs::Ntfs;
use alloc::string::String;
use core::char;
use core::cmp::Ordering;
-use core::convert::TryInto;
+use core::convert::{identity, TryInto};
use core::fmt;
/// Zero-copy representation of a string stored in an NTFS filesystem structure.
@@ -12,17 +13,21 @@ use core::fmt;
pub struct NtfsString<'a>(pub &'a [u8]);
impl<'a> NtfsString<'a> {
- fn cmp_iter<TI, OI>(mut this_iter: TI, mut other_iter: OI) -> Ordering
+ fn cmp_iter<TI, OI, F>(mut this_iter: TI, mut other_iter: OI, code_unit_fn: F) -> Ordering
where
TI: Iterator<Item = u16>,
OI: Iterator<Item = u16>,
+ F: Fn(u16) -> u16,
{
loop {
match (this_iter.next(), other_iter.next()) {
(Some(this_code_unit), Some(other_code_unit)) => {
// We have two UTF-16 code units to compare.
- if this_code_unit != other_code_unit {
- return this_code_unit.cmp(&other_code_unit);
+ let this_upper = code_unit_fn(this_code_unit);
+ let other_upper = code_unit_fn(other_code_unit);
+
+ if this_upper != other_upper {
+ return this_upper.cmp(&other_upper);
}
}
(Some(_), None) => {
@@ -91,7 +96,7 @@ impl<'a> fmt::Display for NtfsString<'a> {
impl<'a> Ord for NtfsString<'a> {
fn cmp(&self, other: &Self) -> Ordering {
- NtfsString::cmp_iter(self.u16_iter(), other.u16_iter())
+ NtfsString::cmp_iter(self.u16_iter(), other.u16_iter(), identity)
}
}
@@ -104,25 +109,25 @@ impl<'a> PartialEq for NtfsString<'a> {
impl<'a> PartialEq<str> for NtfsString<'a> {
fn eq(&self, other: &str) -> bool {
- NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16()) == Ordering::Equal
+ NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16(), identity) == Ordering::Equal
}
}
impl<'a> PartialEq<NtfsString<'a>> for str {
fn eq(&self, other: &NtfsString<'a>) -> bool {
- NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter()) == Ordering::Equal
+ NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter(), identity) == Ordering::Equal
}
}
impl<'a> PartialEq<&str> for NtfsString<'a> {
fn eq(&self, other: &&str) -> bool {
- NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16()) == Ordering::Equal
+ NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16(), identity) == Ordering::Equal
}
}
impl<'a> PartialEq<NtfsString<'a>> for &str {
fn eq(&self, other: &NtfsString<'a>) -> bool {
- NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter()) == Ordering::Equal
+ NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter(), identity) == Ordering::Equal
}
}
@@ -134,24 +139,70 @@ impl<'a> PartialOrd for NtfsString<'a> {
impl<'a> PartialOrd<str> for NtfsString<'a> {
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
- Some(NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16()))
+ Some(NtfsString::cmp_iter(
+ self.u16_iter(),
+ other.encode_utf16(),
+ identity,
+ ))
}
}
impl<'a> PartialOrd<NtfsString<'a>> for str {
fn partial_cmp(&self, other: &NtfsString<'a>) -> Option<Ordering> {
- Some(NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter()))
+ Some(NtfsString::cmp_iter(
+ self.encode_utf16(),
+ other.u16_iter(),
+ identity,
+ ))
}
}
impl<'a> PartialOrd<&str> for NtfsString<'a> {
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
- Some(NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16()))
+ Some(NtfsString::cmp_iter(
+ self.u16_iter(),
+ other.encode_utf16(),
+ identity,
+ ))
}
}
impl<'a> PartialOrd<NtfsString<'a>> for &str {
fn partial_cmp(&self, other: &NtfsString<'a>) -> Option<Ordering> {
- Some(NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter()))
+ Some(NtfsString::cmp_iter(
+ self.encode_utf16(),
+ other.u16_iter(),
+ identity,
+ ))
+ }
+}
+
+pub trait UpcaseOrd<Rhs> {
+ /// Performs a case-insensitive ordering based on the upcase table read from the filesystem.
+ ///
+ /// # Panics
+ ///
+ /// Panics if [`read_upcase_table`][Ntfs::read_upcase_table] had not been called on the passed [`Ntfs`] object.
+ fn upcase_cmp(&self, ntfs: &Ntfs, other: &Rhs) -> Ordering;
+}
+
+impl<'a> UpcaseOrd<NtfsString<'a>> for NtfsString<'a> {
+ fn upcase_cmp(&self, ntfs: &Ntfs, other: &NtfsString<'a>) -> Ordering {
+ let upcase_fn = |x| ntfs.upcase_table().u16_to_uppercase(x);
+ NtfsString::cmp_iter(self.u16_iter(), other.u16_iter(), upcase_fn)
+ }
+}
+
+impl<'a> UpcaseOrd<&str> for NtfsString<'a> {
+ fn upcase_cmp(&self, ntfs: &Ntfs, other: &&str) -> Ordering {
+ let upcase_fn = |x| ntfs.upcase_table().u16_to_uppercase(x);
+ NtfsString::cmp_iter(self.u16_iter(), other.encode_utf16(), upcase_fn)
+ }
+}
+
+impl<'a> UpcaseOrd<NtfsString<'a>> for &str {
+ fn upcase_cmp(&self, ntfs: &Ntfs, other: &NtfsString<'a>) -> Ordering {
+ let upcase_fn = |x| ntfs.upcase_table().u16_to_uppercase(x);
+ NtfsString::cmp_iter(self.encode_utf16(), other.u16_iter(), upcase_fn)
}
}