From 234313f87b491e3fb160c8196f28ddc044924b6a Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sun, 12 May 2024 01:44:26 -0400 Subject: [PATCH] Simplify static_dict * Convert `IsMatch(dict, ...)` into a member method. The original `IsMatch` is marked as deprecated - and we probably can delete it, but it will require a major release due to being a breaking change. So for now, lets keep it, but remove it when releasing a new breaking version * Same for `BrotliFindAllStaticDictionaryMatches` and a few more methods (they were not moved though to allow for easier review) * lots of internal simplifications - like using direct comparisons, using bools, etc --- src/enc/backward_references/hq.rs | 9 +- src/enc/backward_references/mod.rs | 148 +++-- src/enc/static_dict.rs | 904 ++++++++++++++--------------- 3 files changed, 497 insertions(+), 564 deletions(-) diff --git a/src/enc/backward_references/hq.rs b/src/enc/backward_references/hq.rs index 43cce368..b3e54717 100644 --- a/src/enc/backward_references/hq.rs +++ b/src/enc/backward_references/hq.rs @@ -17,9 +17,7 @@ use crate::enc::command::{ use crate::enc::constants::{kCopyExtra, kInsExtra}; use crate::enc::encode; use crate::enc::literal_cost::BrotliEstimateBitCostsForLiterals; -use crate::enc::static_dict::{ - BrotliDictionary, BrotliFindAllStaticDictionaryMatches, FindMatchLengthWithLimit, -}; +use crate::enc::static_dict::{BrotliDictionary, FindMatchLengthWithLimit}; use crate::enc::util::{floatX, FastLog2, FastLog2f64}; const BROTLI_WINDOW_GAP: usize = 16; @@ -369,13 +367,12 @@ where { let minlen = max(4, best_len.wrapping_add(1)); if dictionary.is_some() - && BrotliFindAllStaticDictionaryMatches( - dictionary.unwrap(), + && dictionary.unwrap().find_all_matches( &data[cur_ix_masked..], minlen, max_length, &mut dict_matches[..], - ) != 0 + ) { assert!(params.use_dictionary); let maxlen = min(37, max_length); diff --git a/src/enc/backward_references/mod.rs b/src/enc/backward_references/mod.rs index 120c25dd..23b96c96 100644 --- a/src/enc/backward_references/mod.rs +++ b/src/enc/backward_references/mod.rs @@ -432,8 +432,7 @@ impl + SliceWrapper + BasicHashComputer> AnyHasher } } if dictionary.is_some() && self.buckets_.USE_DICTIONARY() != 0 && !is_match_found { - is_match_found = SearchInStaticDictionary( - dictionary.unwrap(), + is_match_found = dictionary.unwrap().search_static_item( dictionary_hash, self, &data[cur_ix_masked..], @@ -821,8 +820,7 @@ impl + alloc::Allocator> AnyHasher for H9 u32 { h >> (32i32 - 14i32) } -fn TestStaticDictionaryItem( - dictionary: &BrotliDictionary, - item: usize, - data: &[u8], - max_length: usize, - max_backward: usize, - max_distance: usize, - h9_opts: H9Opts, - out: &mut HasherSearchResult, -) -> i32 { - let backward: usize; - - let len: usize = item & 0x1fusize; - let dist: usize = item >> 5; - let offset: usize = - (dictionary.offsets_by_length[len] as usize).wrapping_add(len.wrapping_mul(dist)); - if len > max_length { - return 0i32; - } - let matchlen: usize = FindMatchLengthWithLimit(data, &dictionary.data[offset..], len); - if matchlen.wrapping_add(kCutoffTransformsCount as usize) <= len || matchlen == 0usize { - return 0i32; - } - { - let cut: u64 = len.wrapping_sub(matchlen) as u64; - let transform_id: usize = +impl BrotliDictionary { + fn test_static_item( + &self, + item: usize, + data: &[u8], + max_length: usize, + max_backward: usize, + max_distance: usize, + h9_opts: H9Opts, + out: &mut HasherSearchResult, + ) -> bool { + let len = item & 0x1f; + let dist = item >> 5; + let offset = (self.offsets_by_length[len] as usize).wrapping_add(len.wrapping_mul(dist)); + if len > max_length { + return false; + } + let matchlen: usize = FindMatchLengthWithLimit(data, &self.data[offset..], len); + if matchlen.wrapping_add(kCutoffTransformsCount as usize) <= len || matchlen == 0 { + return false; + } + + let cut = len.wrapping_sub(matchlen) as u64; + let transform_id = (cut << 2).wrapping_add(kCutoffTransforms >> cut.wrapping_mul(6) & 0x3f) as usize; - backward = max_backward + let backward = max_backward .wrapping_add(dist) .wrapping_add(1) - .wrapping_add(transform_id << dictionary.size_bits_by_length[len] as i32); - } - if backward > max_distance { - return 0i32; - } - let score: u64 = BackwardReferenceScore(matchlen, backward, h9_opts); - if score < out.score { - return 0i32; + .wrapping_add(transform_id << self.size_bits_by_length[len]); + + if backward > max_distance { + return false; + } + let score = BackwardReferenceScore(matchlen, backward, h9_opts); + if score < out.score { + return false; + } + out.len = matchlen; + out.len_x_code = len ^ matchlen; + out.distance = backward; + out.score = score; + true } - out.len = matchlen; - out.len_x_code = len ^ matchlen; - out.distance = backward; - out.score = score; - 1i32 -} -fn SearchInStaticDictionary( - dictionary: &BrotliDictionary, - dictionary_hash: &[u16], - handle: &mut HasherType, - data: &[u8], - max_length: usize, - max_backward: usize, - max_distance: usize, - out: &mut HasherSearchResult, - shallow: bool, -) -> bool { - let mut key: usize; - let mut i: usize; - let mut is_match_found = false; - let opts = handle.Opts(); - let xself: &mut Struct1 = handle.GetHasherCommon(); - if xself.dict_num_matches < xself.dict_num_lookups >> 7 { - return false; - } - key = (Hash14(data) << 1) as usize; //FIXME: works for any kind of hasher?? - i = 0usize; - while i < if shallow { 1 } else { 2 } { - { - let item: usize = dictionary_hash[key] as usize; + fn search_static_item( + &self, + dictionary_hash: &[u16], + handle: &mut HasherType, + data: &[u8], + max_length: usize, + max_backward: usize, + max_distance: usize, + out: &mut HasherSearchResult, + shallow: bool, + ) -> bool { + let mut is_match_found = false; + let opts = handle.Opts(); + let xself = handle.GetHasherCommon(); + if xself.dict_num_matches < xself.dict_num_lookups >> 7 { + return false; + } + let mut key = (Hash14(data) << 1) as usize; //FIXME: works for any kind of hasher?? + let iterations = if shallow { 1 } else { 2 }; + for _ in 0..iterations { + let item = dictionary_hash[key] as usize; xself.dict_num_lookups = xself.dict_num_lookups.wrapping_add(1); - if item != 0usize { - let item_matches: i32 = TestStaticDictionaryItem( - dictionary, + if item != 0 { + if self.test_static_item( item, data, max_length, @@ -1930,17 +1921,16 @@ fn SearchInStaticDictionary( max_distance, opts, out, - ); - if item_matches != 0 { + ) { xself.dict_num_matches = xself.dict_num_matches.wrapping_add(1); is_match_found = true; } } + key += 1; } - i = i.wrapping_add(1); - key = key.wrapping_add(1); + + is_match_found } - is_match_found } impl + alloc::Allocator> CloneWithAlloc diff --git a/src/enc/static_dict.rs b/src/enc/static_dict.rs index fa8f7a36..f2d7e905 100644 --- a/src/enc/static_dict.rs +++ b/src/enc/static_dict.rs @@ -1,16 +1,17 @@ use core::cmp::{max, min}; -pub const kNumDistanceCacheEntries: usize = 4; -use super::super::dictionary::{ +use brotli_decompressor::dictionary::{ kBrotliDictionary, kBrotliDictionaryOffsetsByLength, kBrotliDictionarySizeBitsByLength, }; -use super::static_dict_lut::{ + +use crate::enc::static_dict_lut::{ kDictHashMul32, kDictNumBits, kStaticDictionaryBuckets, kStaticDictionaryWords, DictWord, }; -#[allow(unused)] -static kUppercaseFirst: u8 = 10u8; -#[allow(unused)] +pub const kNumDistanceCacheEntries: usize = 4; + +const kUppercaseFirst: u8 = 10u8; + static kOmitLastNTransforms: [u8; 10] = [0, 12, 27, 23, 42, 63, 56, 48, 59, 64]; pub struct BrotliDictionary { @@ -110,8 +111,7 @@ macro_rules! sub_match8 { }; } -// factor of 10 slower (example takes 158s, not 30, and for the 30 second run it took 15 of them) -#[allow(unused)] +// factor of 10 slower (example takes 158s, not 30, and for the 30 seconds run it took 15 of them) pub fn SlowerFindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usize { for index in 0..limit { if s1[index] != s2[index] { @@ -121,7 +121,6 @@ pub fn SlowerFindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usi limit } // factor of 5 slower (example takes 90 seconds) -#[allow(unused)] pub fn FindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usize { for (index, pair) in s1[..limit].iter().zip(s2[..limit].iter()).enumerate() { if *pair.0 != *pair.1 { @@ -130,7 +129,6 @@ pub fn FindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usize { } limit } -#[allow(unused)] pub fn FindMatchLengthWithLimitMin4(s1: &[u8], s2: &[u8], limit: usize) -> usize { let (s1_start, s1_rest) = s1.split_at(5); let (s2_start, s2_rest) = s2.split_at(5); @@ -224,17 +222,16 @@ pub fn ComplexFindMatchLengthWithLimit(mut s1: &[u8], mut s2: &[u8], mut limit: sub_match8!(s1, s2, limit, matched, s1_as_64, s2_as_64); } } - assert!(s1.len() >= (limit & 7usize)); - assert!(s2.len() >= (limit & 7usize)); - for index in 0..(limit & 7usize) { + assert!(s1.len() >= (limit & 7)); + assert!(s2.len() >= (limit & 7)); + for index in 0..(limit & 7) { if s1[index] != s2[index] { return matched + index; } } - matched + (limit & 7usize) // made it through the loop + matched + (limit & 7) // made it through the loop } -#[allow(unused)] pub fn slowFindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usize { for (index, it) in s1[..limit].iter().zip(s2[..limit].iter()).enumerate() { if it.0 != it.1 { @@ -244,97 +241,105 @@ pub fn slowFindMatchLengthWithLimit(s1: &[u8], s2: &[u8], limit: usize) -> usize limit } +// TODO: delete because we probably don't want to make it public(?) +#[deprecated(note = "use BrotliDictionary::is_match(...) instead")] pub fn IsMatch(dictionary: &BrotliDictionary, w: DictWord, data: &[u8], max_length: usize) -> i32 { - if w.l as usize > max_length { - 0 + if dictionary.is_match(w, data, max_length) { + 1 } else { - let offset: usize = (dictionary.offsets_by_length[w.l as usize] as usize) - .wrapping_add((w.len() as usize).wrapping_mul(w.idx() as usize)); - let dict = &dictionary.data.split_at(offset).1; - if w.transform() as i32 == 0i32 { - if FindMatchLengthWithLimit(dict, data, w.l as usize) == w.l as usize { - 1 - } else { - 0 - } - } else if w.transform() as i32 == 10i32 { - if dict[0] as i32 >= b'a' as i32 - && (dict[0] as i32 <= b'z' as i32) - && (dict[0] as i32 ^ 32i32 == data[0] as i32) - && (FindMatchLengthWithLimit( - dict.split_at(1).1, - data.split_at(1).1, - (w.len() as u32).wrapping_sub(1) as usize, - ) == (w.len() as u32).wrapping_sub(1) as usize) - { - 1 - } else { - 0 - } + 0 + } +} + +impl BrotliDictionary { + pub(crate) fn is_match(&self, w: DictWord, data: &[u8], max_length: usize) -> bool { + if w.l as usize > max_length { + false } else { - for i in 0usize..w.len() as usize { - if dict[i] as i32 >= b'a' as i32 && (dict[i] as i32 <= b'z' as i32) { - if dict[i] as i32 ^ 32i32 != data[i] as i32 { - return 0; + let offset: usize = (self.offsets_by_length[w.l as usize] as usize) + .wrapping_add((w.len() as usize).wrapping_mul(w.idx() as usize)); + let dict = self.data.split_at(offset).1; + if w.transform() == 0 { + FindMatchLengthWithLimit(dict, data, w.l as usize) == w.l as usize + } else if w.transform() == 10 { + dict[0] >= b'a' + && dict[0] <= b'z' + && dict[0] ^ 32 == data[0] + && (FindMatchLengthWithLimit( + dict.split_at(1).1, + data.split_at(1).1, + (w.len() as u32).wrapping_sub(1) as usize, + ) == (w.len() as u32).wrapping_sub(1) as usize) + } else { + for i in 0..w.len() as usize { + if dict[i] >= b'a' && dict[i] <= b'z' { + if dict[i] ^ 32 != data[i] { + return false; + } + } else if dict[i] != data[i] { + return false; } - } else if dict[i] as i32 != data[i] as i32 { - return 0; } + true } - 1 } } } -#[allow(unused)] -fn AddMatch(distance: usize, len: usize, len_code: usize, mut matches: &mut [u32]) { +fn AddMatch(distance: usize, len: usize, len_code: usize, matches: &mut [u32]) { let match_: u32 = (distance << 5).wrapping_add(len_code) as u32; matches[len] = min(matches[len], match_); } -#[allow(unused)] -fn DictMatchLength( - dictionary: &BrotliDictionary, - data: &[u8], - id: usize, - len: usize, - maxlen: usize, -) -> usize { - let offset: usize = - (dictionary.offsets_by_length[len] as usize).wrapping_add(len.wrapping_mul(id)); - FindMatchLengthWithLimit(dictionary.data.split_at(offset).1, data, min(len, maxlen)) -} - -#[allow(unused)] +// TODO: delete because we probably don't want to make it public(?) +#[deprecated(note = "use BrotliDictionary::find_all_matches(...) instead")] pub fn BrotliFindAllStaticDictionaryMatches( dictionary: &BrotliDictionary, data: &[u8], min_length: usize, max_length: usize, - mut matches: &mut [u32], + matches: &mut [u32], ) -> i32 { - let mut has_found_match: i32 = 0i32; - { + if dictionary.find_all_matches(data, min_length, max_length, matches) { + 1 + } else { + 0 + } +} + +impl BrotliDictionary { + fn dict_match_length(&self, data: &[u8], id: usize, len: usize, maxlen: usize) -> usize { + let offset: usize = + (self.offsets_by_length[len] as usize).wrapping_add(len.wrapping_mul(id)); + FindMatchLengthWithLimit(self.data.split_at(offset).1, data, min(len, maxlen)) + } + + pub(crate) fn find_all_matches( + &self, + data: &[u8], + min_length: usize, + max_length: usize, + matches: &mut [u32], + ) -> bool { + let mut has_found_match = false; let mut offset: usize = kStaticDictionaryBuckets[Hash(data) as usize] as usize; - let mut end: i32 = (offset == 0) as i32; - while end == 0 { + let mut end = (offset == 0); + while !end { let mut w: DictWord = kStaticDictionaryWords[offset]; offset = offset.wrapping_add(1); - let l: usize = (w.len() as i32 & 0x1fi32) as usize; - let n: usize = 1usize << dictionary.size_bits_by_length[l] as i32; - let id: usize = w.idx() as usize; - end = !(w.len() as i32 & 0x80i32 == 0) as i32; + let l = (w.len() & 0x1f) as usize; + let n: usize = 1usize << self.size_bits_by_length[l]; + let id = w.idx() as usize; + end = !(w.len() & 0x80 == 0); w.l = l as u8; - if w.transform() as i32 == 0i32 { - let matchlen: usize = DictMatchLength(dictionary, data, id, l, max_length); - + if w.transform() == 0 { + let matchlen: usize = self.dict_match_length(data, id, l, max_length); let mut minlen: usize; - let mut len: usize; if matchlen == l { //eprint!("Adding match {} {} {}\n", w.len(), w.transform(), w.idx()); AddMatch(id, l, l, matches); - has_found_match = 1i32; + has_found_match = true; } if matchlen >= l.wrapping_sub(1) { //eprint!("Bdding match {} {} {}\n", w.len(), w.transform(), w.idx()); @@ -345,10 +350,10 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); if l.wrapping_add(2) < max_length - && (data[(l.wrapping_sub(1) as usize)] as i32 == b'i' as i32) - && (data[(l as usize)] as i32 == b'n' as i32) - && (data[(l.wrapping_add(1) as usize)] as i32 == b'g' as i32) - && (data[(l.wrapping_add(2) as usize)] as i32 == b' ' as i32) + && data[l.wrapping_sub(1)] == b'i' + && data[l] == b'n' + && data[l.wrapping_add(1)] == b'g' + && data[l.wrapping_add(2)] == b' ' { //eprint!("Cdding match {} {} {}\n", w.len(), w.transform(), w.idx()); AddMatch( @@ -358,10 +363,10 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - has_found_match = 1i32; + has_found_match = true; } minlen = min_length; - if l > 9usize { + if l > 9 { minlen = max(minlen, l.wrapping_sub(9)); } let maxlen: usize = min(matchlen, l.wrapping_sub(2)); @@ -375,18 +380,18 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - has_found_match = 1i32; + has_found_match = true; } if matchlen < l || l.wrapping_add(6) >= max_length { continue; } - let s: &[u8] = data.split_at(l as usize).1; - if s[0] as i32 == b' ' as i32 { + let s: &[u8] = data.split_at(l).1; + if s[0] == b' ' { //eprint!("Edding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch(id.wrapping_add(n), l.wrapping_add(1), l, matches); - if s[1] as i32 == b'a' as i32 { - if s[2] as i32 == b' ' as i32 { + if s[1] == b'a' { + if s[2] == b' ' { //eprint!("Fdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((28usize).wrapping_mul(n)), @@ -394,8 +399,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[2] as i32 == b's' as i32 { - if s[3] as i32 == b' ' as i32 { + } else if s[2] == b's' { + if s[3] == b' ' { //eprint!("Gdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((46usize).wrapping_mul(n)), @@ -404,8 +409,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b't' as i32 { - if s[3] as i32 == b' ' as i32 { + } else if s[2] == b't' { + if s[3] == b' ' { //eprint!("Hdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((60usize).wrapping_mul(n)), @@ -414,10 +419,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b'n' as i32 - && s[3] as i32 == b'd' as i32 - && (s[4] as i32 == b' ' as i32) - { + } else if s[2] == b'n' && s[3] == b'd' && (s[4] == b' ') { //eprint!("Idding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((10usize).wrapping_mul(n)), @@ -426,8 +428,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'b' as i32 { - if s[2] as i32 == b'y' as i32 && (s[3] as i32 == b' ' as i32) { + } else if s[1] == b'b' { + if s[2] == b'y' && s[3] == b' ' { //eprint!("Jdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((38usize).wrapping_mul(n)), @@ -436,9 +438,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'i' as i32 { - if s[2] as i32 == b'n' as i32 { - if s[3] as i32 == b' ' as i32 { + } else if s[1] == b'i' { + if s[2] == b'n' { + if s[3] == b' ' { //eprint!("Kdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((16usize).wrapping_mul(n)), @@ -447,7 +449,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b's' as i32 && s[3] as i32 == b' ' as i32 { + } else if s[2] == b's' && s[3] == b' ' { //eprint!("Ldding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((47usize).wrapping_mul(n)), @@ -456,9 +458,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'f' as i32 { - if s[2] as i32 == b'o' as i32 { - if s[3] as i32 == b'r' as i32 && (s[4] as i32 == b' ' as i32) { + } else if s[1] == b'f' { + if s[2] == b'o' { + if s[3] == b'r' && s[4] == b' ' { //eprint!("Mdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((25usize).wrapping_mul(n)), @@ -467,11 +469,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b'r' as i32 - && s[3] as i32 == b'o' as i32 - && (s[4] as i32 == b'm' as i32) - && (s[5] as i32 == b' ' as i32) - { + } else if s[2] == b'r' && s[3] == b'o' && s[4] == b'm' && s[5] == b' ' { //eprint!("Ndding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((37usize).wrapping_mul(n)), @@ -480,9 +478,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'o' as i32 { - if s[2] as i32 == b'f' as i32 { - if s[3] as i32 == b' ' as i32 { + } else if s[1] == b'o' { + if s[2] == b'f' { + if s[3] == b' ' { //eprint!("Odding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((8usize).wrapping_mul(n)), @@ -491,7 +489,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b'n' as i32 && s[3] as i32 == b' ' as i32 { + } else if s[2] == b'n' && s[3] == b' ' { //eprint!("Pdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((45usize).wrapping_mul(n)), @@ -500,11 +498,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'n' as i32 { - if s[2] as i32 == b'o' as i32 - && (s[3] as i32 == b't' as i32) - && (s[4] as i32 == b' ' as i32) - { + } else if s[1] == b'n' { + if s[2] == b'o' && s[3] == b't' && s[4] == b' ' { //eprint!("Qdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((80usize).wrapping_mul(n)), @@ -513,10 +508,10 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b't' as i32 { - if s[2] as i32 == b'h' as i32 { - if s[3] as i32 == b'e' as i32 { - if s[4] as i32 == b' ' as i32 { + } else if s[1] == b't' { + if s[2] == b'h' { + if s[3] == b'e' { + if s[4] == b' ' { //eprint!("Rdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((5usize).wrapping_mul(n)), @@ -525,10 +520,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[3] as i32 == b'a' as i32 - && s[4] as i32 == b't' as i32 - && (s[5] as i32 == b' ' as i32) - { + } else if s[3] == b'a' && s[4] == b't' && s[5] == b' ' { //eprint!("Sdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((29usize).wrapping_mul(n)), @@ -537,7 +529,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[2] as i32 == b'o' as i32 && s[3] as i32 == b' ' as i32 { + } else if s[2] == b'o' && s[3] == b' ' { //eprint!("Tdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((17usize).wrapping_mul(n)), @@ -546,11 +538,11 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'w' as i32 - && s[2] as i32 == b'i' as i32 - && (s[3] as i32 == b't' as i32) - && (s[4] as i32 == b'h' as i32) - && (s[5] as i32 == b' ' as i32) + } else if s[1] == b'w' + && s[2] == b'i' + && s[3] == b't' + && s[4] == b'h' + && s[5] == b' ' { //eprint!("Udding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( @@ -560,7 +552,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'\"' as i32 { + } else if s[0] == b'\"' { //eprint!("Vdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((19usize).wrapping_mul(n)), @@ -568,7 +560,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b'>' as i32 { + if s[1] == b'>' { //eprint!("Wdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((21usize).wrapping_mul(n)), @@ -577,7 +569,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'.' as i32 { + } else if s[0] == b'.' { //eprint!("Xdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((20usize).wrapping_mul(n)), @@ -585,7 +577,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b' ' as i32 { + if s[1] == b' ' { //eprint!("Ydding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((31usize).wrapping_mul(n)), @@ -593,9 +585,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[2] as i32 == b'T' as i32 && (s[3] as i32 == b'h' as i32) { - if s[4] as i32 == b'e' as i32 { - if s[5] as i32 == b' ' as i32 { + if s[2] == b'T' && s[3] == b'h' { + if s[4] == b'e' { + if s[5] == b' ' { //eprint!("Zdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((43usize).wrapping_mul(n)), @@ -604,10 +596,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[4] as i32 == b'i' as i32 - && s[5] as i32 == b's' as i32 - && (s[6] as i32 == b' ' as i32) - { + } else if s[4] == b'i' && s[5] == b's' && s[6] == b' ' { //eprint!("AAdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((75usize).wrapping_mul(n)), @@ -618,7 +607,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( } } } - } else if s[0] as i32 == b',' as i32 { + } else if s[0] == b',' { //eprint!("ABdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((76usize).wrapping_mul(n)), @@ -626,7 +615,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b' ' as i32 { + if s[1] == b' ' { //eprint!("ACdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((14usize).wrapping_mul(n)), @@ -635,7 +624,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'\n' as i32 { + } else if s[0] == b'\n' { //eprint!("ADdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((22usize).wrapping_mul(n)), @@ -643,7 +632,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b'\t' as i32 { + if s[1] == b'\t' { //eprint!("AEdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((50usize).wrapping_mul(n)), @@ -652,7 +641,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b']' as i32 { + } else if s[0] == b']' { //eprint!("AFdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((24usize).wrapping_mul(n)), @@ -660,7 +649,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'\'' as i32 { + } else if s[0] == b'\'' { //eprint!("AGdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((36usize).wrapping_mul(n)), @@ -668,7 +657,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b':' as i32 { + } else if s[0] == b':' { //eprint!("AHdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((51usize).wrapping_mul(n)), @@ -676,7 +665,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'(' as i32 { + } else if s[0] == b'(' { //eprint!("AIdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((57usize).wrapping_mul(n)), @@ -684,8 +673,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'=' as i32 { - if s[1] as i32 == b'\"' as i32 { + } else if s[0] == b'=' { + if s[1] == b'\"' { //eprint!("AJdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((70usize).wrapping_mul(n)), @@ -693,7 +682,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[1] as i32 == b'\'' as i32 { + } else if s[1] == b'\'' { //eprint!("AKdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((86usize).wrapping_mul(n)), @@ -702,8 +691,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'a' as i32 { - if s[1] as i32 == b'l' as i32 && (s[2] as i32 == b' ' as i32) { + } else if s[0] == b'a' { + if s[1] == b'l' && s[2] == b' ' { //eprint!("ALdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((84usize).wrapping_mul(n)), @@ -712,9 +701,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'e' as i32 { - if s[1] as i32 == b'd' as i32 { - if s[2] as i32 == b' ' as i32 { + } else if s[0] == b'e' { + if s[1] == b'd' { + if s[2] == b' ' { //eprint!("AMdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((53usize).wrapping_mul(n)), @@ -723,8 +712,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'r' as i32 { - if s[2] as i32 == b' ' as i32 { + } else if s[1] == b'r' { + if s[2] == b' ' { //eprint!("ANdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((82usize).wrapping_mul(n)), @@ -733,10 +722,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b's' as i32 - && s[2] as i32 == b't' as i32 - && (s[3] as i32 == b' ' as i32) - { + } else if s[1] == b's' && s[2] == b't' && s[3] == b' ' { //eprint!("AOdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((95usize).wrapping_mul(n)), @@ -745,11 +731,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'f' as i32 { - if s[1] as i32 == b'u' as i32 - && (s[2] as i32 == b'l' as i32) - && (s[3] as i32 == b' ' as i32) - { + } else if s[0] == b'f' { + if s[1] == b'u' && s[2] == b'l' && s[3] == b' ' { //eprint!("APdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((90usize).wrapping_mul(n)), @@ -758,9 +741,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'i' as i32 { - if s[1] as i32 == b'v' as i32 { - if s[2] as i32 == b'e' as i32 && (s[3] as i32 == b' ' as i32) { + } else if s[0] == b'i' { + if s[1] == b'v' { + if s[2] == b'e' && s[3] == b' ' { //eprint!("AQdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((92usize).wrapping_mul(n)), @@ -769,10 +752,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'z' as i32 - && s[2] as i32 == b'e' as i32 - && (s[3] as i32 == b' ' as i32) - { + } else if s[1] == b'z' && s[2] == b'e' && s[3] == b' ' { //eprint!("ARdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((100usize).wrapping_mul(n)), @@ -781,12 +761,9 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'l' as i32 { - if s[1] as i32 == b'e' as i32 { - if s[2] as i32 == b's' as i32 - && (s[3] as i32 == b's' as i32) - && (s[4] as i32 == b' ' as i32) - { + } else if s[0] == b'l' { + if s[1] == b'e' { + if s[2] == b's' && s[3] == b's' && s[4] == b' ' { //eprint!("ASdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((93usize).wrapping_mul(n)), @@ -795,7 +772,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[1] as i32 == b'y' as i32 && s[2] as i32 == b' ' as i32 { + } else if s[1] == b'y' && s[2] == b' ' { //eprint!("ATdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((61usize).wrapping_mul(n)), @@ -804,11 +781,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'o' as i32 - && s[1] as i32 == b'u' as i32 - && (s[2] as i32 == b's' as i32) - && (s[3] as i32 == b' ' as i32) - { + } else if s[0] == b'o' && s[1] == b'u' && s[2] == b's' && s[3] == b' ' { //eprint!("AUdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), len); AddMatch( id.wrapping_add((106usize).wrapping_mul(n)), @@ -820,7 +793,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( } else { let is_all_caps = w.transform() != kUppercaseFirst; - if IsMatch(dictionary, w, data, max_length) == 0 { + if !self.is_match(w, data, max_length) { continue; } //eprint!("AVdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); @@ -830,12 +803,12 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - has_found_match = 1i32; + has_found_match = true; if l.wrapping_add(1) >= max_length { continue; } - let s: &[u8] = data.split_at(l as usize).1; - if s[0] as i32 == b' ' as i32 { + let s: &[u8] = data.split_at(l).1; + if s[0] == b' ' { //eprint!("AWdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -845,7 +818,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'\"' as i32 { + } else if s[0] == b'\"' { //eprint!("AXdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -855,7 +828,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b'>' as i32 { + if s[1] == b'>' { //eprint!("AYdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -866,7 +839,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'.' as i32 { + } else if s[0] == b'.' { //eprint!("AZdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -876,7 +849,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b' ' as i32 { + if s[1] == b' ' { //eprint!("BAdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -887,7 +860,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b',' as i32 { + } else if s[0] == b',' { //eprint!("BBdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -897,7 +870,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - if s[1] as i32 == b' ' as i32 { + if s[1] == b' ' { //eprint!("BCdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -908,7 +881,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( matches, ); } - } else if s[0] as i32 == b'\'' as i32 { + } else if s[0] == b'\'' { //eprint!("BDdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -918,7 +891,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'(' as i32 { + } else if s[0] == b'(' { //eprint!("BEdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -928,8 +901,8 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[0] as i32 == b'=' as i32 { - if s[1] as i32 == b'\"' as i32 { + } else if s[0] == b'=' { + if s[1] == b'\"' { //eprint!("BFdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -939,7 +912,7 @@ pub fn BrotliFindAllStaticDictionaryMatches( l, matches, ); - } else if s[1] as i32 == b'\'' as i32 { + } else if s[1] == b'\'' { //eprint!("BGdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( @@ -953,354 +926,327 @@ pub fn BrotliFindAllStaticDictionaryMatches( } } } - } - if max_length >= 5usize && (data[0] as i32 == b' ' as i32 || data[0] as i32 == b'.' as i32) { - let is_space = data[0] == b' '; - let mut offset: usize = - kStaticDictionaryBuckets[Hash(data.split_at(1).1) as usize] as usize; - let mut end: i32 = (offset == 0) as i32; - while end == 0 { - let mut w: DictWord = kStaticDictionaryWords[offset]; - offset = offset.wrapping_add(1); - let l: usize = (w.len() as i32 & 0x1fi32) as usize; - let n: usize = 1usize << dictionary.size_bits_by_length[l] as i32; - let id: usize = w.idx() as usize; - end = !(w.len() as i32 & 0x80i32 == 0) as i32; - w.l = l as u8; - if w.transform() as i32 == 0i32 { - if IsMatch( - dictionary, - w, - data.split_at(1).1, - max_length.wrapping_sub(1), - ) == 0 - { - continue; - } - //eprint!("BHdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((if is_space { 6usize } else { 32usize }).wrapping_mul(n)), - l.wrapping_add(1), - l, - matches, - ); - has_found_match = 1i32; - if l.wrapping_add(2) >= max_length { - continue; - } - let s: &[u8] = data.split_at(l.wrapping_add(1) as usize).1; - if s[0] as i32 == b' ' as i32 { - //eprint!("BIdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((if is_space { 2usize } else { 77usize }).wrapping_mul(n)), - l.wrapping_add(2), - l, - matches, - ); - } else if s[0] as i32 == b'(' as i32 { - //eprint!("BJdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + + if max_length >= 5 && (data[0] == b' ' || data[0] == b'.') { + let is_space = data[0] == b' '; + let mut offset: usize = + kStaticDictionaryBuckets[Hash(data.split_at(1).1) as usize] as usize; + let mut end = (offset == 0); + while !end { + let mut w: DictWord = kStaticDictionaryWords[offset]; + offset = offset.wrapping_add(1); + let l = (w.len() & 0x1f) as usize; + let n: usize = 1usize << self.size_bits_by_length[l]; + let id = w.idx() as usize; + end = !(w.len() & 0x80 == 0); + w.l = l as u8; + if w.transform() == 0 { + if !self.is_match(w, data.split_at(1).1, max_length.wrapping_sub(1)) { + continue; + } + //eprint!("BHdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((if is_space { 89usize } else { 67usize }).wrapping_mul(n)), - l.wrapping_add(2), + id.wrapping_add((if is_space { 6usize } else { 32usize }).wrapping_mul(n)), + l.wrapping_add(1), l, matches, ); - } else if is_space { - if s[0] as i32 == b',' as i32 { - //eprint!("BKdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + has_found_match = true; + if l.wrapping_add(2) >= max_length { + continue; + } + let s: &[u8] = data.split_at(l.wrapping_add(1)).1; + if s[0] == b' ' { + //eprint!("BIdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((103usize).wrapping_mul(n)), + id.wrapping_add( + (if is_space { 2usize } else { 77usize }).wrapping_mul(n), + ), l.wrapping_add(2), l, matches, ); - if s[1] as i32 == b' ' as i32 { - //eprint!("BLdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((33usize).wrapping_mul(n)), - l.wrapping_add(3), - l, - matches, - ); - } - } else if s[0] as i32 == b'.' as i32 { - //eprint!("BMdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + } else if s[0] == b'(' { + //eprint!("BJdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((71usize).wrapping_mul(n)), + id.wrapping_add( + (if is_space { 89usize } else { 67usize }).wrapping_mul(n), + ), l.wrapping_add(2), l, matches, ); - if s[1] as i32 == b' ' as i32 { - //eprint!("BNdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((52usize).wrapping_mul(n)), - l.wrapping_add(3), - l, - matches, - ); - } - } else if s[0] as i32 == b'=' as i32 { - if s[1] as i32 == b'\"' as i32 { - //eprint!("BOdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + } else if is_space { + if s[0] == b',' { + //eprint!("BKdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((81usize).wrapping_mul(n)), - l.wrapping_add(3), + id.wrapping_add((103usize).wrapping_mul(n)), + l.wrapping_add(2), l, matches, ); - } else if s[1] as i32 == b'\'' as i32 { - //eprint!("BPdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + if s[1] == b' ' { + //eprint!("BLdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((33usize).wrapping_mul(n)), + l.wrapping_add(3), + l, + matches, + ); + } + } else if s[0] == b'.' { + //eprint!("BMdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((98usize).wrapping_mul(n)), - l.wrapping_add(3), + id.wrapping_add((71usize).wrapping_mul(n)), + l.wrapping_add(2), l, matches, ); + if s[1] == b' ' { + //eprint!("BNdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((52usize).wrapping_mul(n)), + l.wrapping_add(3), + l, + matches, + ); + } + } else if s[0] == b'=' { + if s[1] == b'\"' { + //eprint!("BOdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((81usize).wrapping_mul(n)), + l.wrapping_add(3), + l, + matches, + ); + } else if s[1] == b'\'' { + //eprint!("BPdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((98usize).wrapping_mul(n)), + l.wrapping_add(3), + l, + matches, + ); + } } } - } - } else if is_space { - let is_all_caps = w.transform() != kUppercaseFirst; + } else if is_space { + let is_all_caps = w.transform() != kUppercaseFirst; - if IsMatch( - dictionary, - w, - data.split_at(1).1, - max_length.wrapping_sub(1), - ) == 0 - { - continue; - } - //eprint!("CAdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((if is_all_caps { 85usize } else { 30usize }).wrapping_mul(n)), - l.wrapping_add(1), - l, - matches, - ); - has_found_match = 1i32; - if l.wrapping_add(2) >= max_length { - continue; - } - let s: &[u8] = data.split_at(l.wrapping_add(1)).1; - if s[0] as i32 == b' ' as i32 { - //eprint!("CBdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + if !self.is_match(w, data.split_at(1).1, max_length.wrapping_sub(1)) { + continue; + } + //eprint!("CAdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( - (if is_all_caps { 83usize } else { 15usize }).wrapping_mul(n), + (if is_all_caps { 85usize } else { 30usize }).wrapping_mul(n), ), - l.wrapping_add(2), + l.wrapping_add(1), l, matches, ); - } else if s[0] as i32 == b',' as i32 { - if !is_all_caps { - //eprint!("CCdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((109usize).wrapping_mul(n)), - l.wrapping_add(2), - l, - matches, - ); + has_found_match = true; + if l.wrapping_add(2) >= max_length { + continue; } - if s[1] as i32 == b' ' as i32 { - //eprint!("CDdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + let s: &[u8] = data.split_at(l.wrapping_add(1)).1; + if s[0] == b' ' { + //eprint!("CBdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( - (if is_all_caps { 111usize } else { 65usize }).wrapping_mul(n), + (if is_all_caps { 83usize } else { 15usize }).wrapping_mul(n), ), - l.wrapping_add(3), + l.wrapping_add(2), l, matches, ); - } - } else if s[0] as i32 == b'.' as i32 { - //eprint!("CEdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add( - (if is_all_caps { 115usize } else { 96usize }).wrapping_mul(n), - ), - l.wrapping_add(2), - l, - matches, - ); - if s[1] as i32 == b' ' as i32 { - //eprint!("CFdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + } else if s[0] == b',' { + if !is_all_caps { + //eprint!("CCdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((109usize).wrapping_mul(n)), + l.wrapping_add(2), + l, + matches, + ); + } + if s[1] == b' ' { + //eprint!("CDdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add( + (if is_all_caps { 111usize } else { 65usize }).wrapping_mul(n), + ), + l.wrapping_add(3), + l, + matches, + ); + } + } else if s[0] == b'.' { + //eprint!("CEdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( id.wrapping_add( - (if is_all_caps { 117usize } else { 91usize }).wrapping_mul(n), + (if is_all_caps { 115usize } else { 96usize }).wrapping_mul(n), ), - l.wrapping_add(3), + l.wrapping_add(2), l, matches, ); + if s[1] == b' ' { + //eprint!("CFdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add( + (if is_all_caps { 117usize } else { 91usize }).wrapping_mul(n), + ), + l.wrapping_add(3), + l, + matches, + ); + } + } else if s[0] == b'=' { + if s[1] == b'\"' { + //eprint!("CGdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add( + (if is_all_caps { 110usize } else { 118usize }).wrapping_mul(n), + ), + l.wrapping_add(3), + l, + matches, + ); + } else if s[1] == b'\'' { + //eprint!("CHdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add( + (if is_all_caps { 119usize } else { 120usize }).wrapping_mul(n), + ), + l.wrapping_add(3), + l, + matches, + ); + } } - } else if s[0] as i32 == b'=' as i32 { - if s[1] as i32 == b'\"' as i32 { - //eprint!("CGdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + } + } + } + if max_length >= 6 + && (data[1] == b' ' && (data[0] == b'e' || data[0] == b's' || data[0] == b',') + || data[0] == 0xc2 && data[1] == 0xa0) + { + let mut offset = kStaticDictionaryBuckets[Hash(data.split_at(2).1) as usize] as usize; + let mut end = (offset == 0); + while !end { + let mut w: DictWord = kStaticDictionaryWords[offset]; + offset = offset.wrapping_add(1); + let l = (w.len() & 0x1f) as usize; + let n: usize = 1usize << self.size_bits_by_length[l]; + let id = w.idx() as usize; + end = !(w.len() & 0x80 == 0); + w.l = l as u8; + if w.transform() == 0 + && self.is_match(w, data.split_at(2).1, max_length.wrapping_sub(2)) + { + if data[0] == 0xc2 { + //eprint!("CIdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add( - (if is_all_caps { 110usize } else { 118usize }).wrapping_mul(n), - ), - l.wrapping_add(3), + id.wrapping_add((102usize).wrapping_mul(n)), + l.wrapping_add(2), l, matches, ); - } else if s[1] as i32 == b'\'' as i32 { - //eprint!("CHdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + has_found_match = true; + } else if l.wrapping_add(2) < max_length && data[l.wrapping_add(2)] == b' ' { + let t = (if data[0] == b'e' { + 18 + } else if data[0] == b's' { + 7 + } else { + 13 + }) as usize; + //eprint!("CJdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add( - (if is_all_caps { 119usize } else { 120usize }).wrapping_mul(n), - ), + id.wrapping_add(t.wrapping_mul(n)), l.wrapping_add(3), l, matches, ); + has_found_match = true; } } } } - } - if max_length >= 6usize - && (data[1] as i32 == b' ' as i32 - && (data[0] as i32 == b'e' as i32 - || data[0] as i32 == b's' as i32 - || data[0] as i32 == b',' as i32) - || data[0] as i32 == 0xc2i32 && (data[1] as i32 == 0xa0i32)) - { - let mut offset: usize = - kStaticDictionaryBuckets[Hash(data.split_at(2).1) as usize] as usize; - let mut end: i32 = (offset == 0) as i32; - while end == 0 { - let mut w: DictWord = kStaticDictionaryWords[offset]; - offset = offset.wrapping_add(1); - let l: usize = (w.len() as i32 & 0x1fi32) as usize; - let n: usize = 1usize << dictionary.size_bits_by_length[l] as i32; - let id: usize = w.idx() as usize; - end = !(w.len() as i32 & 0x80i32 == 0) as i32; - w.l = l as u8; - if w.transform() as i32 == 0i32 - && (IsMatch( - dictionary, - w, - data.split_at(2).1, - max_length.wrapping_sub(2), - ) != 0) - { - if data[0] as i32 == 0xc2i32 { - //eprint!("CIdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((102usize).wrapping_mul(n)), - l.wrapping_add(2), - l, - matches, - ); - has_found_match = 1i32; - } else if l.wrapping_add(2) < max_length - && (data[(l.wrapping_add(2) as usize)] as i32 == b' ' as i32) + if max_length >= 9 + && (data[0] == b' ' + && data[1] == b't' + && data[2] == b'h' + && data[3] == b'e' + && data[4] == b' ' + || data[0] == b'.' + && data[1] == b'c' + && data[2] == b'o' + && data[3] == b'm' + && data[4] == b'/') + { + let mut offset = kStaticDictionaryBuckets[Hash(data.split_at(5).1) as usize] as usize; + let mut end = (offset == 0); + while !end { + let mut w: DictWord = kStaticDictionaryWords[offset]; + offset = offset.wrapping_add(1); + let l = (w.len() & 0x1f) as usize; + let n: usize = 1usize << self.size_bits_by_length[l]; + let id = w.idx() as usize; + end = !(w.len() & 0x80 == 0); + w.l = l as u8; + if w.transform() == 0 + && self.is_match(w, data.split_at(5).1, max_length.wrapping_sub(5)) { - let t: usize = (if data[0] as i32 == b'e' as i32 { - 18i32 - } else if data[0] as i32 == b's' as i32 { - 7i32 - } else { - 13i32 - }) as usize; - //eprint!("CJdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + //eprint!("CKdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add(t.wrapping_mul(n)), - l.wrapping_add(3), + id.wrapping_add( + (if data[0] == b' ' { 41_usize } else { 72_usize }).wrapping_mul(n), + ), + l.wrapping_add(5), l, matches, ); - has_found_match = 1i32; - } - } - } - } - if max_length >= 9usize - && (data[0] as i32 == b' ' as i32 - && (data[1] as i32 == b't' as i32) - && (data[2] as i32 == b'h' as i32) - && (data[3] as i32 == b'e' as i32) - && (data[4] as i32 == b' ' as i32) - || data[0] as i32 == b'.' as i32 - && (data[1] as i32 == b'c' as i32) - && (data[2] as i32 == b'o' as i32) - && (data[3] as i32 == b'm' as i32) - && (data[4] as i32 == b'/' as i32)) - { - let mut offset: usize = - kStaticDictionaryBuckets[Hash(data.split_at(5).1) as usize] as usize; - let mut end: i32 = (offset == 0) as i32; - while end == 0 { - let mut w: DictWord = kStaticDictionaryWords[offset]; - offset = offset.wrapping_add(1); - let l: usize = (w.len() as i32 & 0x1fi32) as usize; - let n: usize = 1usize << dictionary.size_bits_by_length[l] as i32; - let id: usize = w.idx() as usize; - end = !(w.len() as i32 & 0x80i32 == 0) as i32; - w.l = l as u8; - if w.transform() as i32 == 0i32 - && (IsMatch( - dictionary, - w, - data.split_at(5).1, - max_length.wrapping_sub(5), - ) != 0) - { - //eprint!("CKdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add( - (if data[0] as i32 == b' ' as i32 { - 41i32 - } else { - 72i32 - } as usize) - .wrapping_mul(n), - ), - l.wrapping_add(5), - l, - matches, - ); - has_found_match = 1i32; - if l.wrapping_add(5) < max_length { - let s: &[u8] = data.split_at(l.wrapping_add(5) as usize).1; - if data[0] as i32 == b' ' as i32 - && l.wrapping_add(8) < max_length - && (s[0] as i32 == b' ' as i32) - && (s[1] as i32 == b'o' as i32) - && (s[2] as i32 == b'f' as i32) - && (s[3] as i32 == b' ' as i32) - { - //eprint!("CLdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); - AddMatch( - id.wrapping_add((62usize).wrapping_mul(n)), - l.wrapping_add(9), - l, - matches, - ); - if l.wrapping_add(12) < max_length - && (s[4] as i32 == b't' as i32) - && (s[5] as i32 == b'h' as i32) - && (s[6] as i32 == b'e' as i32) - && (s[7] as i32 == b' ' as i32) + has_found_match = true; + if l.wrapping_add(5) < max_length { + let s: &[u8] = data.split_at(l.wrapping_add(5)).1; + if data[0] == b' ' + && l.wrapping_add(8) < max_length + && s[0] == b' ' + && s[1] == b'o' + && s[2] == b'f' + && s[3] == b' ' { - //eprint!("BQdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + //eprint!("CLdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); AddMatch( - id.wrapping_add((73usize).wrapping_mul(n)), - l.wrapping_add(13), + id.wrapping_add((62usize).wrapping_mul(n)), + l.wrapping_add(9), l, matches, ); + if l.wrapping_add(12) < max_length + && s[4] == b't' + && s[5] == b'h' + && s[6] == b'e' + && s[7] == b' ' + { + //eprint!("BQdding match {} {} {} {}\n", w.len(), w.transform(), w.idx(), 666); + AddMatch( + id.wrapping_add((73usize).wrapping_mul(n)), + l.wrapping_add(13), + l, + matches, + ); + } } } } } } + has_found_match } - has_found_match } #[cfg(test)]