fix string order
This commit is contained in:
parent
0b8dce9266
commit
3a7208f1b5
4 changed files with 227 additions and 56 deletions
|
|
@ -36,8 +36,9 @@ const VALUE_TRAYLING_BYTE_PREFIX: u8 = 0b1000_0000;
|
|||
|
||||
impl Ord for StringDataItem {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.data
|
||||
.cmp(&other.data)
|
||||
self.get_aosp_utf16()
|
||||
.unwrap()
|
||||
.cmp(&other.get_aosp_utf16().unwrap())
|
||||
.then(self.utf16_size.cmp(&other.utf16_size))
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +123,57 @@ impl From<&str> for StringDataItem {
|
|||
}
|
||||
|
||||
impl StringDataItem {
|
||||
/// Return the utf-16 string used by google in the aosp for comparaison & other.
|
||||
fn get_aosp_utf16(&self) -> Result<Vec<u32>> {
|
||||
let mut utf16_string = vec![];
|
||||
let mut i = 0;
|
||||
while i < self.data.len() {
|
||||
let one = self.data[i] as u32;
|
||||
i += 1;
|
||||
if one & 0x80 == 0 {
|
||||
utf16_string.push(one);
|
||||
continue;
|
||||
}
|
||||
|
||||
if i >= self.data.len() {
|
||||
return Err(Error::InvalidStringEncoding(
|
||||
"String contains invalid caracters".into(),
|
||||
));
|
||||
}
|
||||
let two = self.data[i] as u32;
|
||||
i += 1;
|
||||
if one & 0x20 == 0 {
|
||||
utf16_string.push((one & 0x1f) << 6 | (two & 0x3f));
|
||||
continue;
|
||||
}
|
||||
|
||||
if i >= self.data.len() {
|
||||
return Err(Error::InvalidStringEncoding(
|
||||
"String contains invalid caracters".into(),
|
||||
));
|
||||
}
|
||||
let three = self.data[i] as u32;
|
||||
i += 1;
|
||||
if one & 0x10 == 0 {
|
||||
utf16_string.push((one & 0x0f) << 12 | (two & 0x3f) << 6 | (three & 0x3f));
|
||||
continue;
|
||||
}
|
||||
|
||||
if i >= self.data.len() {
|
||||
return Err(Error::InvalidStringEncoding(
|
||||
"String contains invalid caracters".into(),
|
||||
));
|
||||
}
|
||||
let four = self.data[i] as u32;
|
||||
i += 1;
|
||||
let code_point =
|
||||
(one & 0x0f) << 18 | (two & 0x3f) << 12 | (three & 0x3f) << 6 | (four & 0x3f);
|
||||
let mut pair = ((code_point >> 10) + 0xd7c0) & 0xffff;
|
||||
pair |= ((code_point & 0x03ff) + 0xdc00) << 16;
|
||||
utf16_string.push(pair);
|
||||
}
|
||||
Ok(utf16_string)
|
||||
}
|
||||
fn get_string(&self) -> Result<String> {
|
||||
let mut string = String::new();
|
||||
let mut i = 0;
|
||||
|
|
@ -481,4 +533,25 @@ mod test {
|
|||
assert_eq!(encoded, expected.as_str().into());
|
||||
}
|
||||
}
|
||||
|
||||
/// Apparently I don't know how to code an order relation so here it is...
|
||||
#[test]
|
||||
fn test_ord_relation() {
|
||||
let s1: StringDataItem = "Landroidx/lifecycle/WithLifecycleStateKt$suspendWithStateAtLeastUnchecked$2$observer$1;".into();
|
||||
let s2: StringDataItem = "Lcom/google/android/material/search/SearchBarAnimationHelper$$ExternalSyntheticLambda4;".into();
|
||||
let s1_utf16 = s1.get_aosp_utf16().unwrap();
|
||||
let s2_utf16 = s2.get_aosp_utf16().unwrap();
|
||||
assert_eq!(s1_utf16 < s2_utf16, true);
|
||||
assert_eq!(s1_utf16 == s2_utf16, false);
|
||||
assert_eq!(s1_utf16 > s2_utf16, false);
|
||||
assert_eq!(s2_utf16 < s1_utf16, false);
|
||||
assert_eq!(s2_utf16 == s1_utf16, false);
|
||||
assert_eq!(s2_utf16 > s1_utf16, true);
|
||||
assert_eq!(s1 < s2, true);
|
||||
assert_eq!(s1 == s2, false);
|
||||
assert_eq!(s1 > s2, false);
|
||||
assert_eq!(s2 < s1, false);
|
||||
assert_eq!(s2 == s1, false);
|
||||
assert_eq!(s2 > s1, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue