Revision control
Copy as Markdown
Other Tools
/*
* Copyright Stalwart Labs Ltd. See the COPYING
* file at the top-level directory of this distribution.
*
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
* option. This file may not be copied, modified, or distributed
* except according to those terms.
*/
use super::{
multi_byte::*,
single_byte::*,
utf::{decoder_utf16, decoder_utf16_be, decoder_utf16_le, decoder_utf7},
DecoderFnc,
};
pub fn charset_decoder(charset: &[u8]) -> Option<DecoderFnc> {
if (2..=45).contains(&charset.len()) {
let mut l_charset = [0u8; 45];
let mut hash = charset.len();
let mut ch = 0;
for (pos, ch_) in charset.iter().enumerate() {
ch = match ch_ {
b'A'..=b'Z' => *ch_ + 32,
b'-' => b'_',
_ => *ch_,
};
#[cfg(feature = "ludicrous_mode")]
unsafe {
*l_charset.get_unchecked_mut(pos) = ch;
}
#[cfg(not(feature = "ludicrous_mode"))]
{
l_charset[pos] = ch;
}
if let 0 | 2 | 6 | 7 | 8 | 9 = pos {
hash += {
#[cfg(feature = "ludicrous_mode")]
unsafe {
*CH_HASH.get_unchecked(ch as usize)
}
#[cfg(not(feature = "ludicrous_mode"))]
CH_HASH[ch as usize]
} as usize;
}
}
hash += {
#[cfg(feature = "ludicrous_mode")]
unsafe {
*CH_HASH.get_unchecked(ch as usize)
}
#[cfg(not(feature = "ludicrous_mode"))]
CH_HASH[ch as usize]
} as usize;
if hash <= 544 {
let ch_map = {
#[cfg(feature = "ludicrous_mode")]
unsafe {
*CH_MAP.get_unchecked(hash)
}
#[cfg(not(feature = "ludicrous_mode"))]
CH_MAP[hash]
};
if l_charset[..charset.len()].eq(ch_map) {
return Some({
#[cfg(feature = "ludicrous_mode")]
unsafe {
*FNC_MAP.get_unchecked(hash)
}
#[cfg(not(feature = "ludicrous_mode"))]
FNC_MAP[hash]
});
}
}
}
None
}
pub fn no_op(_bytes: &[u8]) -> String {
String::new()
}
// Perfect hashing table for charset names
static CH_HASH: &[u16] = &[
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 50, 0, 80, 55, 15, 25, 40, 100, 5, 35, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 0, 545,
135, 10, 0, 5, 15, 35, 10, 65, 30, 0, 5, 0, 230, 0, 0, 70, 545, 55, 5, 0, 175, 545, 55, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, 545,
545, 545,
];
static CH_MAP: &[&[u8]; 545] = &[
b"",
b"",
b"l1",
b"",
b"",
b"",
b"latin1",
b"l8",
b"",
b"",
b"",
b"latin8",
b"",
b"",
b"",
b"",
b"",
b"l4",
b"",
b"",
b"csgbk",
b"latin4",
b"",
b"gbk",
b"",
b"",
b"",
b"l5",
b"",
b"",
b"",
b"latin5",
b"",
b"",
b"",
b"greek",
b"greek8",
b"",
b"",
b"",
b"",
b"csbig5",
b"l6",
b"",
b"",
b"cp819",
b"latin6",
b"",
b"",
b"big5",
b"cp866",
b"",
b"",
b"",
b"",
b"csshiftjis",
b"",
b"l3",
b"",
b"",
b"cp850",
b"latin3",
b"",
b"",
b"",
b"iso_ir_148",
b"",
b"",
b"",
b"",
b"iso_celtic",
b"",
b"",
b"",
b"",
b"",
b"euc_kr",
b"latin_9",
b"",
b"",
b"cp936",
b"",
b"l2",
b"",
b"shift_jis",
b"iso_ir_144",
b"latin2",
b"",
b"866",
b"",
b"iso_ir_101",
b"euc_jp",
b"",
b"cyrillic",
b"",
b"",
b"koi8_r",
b"",
b"",
b"",
b"iso_8859_1",
b"iso_8859_11",
b"",
b"l10",
b"",
b"iso_ir_138",
b"iso_8859_16:2001",
b"latin10",
b"850",
b"",
b"iso_8859_8",
b"iso_8859_14:1998",
b"tis_620",
b"elot_928",
b"",
b"iso_8859_8:1988",
b"iso_8859_14",
b"gb18030",
b"",
b"",
b"",
b"csiso885914",
b"cskoi8r",
b"",
b"",
b"iso_8859_4:1988",
b"iso_8859_15",
b"",
b"cswindows1251",
b"",
b"iso_8859_4",
b"csiso885915",
b"cseuckr",
b"cswindows1258",
b"",
b"iso_8859_5:1988",
b"hebrew",
b"",
b"",
b"",
b"iso_ir_110",
b"iso_8859_16",
b"",
b"cswindows1254",
b"ks_c_5601_1989",
b"iso_ir_199",
b"csiso885916",
b"cswindows874",
b"",
b"",
b"iso_8859_5",
b"iso_8859_10",
b"windows_1251",
b"cswindows1255",
b"",
b"",
b"iso_8859_13",
b"windows_1258",
b"csibm866",
b"",
b"iso_ir_109",
b"csiso885913",
b"",
b"",
b"",
b"iso_8859_3:1988",
b"",
b"windows_1254",
b"cswindows1256",
b"",
b"iso_8859_9",
b"",
b"",
b"",
b"",
b"iso_8859_9:1989",
b"gb2312",
b"windows_1255",
b"cswindows1250",
b"",
b"iso_8859_6",
b"",
b"",
b"cswindows1253",
b"",
b"",
b"iso_8859_10:1992",
b"",
b"cstis620",
b"",
b"iso_ir_100",
b"windows_874",
b"windows_1256",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"iso_ir_126",
b"windows_936",
b"windows_1250",
b"",
b"",
b"iso_8859_1:1987",
b"csisolatin1",
b"windows_1253",
b"cswindows1252",
b"ks_c_5601_1987",
b"iso_8859_3",
b"csisolatinarabic",
b"",
b"csisolatincyrillic",
b"",
b"csisolatingreek",
b"koi8_u",
b"",
b"",
b"",
b"",
b"csisolatin4",
b"",
b"",
b"csgb18030",
b"",
b"",
b"",
b"cswindows1257",
b"",
b"",
b"csisolatin5",
b"windows_1252",
b"mac",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"iso_8859_6:1987",
b"csisolatin6",
b"",
b"utf_16le",
b"",
b"",
b"",
b"windows_1257",
b"",
b"csutf16le",
b"",
b"utf_16",
b"",
b"utf_16be",
b"",
b"iso_8859_2",
b"csisolatin3",
b"csutf16",
b"ecma_118",
b"csutf16be",
b"iso_ir_157",
b"csisolatinhebrew",
b"",
b"",
b"",
b"extended_unix_code_packed_format_for_japanese",
b"iso_2022_jp",
b"",
b"",
b"",
b"",
b"arabic",
b"",
b"",
b"",
b"iso_ir_226",
b"csutf7",
b"",
b"ecma_114",
b"",
b"iso_8859_2:1987",
b"csisolatin2",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"ms_kanji",
b"",
b"iso_8859_7",
b"ibm819",
b"",
b"",
b"",
b"iso_8859_7:1987",
b"ibm866",
b"",
b"",
b"",
b"ms936",
b"csmacintosh",
b"",
b"",
b"",
b"utf_7",
b"ibm850",
b"",
b"",
b"",
b"iso_ir_127",
b"csiso2022jp",
b"",
b"",
b"cseucpkdfmtjapanese",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"cskoi8u",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"macintosh",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"asmo_708",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"cspc850multilingual",
];
static FNC_MAP: &[for<'x> fn(&'x [u8]) -> String; 545] = &[
no_op,
no_op,
decoder_iso_8859_1,
no_op,
no_op,
no_op,
decoder_iso_8859_1,
decoder_iso_8859_14,
no_op,
no_op,
no_op,
decoder_iso_8859_14,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_4,
no_op,
no_op,
decoder_gbk,
decoder_iso_8859_4,
no_op,
decoder_gbk,
no_op,
no_op,
no_op,
decoder_iso_8859_9,
no_op,
no_op,
no_op,
decoder_iso_8859_9,
no_op,
no_op,
no_op,
decoder_iso_8859_7,
decoder_iso_8859_7,
no_op,
no_op,
no_op,
no_op,
decoder_big5,
decoder_iso_8859_10,
no_op,
no_op,
decoder_iso_8859_1,
decoder_iso_8859_10,
no_op,
no_op,
decoder_big5,
decoder_ibm866,
no_op,
no_op,
no_op,
no_op,
decoder_shift_jis,
no_op,
decoder_iso_8859_3,
no_op,
no_op,
decoder_ibm_850,
decoder_iso_8859_3,
no_op,
no_op,
no_op,
decoder_iso_8859_9,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_14,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_euc_kr,
decoder_iso_8859_15,
no_op,
no_op,
decoder_gbk,
no_op,
decoder_iso_8859_2,
no_op,
decoder_shift_jis,
decoder_iso_8859_5,
decoder_iso_8859_2,
no_op,
decoder_ibm866,
no_op,
decoder_iso_8859_2,
decoder_euc_jp,
no_op,
decoder_iso_8859_5,
no_op,
no_op,
decoder_koi8_r,
no_op,
no_op,
no_op,
decoder_iso_8859_1,
decoder_tis_620,
no_op,
decoder_iso_8859_16,
no_op,
decoder_iso_8859_8,
decoder_iso_8859_16,
decoder_iso_8859_16,
decoder_ibm_850,
no_op,
decoder_iso_8859_8,
decoder_iso_8859_14,
decoder_tis_620,
decoder_iso_8859_7,
no_op,
decoder_iso_8859_8,
decoder_iso_8859_14,
decoder_gb18030,
no_op,
no_op,
no_op,
decoder_iso_8859_14,
decoder_koi8_r,
no_op,
no_op,
decoder_iso_8859_4,
decoder_iso_8859_15,
no_op,
decoder_cp1251,
no_op,
decoder_iso_8859_4,
decoder_iso_8859_15,
decoder_euc_kr,
decoder_cp1258,
no_op,
decoder_iso_8859_5,
decoder_iso_8859_8,
no_op,
no_op,
no_op,
decoder_iso_8859_4,
decoder_iso_8859_16,
no_op,
decoder_cp1254,
decoder_euc_kr,
decoder_iso_8859_14,
decoder_iso_8859_16,
decoder_windows874,
no_op,
no_op,
decoder_iso_8859_5,
decoder_iso_8859_10,
decoder_cp1251,
decoder_cp1255,
no_op,
no_op,
decoder_iso_8859_13,
decoder_cp1258,
decoder_ibm866,
no_op,
decoder_iso_8859_3,
decoder_iso_8859_13,
no_op,
no_op,
no_op,
decoder_iso_8859_3,
no_op,
decoder_cp1254,
decoder_cp1256,
no_op,
decoder_iso_8859_9,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_9,
decoder_gb18030,
decoder_cp1255,
decoder_cp1250,
no_op,
decoder_iso_8859_6,
no_op,
no_op,
decoder_cp1253,
no_op,
no_op,
decoder_iso_8859_10,
no_op,
decoder_tis_620,
no_op,
decoder_iso_8859_1,
decoder_windows874,
decoder_cp1256,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_7,
decoder_gbk,
decoder_cp1250,
no_op,
no_op,
decoder_iso_8859_1,
decoder_iso_8859_1,
decoder_cp1253,
decoder_cp1252,
decoder_euc_kr,
decoder_iso_8859_3,
decoder_iso_8859_6,
no_op,
decoder_iso_8859_5,
no_op,
decoder_iso_8859_7,
decoder_koi8_u,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_4,
no_op,
no_op,
decoder_gb18030,
no_op,
no_op,
no_op,
decoder_cp1257,
no_op,
no_op,
decoder_iso_8859_9,
decoder_cp1252,
decoder_macintosh,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_6,
decoder_iso_8859_10,
no_op,
decoder_utf16_le,
no_op,
no_op,
no_op,
decoder_cp1257,
no_op,
decoder_utf16_le,
no_op,
decoder_utf16,
no_op,
decoder_utf16_be,
no_op,
decoder_iso_8859_2,
decoder_iso_8859_3,
decoder_utf16,
decoder_iso_8859_7,
decoder_utf16_be,
decoder_iso_8859_10,
decoder_iso_8859_8,
no_op,
no_op,
no_op,
decoder_euc_jp,
decoder_iso2022_jp,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_6,
no_op,
no_op,
no_op,
decoder_iso_8859_16,
decoder_utf7,
no_op,
decoder_iso_8859_6,
no_op,
decoder_iso_8859_2,
decoder_iso_8859_2,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_shift_jis,
no_op,
decoder_iso_8859_7,
decoder_iso_8859_1,
no_op,
no_op,
no_op,
decoder_iso_8859_7,
decoder_ibm866,
no_op,
no_op,
no_op,
decoder_gbk,
decoder_macintosh,
no_op,
no_op,
no_op,
decoder_utf7,
decoder_ibm_850,
no_op,
no_op,
no_op,
decoder_iso_8859_6,
decoder_iso2022_jp,
no_op,
no_op,
decoder_euc_jp,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_koi8_u,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_macintosh,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_iso_8859_6,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
no_op,
decoder_ibm_850,
];
#[cfg(test)]
mod tests {
use super::{charset_decoder, CH_MAP};
#[test]
fn decoder_charset() {
for input in CH_MAP {
if !input.is_empty() {
assert!(
charset_decoder(input).is_some(),
"Failed for {}",
std::str::from_utf8(input).unwrap()
);
}
}
}
}