Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/nio/cs/ext/HKSCS.java
38919 views
1
/*
2
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.nio.cs.ext;
27
28
import java.nio.ByteBuffer;
29
import java.nio.CharBuffer;
30
import java.nio.charset.Charset;
31
import java.nio.charset.CharsetDecoder;
32
import java.nio.charset.CharsetEncoder;
33
import java.nio.charset.CoderResult;
34
import java.util.Arrays;
35
import sun.nio.cs.Surrogate;
36
import static sun.nio.cs.CharsetMapping.*;
37
38
public class HKSCS {
39
40
public static class Decoder extends DoubleByte.Decoder {
41
static int b2Min = 0x40;
42
static int b2Max = 0xfe;
43
44
private char[][] b2cBmp;
45
private char[][] b2cSupp;
46
private DoubleByte.Decoder big5Dec;
47
48
protected Decoder(Charset cs,
49
DoubleByte.Decoder big5Dec,
50
char[][] b2cBmp, char[][] b2cSupp)
51
{
52
// super(cs, 0.5f, 1.0f);
53
// need to extends DoubleByte.Decoder so the
54
// sun.io can use it. this implementation
55
super(cs, 0.5f, 1.0f, null, null, 0, 0);
56
this.big5Dec = big5Dec;
57
this.b2cBmp = b2cBmp;
58
this.b2cSupp = b2cSupp;
59
}
60
61
public char decodeSingle(int b) {
62
return big5Dec.decodeSingle(b);
63
}
64
65
public char decodeBig5(int b1, int b2) {
66
return big5Dec.decodeDouble(b1, b2);
67
}
68
69
public char decodeDouble(int b1, int b2) {
70
return b2cBmp[b1][b2 - b2Min];
71
}
72
73
public char decodeDoubleEx(int b1, int b2) {
74
/* if the b2cSupp is null, the subclass need
75
to override the methold
76
if (b2cSupp == null)
77
return UNMAPPABLE_DECODING;
78
*/
79
return b2cSupp[b1][b2 - b2Min];
80
}
81
82
protected CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
83
byte[] sa = src.array();
84
int sp = src.arrayOffset() + src.position();
85
int sl = src.arrayOffset() + src.limit();
86
87
char[] da = dst.array();
88
int dp = dst.arrayOffset() + dst.position();
89
int dl = dst.arrayOffset() + dst.limit();
90
91
try {
92
while (sp < sl) {
93
int b1 = sa[sp] & 0xff;
94
char c = decodeSingle(b1);
95
int inSize = 1, outSize = 1;
96
char[] cc = null;
97
if (c == UNMAPPABLE_DECODING) {
98
if (sl - sp < 2)
99
return CoderResult.UNDERFLOW;
100
int b2 = sa[sp + 1] & 0xff;
101
inSize++;
102
if (b2 < b2Min || b2 > b2Max)
103
return CoderResult.unmappableForLength(2);
104
c = decodeDouble(b1, b2); //bmp
105
if (c == UNMAPPABLE_DECODING) {
106
c = decodeDoubleEx(b1, b2); //supp
107
if (c == UNMAPPABLE_DECODING) {
108
c = decodeBig5(b1, b2); //big5
109
if (c == UNMAPPABLE_DECODING)
110
return CoderResult.unmappableForLength(2);
111
} else {
112
// supplementary character in u+2xxxx area
113
outSize = 2;
114
}
115
}
116
}
117
if (dl - dp < outSize)
118
return CoderResult.OVERFLOW;
119
if (outSize == 2) {
120
// supplementary characters
121
da[dp++] = Surrogate.high(0x20000 + c);
122
da[dp++] = Surrogate.low(0x20000 + c);
123
} else {
124
da[dp++] = c;
125
}
126
sp += inSize;
127
}
128
return CoderResult.UNDERFLOW;
129
} finally {
130
src.position(sp - src.arrayOffset());
131
dst.position(dp - dst.arrayOffset());
132
}
133
}
134
135
protected CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
136
int mark = src.position();
137
try {
138
while (src.hasRemaining()) {
139
char[] cc = null;
140
int b1 = src.get() & 0xff;
141
int inSize = 1, outSize = 1;
142
char c = decodeSingle(b1);
143
if (c == UNMAPPABLE_DECODING) {
144
if (src.remaining() < 1)
145
return CoderResult.UNDERFLOW;
146
int b2 = src.get() & 0xff;
147
inSize++;
148
if (b2 < b2Min || b2 > b2Max)
149
return CoderResult.unmappableForLength(2);
150
c = decodeDouble(b1, b2); //bmp
151
if (c == UNMAPPABLE_DECODING) {
152
c = decodeDoubleEx(b1, b2); //supp
153
if (c == UNMAPPABLE_DECODING) {
154
c = decodeBig5(b1, b2); //big5
155
if (c == UNMAPPABLE_DECODING)
156
return CoderResult.unmappableForLength(2);
157
} else {
158
outSize = 2;
159
}
160
}
161
}
162
if (dst.remaining() < outSize)
163
return CoderResult.OVERFLOW;
164
if (outSize == 2) {
165
dst.put(Surrogate.high(0x20000 + c));
166
dst.put(Surrogate.low(0x20000 + c));
167
} else {
168
dst.put(c);
169
}
170
mark += inSize;
171
}
172
return CoderResult.UNDERFLOW;
173
} finally {
174
src.position(mark);
175
}
176
}
177
178
public int decode(byte[] src, int sp, int len, char[] dst) {
179
int dp = 0;
180
int sl = sp + len;
181
char repl = replacement().charAt(0);
182
while (sp < sl) {
183
int b1 = src[sp++] & 0xff;
184
char c = decodeSingle(b1);
185
if (c == UNMAPPABLE_DECODING) {
186
if (sl == sp) {
187
c = repl;
188
} else {
189
int b2 = src[sp++] & 0xff;
190
if (b2 < b2Min || b2 > b2Max) {
191
c = repl;
192
} else if ((c = decodeDouble(b1, b2)) == UNMAPPABLE_DECODING) {
193
c = decodeDoubleEx(b1, b2); //supp
194
if (c == UNMAPPABLE_DECODING) {
195
c = decodeBig5(b1, b2); //big5
196
if (c == UNMAPPABLE_DECODING)
197
c = repl;
198
} else {
199
// supplementary character in u+2xxxx area
200
dst[dp++] = Surrogate.high(0x20000 + c);
201
dst[dp++] = Surrogate.low(0x20000 + c);
202
continue;
203
}
204
}
205
}
206
}
207
dst[dp++] = c;
208
}
209
return dp;
210
}
211
212
public CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
213
if (src.hasArray() && dst.hasArray())
214
return decodeArrayLoop(src, dst);
215
else
216
return decodeBufferLoop(src, dst);
217
}
218
219
static void initb2c(char[][]b2c, String[] b2cStr)
220
{
221
for (int i = 0; i < b2cStr.length; i++) {
222
if (b2cStr[i] == null)
223
b2c[i] = DoubleByte.B2C_UNMAPPABLE;
224
else
225
b2c[i] = b2cStr[i].toCharArray();
226
}
227
}
228
229
}
230
231
public static class Encoder extends DoubleByte.Encoder {
232
private DoubleByte.Encoder big5Enc;
233
private char[][] c2bBmp;
234
private char[][] c2bSupp;
235
236
protected Encoder(Charset cs,
237
DoubleByte.Encoder big5Enc,
238
char[][] c2bBmp,
239
char[][] c2bSupp)
240
{
241
super(cs, null, null);
242
this.big5Enc = big5Enc;
243
this.c2bBmp = c2bBmp;
244
this.c2bSupp = c2bSupp;
245
}
246
247
public int encodeBig5(char ch) {
248
return big5Enc.encodeChar(ch);
249
}
250
251
public int encodeChar(char ch) {
252
int bb = c2bBmp[ch >> 8][ch & 0xff];
253
if (bb == UNMAPPABLE_ENCODING)
254
return encodeBig5(ch);
255
return bb;
256
}
257
258
public int encodeSupp(int cp) {
259
if ((cp & 0xf0000) != 0x20000)
260
return UNMAPPABLE_ENCODING;
261
return c2bSupp[(cp >> 8) & 0xff][cp & 0xff];
262
}
263
264
public boolean canEncode(char c) {
265
return encodeChar(c) != UNMAPPABLE_ENCODING;
266
}
267
268
protected CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
269
char[] sa = src.array();
270
int sp = src.arrayOffset() + src.position();
271
int sl = src.arrayOffset() + src.limit();
272
273
byte[] da = dst.array();
274
int dp = dst.arrayOffset() + dst.position();
275
int dl = dst.arrayOffset() + dst.limit();
276
277
try {
278
while (sp < sl) {
279
char c = sa[sp];
280
int inSize = 1;
281
int bb = encodeChar(c);
282
if (bb == UNMAPPABLE_ENCODING) {
283
if (Character.isSurrogate(c)) {
284
int cp;
285
if ((cp = sgp().parse(c, sa, sp, sl)) < 0)
286
return sgp.error();
287
bb = encodeSupp(cp);
288
if (bb == UNMAPPABLE_ENCODING)
289
return CoderResult.unmappableForLength(2);
290
inSize = 2;
291
} else {
292
return CoderResult.unmappableForLength(1);
293
}
294
}
295
if (bb > MAX_SINGLEBYTE) { // DoubleByte
296
if (dl - dp < 2)
297
return CoderResult.OVERFLOW;
298
da[dp++] = (byte)(bb >> 8);
299
da[dp++] = (byte)bb;
300
} else { // SingleByte
301
if (dl - dp < 1)
302
return CoderResult.OVERFLOW;
303
da[dp++] = (byte)bb;
304
}
305
sp += inSize;
306
}
307
return CoderResult.UNDERFLOW;
308
} finally {
309
src.position(sp - src.arrayOffset());
310
dst.position(dp - dst.arrayOffset());
311
}
312
}
313
314
protected CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
315
int mark = src.position();
316
try {
317
while (src.hasRemaining()) {
318
int inSize = 1;
319
char c = src.get();
320
int bb = encodeChar(c);
321
if (bb == UNMAPPABLE_ENCODING) {
322
if (Character.isSurrogate(c)) {
323
int cp;
324
if ((cp = sgp().parse(c, src)) < 0)
325
return sgp.error();
326
bb = encodeSupp(cp);
327
if (bb == UNMAPPABLE_ENCODING)
328
return CoderResult.unmappableForLength(2);
329
inSize = 2;
330
} else {
331
return CoderResult.unmappableForLength(1);
332
}
333
}
334
if (bb > MAX_SINGLEBYTE) { // DoubleByte
335
if (dst.remaining() < 2)
336
return CoderResult.OVERFLOW;
337
dst.put((byte)(bb >> 8));
338
dst.put((byte)(bb));
339
} else {
340
if (dst.remaining() < 1)
341
return CoderResult.OVERFLOW;
342
dst.put((byte)bb);
343
}
344
mark += inSize;
345
}
346
return CoderResult.UNDERFLOW;
347
} finally {
348
src.position(mark);
349
}
350
}
351
352
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
353
if (src.hasArray() && dst.hasArray())
354
return encodeArrayLoop(src, dst);
355
else
356
return encodeBufferLoop(src, dst);
357
}
358
359
private byte[] repl = replacement();
360
protected void implReplaceWith(byte[] newReplacement) {
361
repl = newReplacement;
362
}
363
364
public int encode(char[] src, int sp, int len, byte[] dst) {
365
int dp = 0;
366
int sl = sp + len;
367
while (sp < sl) {
368
char c = src[sp++];
369
int bb = encodeChar(c);
370
if (bb == UNMAPPABLE_ENCODING) {
371
if (!Character.isHighSurrogate(c) || sp == sl ||
372
!Character.isLowSurrogate(src[sp]) ||
373
(bb = encodeSupp(Character.toCodePoint(c, src[sp++])))
374
== UNMAPPABLE_ENCODING) {
375
dst[dp++] = repl[0];
376
if (repl.length > 1)
377
dst[dp++] = repl[1];
378
continue;
379
}
380
}
381
if (bb > MAX_SINGLEBYTE) { // DoubleByte
382
dst[dp++] = (byte)(bb >> 8);
383
dst[dp++] = (byte)bb;
384
} else { // SingleByte
385
dst[dp++] = (byte)bb;
386
}
387
}
388
return dp;
389
}
390
391
392
static char[] C2B_UNMAPPABLE = new char[0x100];
393
static {
394
Arrays.fill(C2B_UNMAPPABLE, (char)UNMAPPABLE_ENCODING);
395
}
396
397
static void initc2b(char[][] c2b, String[] b2cStr, String pua) {
398
// init c2b/c2bSupp from b2cStr and supp
399
int b2Min = 0x40;
400
Arrays.fill(c2b, C2B_UNMAPPABLE);
401
for (int b1 = 0; b1 < 0x100; b1++) {
402
String s = b2cStr[b1];
403
if (s == null)
404
continue;
405
for (int i = 0; i < s.length(); i++) {
406
char c = s.charAt(i);
407
int hi = c >> 8;
408
if (c2b[hi] == C2B_UNMAPPABLE) {
409
c2b[hi] = new char[0x100];
410
Arrays.fill(c2b[hi], (char)UNMAPPABLE_ENCODING);
411
}
412
c2b[hi][c & 0xff] = (char)((b1 << 8) | (i + b2Min));
413
}
414
}
415
if (pua != null) { // add the compatibility pua entries
416
char c = '\ue000'; //first pua character
417
for (int i = 0; i < pua.length(); i++) {
418
char bb = pua.charAt(i);
419
if (bb != UNMAPPABLE_DECODING) {
420
int hi = c >> 8;
421
if (c2b[hi] == C2B_UNMAPPABLE) {
422
c2b[hi] = new char[0x100];
423
Arrays.fill(c2b[hi], (char)UNMAPPABLE_ENCODING);
424
}
425
c2b[hi][c & 0xff] = bb;
426
}
427
c++;
428
}
429
}
430
}
431
}
432
}
433
434