| 36 | import java.util.Locale; |
| 37 | |
| 38 | public class CharsetHelper { |
| 39 | private static final int MAX_SAMPLE_SIZE = 8192; |
| 40 | private static String CHINESE = new Locale("zh").getLanguage(); |
| 41 | private static final List<String> COMMON = Collections.unmodifiableList(Arrays.asList( |
| 42 | "US-ASCII", |
| 43 | "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-7", |
| 44 | "windows-1250", "windows-1251", "windows-1252", "windows-1255", "windows-1256", "windows-1257", |
| 45 | "UTF-8" |
| 46 | )); |
| 47 | private static final List<String> LESS_COMMON = Collections.unmodifiableList(Arrays.asList( |
| 48 | "GBK", "GB2312", "HZ-GB-2312", |
| 49 | "EUC", "EUC-KR", |
| 50 | "Big5", "BIG5-CP950", |
| 51 | "ISO-2022-JP", "Shift_JIS", |
| 52 | "cp852", |
| 53 | "KOI8-R", |
| 54 | "x-binaryenc" |
| 55 | )); |
| 56 | private static final int MIN_W1252 = 10; |
| 57 | private static final Pair<byte[], byte[]>[] sUtf8W1252 = new Pair[128]; |
| 58 | |
| 59 | static { |
| 60 | System.loadLibrary("fairemail"); |
| 61 | |
| 62 | // https://www.i18nqa.com/debug/utf8-debug.html |
| 63 | Charset w1252 = Charset.forName("windows-1252"); |
| 64 | for (int c = 128; c < 256; c++) { |
| 65 | String y = new String(new byte[]{(byte) c}, w1252); |
| 66 | String x = new String(y.getBytes(), w1252); |
| 67 | sUtf8W1252[c - 128] = new Pair<>(x.getBytes(), y.getBytes()); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | private static native DetectResult jni_detect_charset(byte[] octets, String ref, String lang); |
| 72 | |
| 73 | static boolean isUTF8(String text) { |
| 74 | // Get extended ASCII characters |
| 75 | byte[] octets = text.getBytes(StandardCharsets.ISO_8859_1); |
| 76 | return isUTF8(octets); |
| 77 | } |
| 78 | |
| 79 | static boolean isUTF8(byte[] octets) { |
| 80 | return isValid(octets, StandardCharsets.UTF_8); |
| 81 | } |
| 82 | |
| 83 | static boolean isUTF16(byte[] octets) { |
| 84 | return isValid(octets, StandardCharsets.UTF_16); |
| 85 | } |
| 86 | |
| 87 | static Boolean isValid(byte[] octets, String charset) { |
| 88 | return isValid(octets, Charset.forName(charset)); |
| 89 | } |
| 90 | |
| 91 | static boolean isValid(byte[] octets, Charset charset) { |
| 92 | CharsetDecoder decoder = charset.newDecoder() |
| 93 | .onMalformedInput(CodingErrorAction.REPORT) |
| 94 | .onUnmappableCharacter(CodingErrorAction.REPORT); |
| 95 | try { |
nothing calls this directly
no test coverage detected