Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/nio/cs/SingleByte.java
41159 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
public static final class Decoder extends CharsetDecoder
53
implements ArrayDecoder {
54
55
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
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
while (len-- > 0) {
220
char c = sa[sp];
221
int b = encode(c);
222
if (b == UNMAPPABLE_ENCODING) {
223
if (Character.isSurrogate(c)) {
224
if (sgp == null)
225
sgp = new Surrogate.Parser();
226
if (sgp.parse(c, sa, sp, sl) < 0) {
227
return withResult(sgp.error(), src, sp, dst, dp);
228
}
229
return withResult(sgp.unmappableResult(), src, sp, dst, dp);
230
}
231
return withResult(CoderResult.unmappableForLength(1),
232
src, sp, dst, dp);
233
}
234
da[dp++] = (byte)b;
235
sp++;
236
}
237
return withResult(sp < sl ? CoderResult.OVERFLOW : CoderResult.UNDERFLOW,
238
src, sp, dst, dp);
239
}
240
241
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
242
int mark = src.position();
243
try {
244
while (src.hasRemaining()) {
245
char c = src.get();
246
int b = encode(c);
247
if (b == UNMAPPABLE_ENCODING) {
248
if (Character.isSurrogate(c)) {
249
if (sgp == null)
250
sgp = new Surrogate.Parser();
251
if (sgp.parse(c, src) < 0)
252
return sgp.error();
253
return sgp.unmappableResult();
254
}
255
return CoderResult.unmappableForLength(1);
256
}
257
if (!dst.hasRemaining())
258
return CoderResult.OVERFLOW;
259
dst.put((byte)b);
260
mark++;
261
}
262
return CoderResult.UNDERFLOW;
263
} finally {
264
src.position(mark);
265
}
266
}
267
268
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
269
if (src.hasArray() && dst.hasArray())
270
return encodeArrayLoop(src, dst);
271
else
272
return encodeBufferLoop(src, dst);
273
}
274
275
public final int encode(char ch) {
276
char index = c2bIndex[ch >> 8];
277
if (index == UNMAPPABLE_ENCODING)
278
return UNMAPPABLE_ENCODING;
279
return c2b[index + (ch & 0xff)];
280
}
281
282
private byte repl = (byte)'?';
283
protected void implReplaceWith(byte[] newReplacement) {
284
repl = newReplacement[0];
285
}
286
287
public int encode(char[] src, int sp, int len, byte[] dst) {
288
int dp = 0;
289
int sl = sp + Math.min(len, dst.length);
290
while (sp < sl) {
291
char c = src[sp++];
292
int b = encode(c);
293
if (b != UNMAPPABLE_ENCODING) {
294
dst[dp++] = (byte)b;
295
continue;
296
}
297
if (Character.isHighSurrogate(c) && sp < sl &&
298
Character.isLowSurrogate(src[sp])) {
299
if (len > dst.length) {
300
sl++;
301
len--;
302
}
303
sp++;
304
}
305
dst[dp++] = repl;
306
}
307
return dp;
308
}
309
310
@Override
311
public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
312
int dp = 0;
313
int sl = sp + Math.min(len, dst.length);
314
while (sp < sl) {
315
char c = (char)(src[sp++] & 0xff);
316
int b = encode(c);
317
if (b == UNMAPPABLE_ENCODING) {
318
dst[dp++] = repl;
319
} else {
320
dst[dp++] = (byte)b;
321
}
322
}
323
return dp;
324
}
325
326
@Override
327
public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
328
int dp = 0;
329
int sl = sp + Math.min(len, dst.length);
330
while (sp < sl) {
331
char c = StringUTF16.getChar(src, sp++);
332
int b = encode(c);
333
if (b != UNMAPPABLE_ENCODING) {
334
dst[dp++] = (byte)b;
335
continue;
336
}
337
if (Character.isHighSurrogate(c) && sp < sl &&
338
Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
339
if (len > dst.length) {
340
sl++;
341
len--;
342
}
343
sp++;
344
}
345
dst[dp++] = repl;
346
}
347
return dp;
348
}
349
350
@Override
351
public boolean isASCIICompatible() {
352
return isASCIICompatible;
353
}
354
}
355
356
// init the c2b and c2bIndex tables from b2c.
357
public static void initC2B(char[] b2c, char[] c2bNR,
358
char[] c2b, char[] c2bIndex) {
359
for (int i = 0; i < c2bIndex.length; i++)
360
c2bIndex[i] = UNMAPPABLE_ENCODING;
361
for (int i = 0; i < c2b.length; i++)
362
c2b[i] = UNMAPPABLE_ENCODING;
363
int off = 0;
364
for (int i = 0; i < b2c.length; i++) {
365
char c = b2c[i];
366
if (c == UNMAPPABLE_DECODING)
367
continue;
368
int index = (c >> 8);
369
if (c2bIndex[index] == UNMAPPABLE_ENCODING) {
370
c2bIndex[index] = (char)off;
371
off += 0x100;
372
}
373
index = c2bIndex[index] + (c & 0xff);
374
c2b[index] = (char)((i>=0x80)?(i-0x80):(i+0x80));
375
}
376
if (c2bNR != null) {
377
// c-->b nr entries
378
int i = 0;
379
while (i < c2bNR.length) {
380
char b = c2bNR[i++];
381
char c = c2bNR[i++];
382
int index = (c >> 8);
383
if (c2bIndex[index] == UNMAPPABLE_ENCODING) {
384
c2bIndex[index] = (char)off;
385
off += 0x100;
386
}
387
index = c2bIndex[index] + (c & 0xff);
388
c2b[index] = b;
389
}
390
}
391
}
392
}
393
394