✨ support for invalid utf8

This commit is contained in:
pantonshire committed 2023-05-18 17:04:30 +01:00
1 parent 26ee43af2e
commit 96d328c829
11 files changed
+467 -133

No files matched your search

+35 -36
View File
@@ -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 {
+20 -9
View File
@@ -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)?;