2 *******************************************************************************
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
9 package com.ibm.icu.text;
12 * This class matches UTF-16 and UTF-32, both big- and little-endian. The
13 * BOM will be used if it is present.
15 abstract class CharsetRecog_Unicode extends CharsetRecognizer {
18 * @see com.ibm.icu.text.CharsetRecognizer#getName()
20 abstract String getName();
23 * @see com.ibm.icu.text.CharsetRecognizer#match(com.ibm.icu.text.CharsetDetector)
25 abstract int match(CharsetDetector det);
27 static class CharsetRecog_UTF_16_BE extends CharsetRecog_Unicode
34 int match(CharsetDetector det)
36 byte[] input = det.fRawInput;
38 if (input.length>=2 && ((input[0] & 0xFF) == 0xFE && (input[1] & 0xFF) == 0xFF)) {
42 // TODO: Do some statistics to check for unsigned UTF-16BE
47 static class CharsetRecog_UTF_16_LE extends CharsetRecog_Unicode
54 int match(CharsetDetector det)
56 byte[] input = det.fRawInput;
58 if (input.length >= 2 && ((input[0] & 0xFF) == 0xFF && (input[1] & 0xFF) == 0xFE))
60 // An LE BOM is present.
61 if (input.length>=4 && input[2] == 0x00 && input[3] == 0x00) {
62 // It is probably UTF-32 LE, not UTF-16
68 // TODO: Do some statistics to check for unsigned UTF-16LE
73 static abstract class CharsetRecog_UTF_32 extends CharsetRecog_Unicode
75 abstract int getChar(byte[] input, int index);
77 abstract String getName();
79 int match(CharsetDetector det)
81 byte[] input = det.fRawInput;
82 int limit = (det.fRawLength / 4) * 4;
85 boolean hasBOM = false;
91 if (getChar(input, 0) == 0x0000FEFF) {
95 for(int i = 0; i < limit; i += 4) {
96 int ch = getChar(input, i);
98 if (ch < 0 || ch >= 0x10FFFF || (ch >= 0xD800 && ch <= 0xDFFF)) {
106 // Cook up some sort of confidence score, based on presence of a BOM
107 // and the existence of valid and/or invalid multi-byte sequences.
108 if (hasBOM && numInvalid==0) {
110 } else if (hasBOM && numValid > numInvalid*10) {
112 } else if (numValid > 3 && numInvalid == 0) {
114 } else if (numValid > 0 && numInvalid == 0) {
116 } else if (numValid > numInvalid*10) {
117 // Probably corrupt UTF-32BE data. Valid sequences aren't likely by chance.
125 static class CharsetRecog_UTF_32_BE extends CharsetRecog_UTF_32
127 int getChar(byte[] input, int index)
129 return (input[index + 0] & 0xFF) << 24 | (input[index + 1] & 0xFF) << 16 |
130 (input[index + 2] & 0xFF) << 8 | (input[index + 3] & 0xFF);
140 static class CharsetRecog_UTF_32_LE extends CharsetRecog_UTF_32
142 int getChar(byte[] input, int index)
144 return (input[index + 3] & 0xFF) << 24 | (input[index + 2] & 0xFF) << 16 |
145 (input[index + 1] & 0xFF) << 8 | (input[index + 0] & 0xFF);