Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.base/share/classes/sun/nio/cs/SingleByte.java
67862 views
1
/*
2
* Copyright (c) 2008, 2021, 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;
27
28
import jdk.internal.access.JavaLangAccess;
29
import jdk.internal.access.SharedSecrets;
30
31
import java.nio.Buffer;
32
import java.nio.ByteBuffer;
33
import java.nio.CharBuffer;
34
import java.nio.charset.Charset;
35
import java.nio.charset.CharsetDecoder;
36
import java.nio.charset.CharsetEncoder;
37
import java.nio.charset.CoderResult;
38
import java.util.Arrays;
39
import static sun.nio.cs.CharsetMapping.*;
40
41
public class SingleByte
42
{
43
private static final CoderResult withResult(CoderResult cr,
44
Buffer src, int sp,
45
Buffer dst, int dp)
46
{
47
src.position(sp - src.arrayOffset());
48
dst.position(dp - dst.arrayOffset());
49
return cr;
50
}
51
52
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
53
54
public static final class Decoder extends CharsetDecoder
55
implements ArrayDecoder {
56
57
private final char[] b2c;
58
private final boolean isASCIICompatible;
59
private final boolean isLatin1Decodable;
60
61
public Decoder(Charset cs, char[] b2c) {
62
super(cs, 1.0f, 1.0f);
63
this.b2c = b2c;
64
this.isASCIICompatible = false;
65
this.isLatin1Decodable = false;
66
}
67
68
public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible) {
69
super(cs, 1.0f, 1.0f);
70
this.b2c = b2c;
71
this.isASCIICompatible = isASCIICompatible;
72
this.isLatin1Decodable = false;
73
}
74
75
public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible, boolean isLatin1Decodable) {
76
super(cs, 1.0f, 1.0f);
77
this.b2c = b2c;
78
this.isASCIICompatible = isASCIICompatible;
79
this.isLatin1Decodable = isLatin1Decodable;
80
}
81
82
private 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
CoderResult cr = CoderResult.UNDERFLOW;
92
if ((dl - dp) < (sl - sp)) {
93
sl = sp + (dl - dp);
94
cr = CoderResult.OVERFLOW;
95
}
96
97
if (isASCIICompatible) {
98
int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp));
99
sp += n;
100
dp += n;
101
}
102
while (sp < sl) {
103
char c = decode(sa[sp]);
104
if (c == UNMAPPABLE_DECODING) {
105
return withResult(CoderResult.unmappableForLength(1),
106
src, sp, dst, dp);
107
}
108
da[dp++] = c;
109
sp++;
110
}
111
return withResult(cr, src, sp, dst, dp);
112
}
113
114
private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
115
int mark = src.position();
116
try {
117
while (src.hasRemaining()) {
118
char c = decode(src.get());
119
if (c == UNMAPPABLE_DECODING)
120
return CoderResult.unmappableForLength(1);
121
if (!dst.hasRemaining())
122
return CoderResult.OVERFLOW;
123
dst.put(c);
124
mark++;
125
}
126
return CoderResult.UNDERFLOW;
127
} finally {
128
src.position(mark);
129
}
130
}
131
132
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
133
if (src.hasArray() && dst.hasArray())
134
return decodeArrayLoop(src, dst);
135
else
136
return decodeBufferLoop(src, dst);
137
}
138
139
public final char decode(int b) {
140
return b2c[b + 128];
141
}
142
143
private char repl = '\uFFFD';
144
protected void implReplaceWith(String newReplacement) {
145
repl = newReplacement.charAt(0);
146
}
147
148
@Override
149
public int decodeToLatin1(byte[] src, int sp, int len, byte[] dst) {
150
if (len > dst.length)
151
len = dst.length;
152
153
int dp = 0;
154
while (dp < len) {
155
dst[dp++] = (byte)decode(src[sp++]);
156
}
157
return dp;
158
}
159
160
@Override
161
public int decode(byte[] src, int sp, int len, char[] dst) {
162
if (len > dst.length)
163
len = dst.length;
164
int dp = 0;
165
while (dp < len) {
166
dst[dp] = decode(src[sp++]);
167
if (dst[dp] == UNMAPPABLE_DECODING) {
168
dst[dp] = repl;
169
}
170
dp++;
171
}
172
return dp;
173
}
174
175
@Override
176
public boolean isASCIICompatible() {
177
return isASCIICompatible;
178
}
179
180
@Override
181
public boolean isLatin1Decodable() {
182
return isLatin1Decodable;
183
}
184
}
185
186
public static final class Encoder extends CharsetEncoder
187
implements ArrayEncoder {
188
private Surrogate.Parser sgp;
189
private final char[] c2b;
190
private final char[] c2bIndex;
191
private final boolean isASCIICompatible;
192
193
public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) {
194
super(cs, 1.0f, 1.0f);
195
this.c2b = c2b;
196
this.c2bIndex = c2bIndex;
197
this.isASCIICompatible = isASCIICompatible;
198
}
199
200
public boolean canEncode(char c) {
201
return encode(c) != UNMAPPABLE_ENCODING;
202
}
203
204
public boolean isLegalReplacement(byte[] repl) {
205
return ((repl.length == 1 && repl[0] == (byte)'?') ||
206
super.isLegalReplacement(repl));
207
}
208
209
private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
210
char[] sa = src.array();
211
int sp = src.arrayOffset() + src.position();
212
int sl = src.arrayOffset() + src.limit();
213
214
byte[] da = dst.array();
215
int dp = dst.arrayOffset() + dst.position();
216
int dl = dst.arrayOffset() + dst.limit();
217
int len = Math.min(dl - dp, sl - sp);
218
219
if (isASCIICompatible) {
220
int n = JLA.encodeASCII(sa, sp, da, dp, len);
221
sp += n;
222
dp += n;
223
len -= n;
224
}
225
while (len-- > 0) {
226
char c = sa[sp];
227
int b = encode(c);
228
if (b == UNMAPPABLE_ENCODING) {
229
if (Character.isSurrogate(c)) {
230
if (sgp == null)
231
sgp = new Surrogate.Parser();
232
if (sgp.parse(c, sa, sp, sl) < 0) {
233
return withResult(sgp.error(), src, sp, dst, dp);
234
}
235
return withResult(sgp.unmappableResult(), src, sp, dst, dp);
236
}
237
return withResult(CoderResult.unmappableForLength(1),
238
src, sp, dst, dp);
239
}
240
da[dp++] = (byte)b;
241
sp++;
242
}
243
return withResult(sp < sl ? CoderResult.OVERFLOW : CoderResult.UNDERFLOW,
244
src, sp, dst, dp);
245
}
246
247
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
248
int mark = src.position();
249
try {
250
while (src.hasRemaining()) {
251
char c = src.get();
252
int b = encode(c);
253
if (b == UNMAPPABLE_ENCODING) {
254
if (Character.isSurrogate(c)) {
255
if (sgp == null)
256
sgp = new Surrogate.Parser();
257
if (sgp.parse(c, src) < 0)
258
return sgp.error();
259
return sgp.unmappableResult();
260
}
261
return CoderResult.unmappableForLength(1);
262
}
263
if (!dst.hasRemaining())
264
return CoderResult.OVERFLOW;
265
dst.put((byte)b);
266
mark++;
267
}
268
return CoderResult.UNDERFLOW;
269
} finally {
270
src.position(mark);
271
}
272
}
273
274
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
275
if (src.hasArray() && dst.hasArray())
276
return encodeArrayLoop(src, dst);
277
else
278
return encodeBufferLoop(src, dst);
279
}
280
281
public final int encode(char ch) {
282
char index = c2bIndex[ch >> 8];
283
if (index == UNMAPPABLE_ENCODING)
284
return UNMAPPABLE_ENCODING;
285
return c2b[index + (ch & 0xff)];
286
}
287
288
private byte repl = (byte)'?';
289
protected void implReplaceWith(byte[] newReplacement) {
290
repl = newReplacement[0];
291
}
292
293
public int encode(char[] src, int sp, int len, byte[] dst) {
294
int dp = 0;
295
int sl = sp + Math.min(len, dst.length);
296
while (sp < sl) {
297
char c = src[sp++];
298
int b = encode(c);
299
if (b != UNMAPPABLE_ENCODING) {
300
dst[dp++] = (byte)b;
301
continue;
302
}
303
if (Character.isHighSurrogate(c) && sp < sl &&
304
Character.isLowSurrogate(src[sp])) {
305
if (len > dst.length) {
306
sl++;
307
len--;
308
}
309
sp++;
310
}
311
dst[dp++] = repl;
312
}
313
return dp;
314
}
315
316
@Override
317
public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
318
int dp = 0;
319
int sl = sp + Math.min(len, dst.length);
320
while (sp < sl) {
321
char c = (char)(src[sp++] & 0xff);
322
int b = encode(c);
323
if (b == UNMAPPABLE_ENCODING) {
324
dst[dp++] = repl;
325
} else {
326
dst[dp++] = (byte)b;
327
}
328
}
329
return dp;
330
}
331
332
@Override
333
public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
334
int dp = 0;
335
int sl = sp + Math.min(len, dst.length);
336
while (sp < sl) {
337
char c = StringUTF16.getChar(src, sp++);
338
int b = encode(c);
339
if (b != UNMAPPABLE_ENCODING) {
340
dst[dp++] = (byte)b;
341
continue;
342
}
343
if (Character.isHighSurrogate(c) && sp < sl &&
344
Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
345
if (len > dst.length) {
346
sl++;
347
len--;
348
}
349
sp++;
350
}
351
dst[dp++] = repl;
352
}
353
return dp;
354
}
355
356
@Override
357
public boolean isASCIICompatible() {
358
return isASCIICompatible;
359
}
360
}
361
362
// init the c2b and c2bIndex tables from b2c.
363
public static void initC2B(char[] b2c, char[] c2bNR,
364
char[] c2b, char[] c2bIndex) {
365
for (int i = 0; i < c2bIndex.length; i++)
366
c2bIndex[i] = UNMAPPABLE_ENCODING;
367
for (int i = 0; i < c2b.length; i++)
368
c2b[i] = UNMAPPABLE_ENCODING;
369
int off = 0;
370
for (int i = 0; i < b2c.length; i++) {
371
char c = b2c[i];
372
if (c == UNMAPPABLE_DECODING)
373
continue;
374
int index = (c >> 8);
375
if (c2bIndex[index] == UNMAPPABLE_ENCODING) {
376
c2bIndex[index] = (char)off;
377
off += 0x100;
378
}
379
index = c2bIndex[index] + (c & 0xff);
380
c2b[index] = (char)((i>=0x80)?(i-0x80):(i+0x80));
381
}
382
if (c2bNR != null) {
383
// c-->b nr entries
384
int i = 0;
385
while (i < c2bNR.length) {
386
char b = c2bNR[i++];
387
char c = c2bNR[i++];
388
int index = (c >> 8);
389
if (c2bIndex[index] == UNMAPPABLE_ENCODING) {
390
c2bIndex[index] = (char)off;
391
off += 0x100;
392
}
393
index = c2bIndex[index] + (c & 0xff);
394
c2b[index] = b;
395
}
396
}
397
}
398
}
399
400