]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/CharsetRecog_Unicode.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / CharsetRecog_Unicode.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2007, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  *\r
7  */\r
8 \r
9 package com.ibm.icu.text;\r
10 \r
11 /**\r
12  * This class matches UTF-16 and UTF-32, both big- and little-endian. The\r
13  * BOM will be used if it is present.\r
14  * \r
15  * @internal\r
16  */\r
17 abstract class CharsetRecog_Unicode extends CharsetRecognizer {\r
18 \r
19     /* (non-Javadoc)\r
20      * @see com.ibm.icu.text.CharsetRecognizer#getName()\r
21      */\r
22     abstract String getName();\r
23 \r
24     /* (non-Javadoc)\r
25      * @see com.ibm.icu.text.CharsetRecognizer#match(com.ibm.icu.text.CharsetDetector)\r
26      */\r
27     abstract int match(CharsetDetector det);\r
28     \r
29     static class CharsetRecog_UTF_16_BE extends CharsetRecog_Unicode\r
30     {\r
31         String getName()\r
32         {\r
33             return "UTF-16BE";\r
34         }\r
35         \r
36         int match(CharsetDetector det)\r
37         {\r
38             byte[] input = det.fRawInput;\r
39             \r
40             if (input.length>=2 && ((input[0] & 0xFF) == 0xFE && (input[1] & 0xFF) == 0xFF)) {\r
41                 return 100;\r
42             }\r
43             \r
44             // TODO: Do some statistics to check for unsigned UTF-16BE\r
45             return 0;\r
46         }\r
47     }\r
48     \r
49     static class CharsetRecog_UTF_16_LE extends CharsetRecog_Unicode\r
50     {\r
51         String getName()\r
52         {\r
53             return "UTF-16LE";\r
54         }\r
55         \r
56         int match(CharsetDetector det)\r
57         {\r
58             byte[] input = det.fRawInput;\r
59             \r
60             if (input.length >= 2 && ((input[0] & 0xFF) == 0xFF && (input[1] & 0xFF) == 0xFE))\r
61             {\r
62                // An LE BOM is present.\r
63                if (input.length>=4 && input[2] == 0x00 && input[3] == 0x00) {\r
64                    // It is probably UTF-32 LE, not UTF-16\r
65                    return 0;\r
66                }\r
67                return 100;\r
68             }        \r
69             \r
70             // TODO: Do some statistics to check for unsigned UTF-16LE\r
71             return 0;\r
72         }\r
73     }\r
74     \r
75     static abstract class CharsetRecog_UTF_32 extends CharsetRecog_Unicode\r
76     {\r
77         abstract int getChar(byte[] input, int index);\r
78         \r
79         abstract String getName();\r
80         \r
81         int match(CharsetDetector det)\r
82         {\r
83             byte[] input   = det.fRawInput;\r
84             int limit      = (det.fRawLength / 4) * 4;\r
85             int numValid   = 0;\r
86             int numInvalid = 0;\r
87             boolean hasBOM = false;\r
88             int confidence = 0;\r
89             \r
90             if (limit==0) {\r
91                 return 0;\r
92             }\r
93             if (getChar(input, 0) == 0x0000FEFF) {\r
94                 hasBOM = true;\r
95             }\r
96             \r
97             for(int i = 0; i < limit; i += 4) {\r
98                 int ch = getChar(input, i);\r
99                 \r
100                 if (ch < 0 || ch >= 0x10FFFF || (ch >= 0xD800 && ch <= 0xDFFF)) {\r
101                     numInvalid += 1;\r
102                 } else {\r
103                     numValid += 1;\r
104                 }\r
105             }\r
106             \r
107             \r
108             // Cook up some sort of confidence score, based on presence of a BOM\r
109             //    and the existence of valid and/or invalid multi-byte sequences.\r
110             if (hasBOM && numInvalid==0) {\r
111                 confidence = 100;\r
112             } else if (hasBOM && numValid > numInvalid*10) {\r
113                 confidence = 80;\r
114             } else if (numValid > 3 && numInvalid == 0) {\r
115                 confidence = 100;            \r
116             } else if (numValid > 0 && numInvalid == 0) {\r
117                 confidence = 80;\r
118             } else if (numValid > numInvalid*10) {\r
119                 // Probably corrupt UTF-32BE data.  Valid sequences aren't likely by chance.\r
120                 confidence = 25;\r
121             }\r
122             \r
123             return confidence;\r
124         }\r
125     }\r
126     \r
127     static class CharsetRecog_UTF_32_BE extends CharsetRecog_UTF_32\r
128     {\r
129         int getChar(byte[] input, int index)\r
130         {\r
131             return (input[index + 0] & 0xFF) << 24 | (input[index + 1] & 0xFF) << 16 |\r
132                    (input[index + 2] & 0xFF) <<  8 | (input[index + 3] & 0xFF);\r
133         }\r
134         \r
135         String getName()\r
136         {\r
137             return "UTF-32BE";\r
138         }\r
139     }\r
140 \r
141     \r
142     static class CharsetRecog_UTF_32_LE extends CharsetRecog_UTF_32\r
143     {\r
144         int getChar(byte[] input, int index)\r
145         {\r
146             return (input[index + 3] & 0xFF) << 24 | (input[index + 2] & 0xFF) << 16 |\r
147                    (input[index + 1] & 0xFF) <<  8 | (input[index + 0] & 0xFF);\r
148         }\r
149         \r
150         String getName()\r
151         {\r
152             return "UTF-32LE";\r
153         }\r
154     }\r
155 }\r