✨ support for invalid utf8
This commit is contained in:
1 parent
26ee43af2e
commit
96d328c829
11 files changed
+467
-133
No files matched your search
@@ -4,7 +4,7 @@ use std::fmt;
|
||||
pub struct CharData<'a> {
|
||||
name: &'a str,
|
||||
category: Category,
|
||||
ccc: CombiningClass,
|
||||
combining_class: CombiningClass,
|
||||
}
|
||||
|
||||
impl<'a> CharData<'a> {
|
||||
@@ -22,8 +22,8 @@ impl<'a> CharData<'a> {
|
||||
Some((codepoint, Self::from_parts(name, category, ccc)))
|
||||
}
|
||||
|
||||
pub fn from_parts(name: &'a str, category: Category, ccc: CombiningClass) -> Self {
|
||||
Self { name, category, ccc }
|
||||
pub fn from_parts(name: &'a str, category: Category, combining_class: CombiningClass) -> Self {
|
||||
Self { name, category, combining_class }
|
||||
}
|
||||
|
||||
pub fn with_name<'b>(self, name: &'a str) -> CharData<'b>
|
||||
@@ -41,44 +41,43 @@ impl<'a> CharData<'a> {
|
||||
self.category
|
||||
}
|
||||
|
||||
pub fn ccc(&self) -> CombiningClass {
|
||||
self.ccc
|
||||
pub fn combining_class(&self) -> CombiningClass {
|
||||
self.combining_class
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum Category {
|
||||
Lu = 0,
|
||||
Ll = 1,
|
||||
Lt = 2,
|
||||
Mn = 3,
|
||||
Mc = 4,
|
||||
Me = 5,
|
||||
Nd = 6,
|
||||
Nl = 7,
|
||||
No = 8,
|
||||
Zs = 9,
|
||||
Zl = 10,
|
||||
Zp = 11,
|
||||
Cc = 12,
|
||||
Cf = 13,
|
||||
Cs = 14,
|
||||
Co = 15,
|
||||
Cn = 16,
|
||||
Lm = 17,
|
||||
Lo = 18,
|
||||
Pc = 19,
|
||||
Pd = 20,
|
||||
Ps = 21,
|
||||
Pe = 22,
|
||||
Pi = 23,
|
||||
Pf = 24,
|
||||
Po = 25,
|
||||
Sm = 26,
|
||||
Sc = 27,
|
||||
Sk = 28,
|
||||
So = 29,
|
||||
Lu,
|
||||
Ll,
|
||||
Lt,
|
||||
Mn,
|
||||
Mc,
|
||||
Me,
|
||||
Nd,
|
||||
Nl,
|
||||
No,
|
||||
Zs,
|
||||
Zl,
|
||||
Zp,
|
||||
Cc,
|
||||
Cf,
|
||||
Cs,
|
||||
Co,
|
||||
Cn,
|
||||
Lm,
|
||||
Lo,
|
||||
Pc,
|
||||
Pd,
|
||||
Ps,
|
||||
Pe,
|
||||
Pi,
|
||||
Pf,
|
||||
Po,
|
||||
Sm,
|
||||
Sc,
|
||||
Sk,
|
||||
So,
|
||||
}
|
||||
|
||||
impl Category {
|
||||
|
||||
@@ -7,7 +7,13 @@ const DATA_ENTRY_SIZE: usize = 8;
|
||||
const DATA_INIT_FLAG: u8 = 1;
|
||||
const DATA_REPEATED_FLAG: u8 = 2;
|
||||
|
||||
fn encode_char_data(name_index: u32, category: Category, ccc: CombiningClass, repeated: bool) -> [u8; DATA_ENTRY_SIZE] {
|
||||
fn encode_char_data(
|
||||
name_index: u32,
|
||||
category: Category,
|
||||
combining_class: CombiningClass,
|
||||
repeated: bool
|
||||
) -> [u8; DATA_ENTRY_SIZE]
|
||||
{
|
||||
let mut buf = [0u8; DATA_ENTRY_SIZE];
|
||||
|
||||
buf[0] |= DATA_INIT_FLAG;
|
||||
@@ -18,12 +24,14 @@ fn encode_char_data(name_index: u32, category: Category, ccc: CombiningClass, re
|
||||
|
||||
buf[1..5].copy_from_slice(&name_index.to_le_bytes());
|
||||
buf[5] = category.byte_repr();
|
||||
buf[6] = ccc.0;
|
||||
buf[6] = combining_class.0;
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
fn decode_char_data(bytes: [u8; DATA_ENTRY_SIZE]) -> Option<(u32, Category, CombiningClass, bool)> {
|
||||
fn decode_char_data(bytes: [u8; DATA_ENTRY_SIZE])
|
||||
-> Option<(u32, Category, CombiningClass, bool)>
|
||||
{
|
||||
let flags = bytes[0];
|
||||
|
||||
if flags & DATA_INIT_FLAG == 0 {
|
||||
@@ -32,10 +40,10 @@ fn decode_char_data(bytes: [u8; DATA_ENTRY_SIZE]) -> Option<(u32, Category, Comb
|
||||
|
||||
let name_index = u32::from_le_bytes(bytes[1..5].try_into().unwrap());
|
||||
let category = Category::from_byte(bytes[5])?;
|
||||
let ccc = CombiningClass(bytes[6]);
|
||||
let combining_class = CombiningClass(bytes[6]);
|
||||
let repeated = flags & DATA_REPEATED_FLAG != 0;
|
||||
|
||||
Some((name_index, category, ccc, repeated))
|
||||
Some((name_index, category, combining_class, repeated))
|
||||
}
|
||||
|
||||
pub struct DataBuf {
|
||||
@@ -62,7 +70,10 @@ impl DataBuf {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let repeated = range.end - range.start > 1;
|
||||
let repeated = range.end
|
||||
.checked_sub(range.start)
|
||||
.map(|len| len > 1)
|
||||
.unwrap_or(false);
|
||||
|
||||
let range = {
|
||||
let start = usize::try_from(range.start)
|
||||
@@ -86,7 +97,7 @@ impl DataBuf {
|
||||
let encoded_char_data = encode_char_data(
|
||||
name_index,
|
||||
char_data.category(),
|
||||
char_data.ccc(),
|
||||
char_data.combining_class(),
|
||||
repeated
|
||||
);
|
||||
|
||||
@@ -121,8 +132,8 @@ pub struct Data<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Data<'a> {
|
||||
pub fn get(self, codepoint: u32) -> Option<CharData<'a>> {
|
||||
let index = usize::try_from(codepoint).ok()?;
|
||||
pub fn get(self, codepoint: char) -> Option<CharData<'a>> {
|
||||
let index = usize::try_from(u32::from(codepoint)).ok()?;
|
||||
let start = index.checked_mul(DATA_ENTRY_SIZE)?;
|
||||
let end = start.checked_add(DATA_ENTRY_SIZE)?;
|
||||
let encoded = self.data.get(start..end)?;
|
||||
|
||||
Reference in new issue
Block a user