Optimize Big5 astral encode.

This commit is contained in:
Henri Sivonen
2017-01-27 09:42:56 +02:00
parent e7e6d2f7d8
commit 683eb5aa53
4 changed files with 68 additions and 19 deletions
+19
View File
@@ -1185,6 +1185,25 @@ pub fn big5_low_bits(rebased_pointer: usize) -> u16 {
}
}
#[inline(always)]
pub fn big5_astral_encode(low_bits: u16) -> Option<usize> {
match low_bits {
0x00CC => Some(11205 - 942),
0x008A => Some(11207 - 942),
0x7607 => Some(11213 - 942),
_ => {
let mut i = 18997 - 942;
while i < BIG5_LOW_BITS.len() {
if BIG5_LOW_BITS[i] == low_bits && big5_is_astral(i) {
return Some(i);
}
i += 1;
}
None
}
}
}
#[inline(always)]
pub fn big5_find_pointer(low_bits: u16, is_astral: bool) -> usize {
if !is_astral {
+25 -19
View File
@@ -194,26 +194,31 @@ impl Big5Encoder {
handle.write_two(lead as u8, trail as u8)
},
{
if astral as u32 & 0xFF0000 != 0x20000 {
// Only Plane 2 is potentially mappable of the astral planes.
return (EncoderResult::Unmappable(astral),
source.consumed(),
handle.written());
}
let pointer = big5_find_pointer(astral as u16, true);
if pointer == 0 {
return (EncoderResult::Unmappable(astral),
source.consumed(),
handle.written());
}
let lead = pointer / 157 + 0x81;
let remainder = pointer % 157;
let trail = if remainder < 0x3F {
remainder + 0x40
if in_inclusive_range32(astral as u32,
0x2008A,
0x2F8A6) {
if let Some(rebased_pointer) =
big5_astral_encode(astral as u16) {
// big5_astral_encode returns rebased pointer,
// so adding 0x87 instead of 0x81.
let lead = rebased_pointer / 157 + 0x87;
let remainder = rebased_pointer % 157;
let trail = if remainder < 0x3F {
remainder + 0x40
} else {
remainder + 0x62
};
handle.write_two(lead as u8, trail as u8)
} else {
return (EncoderResult::Unmappable(astral),
source.consumed(),
handle.written());
}
} else {
remainder + 0x62
};
handle.write_two(lead as u8, trail as u8)
return (EncoderResult::Unmappable(astral),
source.consumed(),
handle.written());
}
},
bmp,
astral,
@@ -321,6 +326,7 @@ mod tests {
// duplicate low bits
encode_big5("\u{203B5}", b"\xFD\x6A");
encode_big5("\u{25605}", b"\xFE\x46");
// prefer last
encode_big5("\u{2550}", b"\xF9\xF9");
+19
View File
@@ -18606,6 +18606,25 @@ pub fn big5_low_bits(rebased_pointer: usize) -> u16 {
}
}
#[inline(always)]
pub fn big5_astral_encode(low_bits: u16) -> Option<usize> {
match low_bits {
0x00CC => Some(11205 - 942),
0x008A => Some(11207 - 942),
0x7607 => Some(11213 - 942),
_ => {
let mut i = 18997 - 942;
while i < BIG5_LOW_BITS.len() {
if BIG5_LOW_BITS[i] == low_bits && big5_is_astral(i) {
return Some(i);
}
i += 1;
}
None
}
}
}
#[inline(always)]
pub fn big5_find_pointer(low_bits: u16, is_astral: bool) -> usize {
if !is_astral {
+5
View File
@@ -3646,6 +3646,11 @@ fn in_inclusive_range16(i: u16, start: u16, end: u16) -> bool {
i.wrapping_sub(start) <= (end - start)
}
#[inline(always)]
fn in_inclusive_range32(i: u32, start: u32, end: u32) -> bool {
i.wrapping_sub(start) <= (end - start)
}
#[inline(always)]
fn in_inclusive_range(i: usize, start: usize, end: usize) -> bool {
i.wrapping_sub(start) <= (end - start)