Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/nio/Buffer/BulkPutBuffer.java
41149 views
1
/*
2
* Copyright (c) 2020, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.lang.invoke.MethodHandle;
25
import java.lang.invoke.MethodHandles;
26
import java.lang.invoke.MethodType;
27
import java.nio.Buffer;
28
import java.nio.ByteBuffer;
29
import java.nio.ByteOrder;
30
import java.nio.CharBuffer;
31
import java.nio.DoubleBuffer;
32
import java.nio.FloatBuffer;
33
import java.nio.IntBuffer;
34
import java.nio.LongBuffer;
35
import java.nio.ReadOnlyBufferException;
36
import java.nio.ShortBuffer;
37
import java.util.ArrayList;
38
import java.util.Arrays;
39
import java.util.HashMap;
40
import java.util.Iterator;
41
import java.util.List;
42
import java.util.Map;
43
import java.util.Random;
44
45
import org.testng.Assert;
46
import org.testng.annotations.DataProvider;
47
import org.testng.annotations.Test;
48
49
50
/*
51
* @test
52
* @bug 8219014 8245121
53
* @summary Ensure that a bulk put of a buffer into another is correct.
54
* @compile --enable-preview -source ${jdk.version} BulkPutBuffer.java
55
* @run testng/othervm --enable-preview BulkPutBuffer
56
*/
57
public class BulkPutBuffer {
58
static final long SEED = System.nanoTime();
59
static final MyRandom RND = new MyRandom(SEED);
60
61
static final int ITERATIONS = 100;
62
static final int MAX_CAPACITY = 1024;
63
64
static class MyRandom extends Random {
65
MyRandom(long seed) {
66
super(seed);
67
}
68
69
public byte nextByte() {
70
return (byte)next(8);
71
}
72
73
public char nextChar() {
74
return (char)next(16);
75
}
76
77
public short nextShort() {
78
return (short)next(16);
79
}
80
}
81
82
enum BufferKind {
83
HEAP,
84
HEAP_VIEW,
85
DIRECT,
86
STRING;
87
}
88
89
static final Map<Class<?>,TypeAttr> typeToAttr;
90
91
static record TypeAttr(Class<?> type, int bytes, String name) {}
92
93
static {
94
typeToAttr = Map.of(
95
byte.class, new TypeAttr(ByteBuffer.class, Byte.BYTES, "Byte"),
96
char.class, new TypeAttr(CharBuffer.class, Character.BYTES, "Char"),
97
short.class, new TypeAttr(ShortBuffer.class, Short.BYTES, "Short"),
98
int.class, new TypeAttr(IntBuffer.class, Integer.BYTES, "Int"),
99
float.class, new TypeAttr(FloatBuffer.class, Float.BYTES, "Float"),
100
long.class, new TypeAttr(LongBuffer.class, Long.BYTES, "Long"),
101
double.class, new TypeAttr(DoubleBuffer.class, Double.BYTES, "Double")
102
);
103
}
104
105
static BufferKind[] getKinds(Class<?> elementType) {
106
BufferKind[] kinds;
107
if (elementType == byte.class)
108
kinds = new BufferKind[] {
109
BufferKind.DIRECT,
110
BufferKind.HEAP
111
};
112
else if (elementType == char.class)
113
kinds = BufferKind.values();
114
else
115
kinds = new BufferKind[] {
116
BufferKind.DIRECT,
117
BufferKind.HEAP,
118
BufferKind.HEAP_VIEW
119
};
120
return kinds;
121
}
122
123
static ByteOrder[] getOrders(BufferKind kind, Class<?> elementType) {
124
switch (kind) {
125
case HEAP:
126
return new ByteOrder[] { ByteOrder.nativeOrder() };
127
default:
128
if (elementType == byte.class)
129
return new ByteOrder[] { ByteOrder.nativeOrder() };
130
else
131
return new ByteOrder[] { ByteOrder.BIG_ENDIAN,
132
ByteOrder.LITTLE_ENDIAN };
133
}
134
}
135
136
public static class BufferProxy {
137
final Class<?> elementType;
138
final BufferKind kind;
139
final ByteOrder order;
140
141
// Buffer methods
142
MethodHandle alloc;
143
MethodHandle allocBB;
144
MethodHandle allocDirect;
145
MethodHandle asReadOnlyBuffer;
146
MethodHandle asTypeBuffer;
147
MethodHandle putAbs;
148
MethodHandle getAbs;
149
MethodHandle putBufAbs;
150
MethodHandle putBufRel;
151
MethodHandle equals;
152
153
// MyRandom method
154
MethodHandle nextType;
155
156
BufferProxy(Class<?> elementType, BufferKind kind, ByteOrder order) {
157
this.elementType = elementType;
158
this.kind = kind;
159
this.order = order;
160
161
Class<?> bufferType = typeToAttr.get(elementType).type;
162
163
var lookup = MethodHandles.lookup();
164
try {
165
String name = typeToAttr.get(elementType).name;
166
167
alloc = lookup.findStatic(bufferType, "allocate",
168
MethodType.methodType(bufferType, int.class));
169
allocBB = lookup.findStatic(ByteBuffer.class, "allocate",
170
MethodType.methodType(ByteBuffer.class, int.class));
171
allocDirect = lookup.findStatic(ByteBuffer.class, "allocateDirect",
172
MethodType.methodType(ByteBuffer.class, int.class));
173
174
asReadOnlyBuffer = lookup.findVirtual(bufferType,
175
"asReadOnlyBuffer", MethodType.methodType(bufferType));
176
if (elementType != byte.class) {
177
asTypeBuffer = lookup.findVirtual(ByteBuffer.class,
178
"as" + name + "Buffer", MethodType.methodType(bufferType));
179
}
180
181
putAbs = lookup.findVirtual(bufferType, "put",
182
MethodType.methodType(bufferType, int.class, elementType));
183
getAbs = lookup.findVirtual(bufferType, "get",
184
MethodType.methodType(elementType, int.class));
185
186
putBufAbs = lookup.findVirtual(bufferType, "put",
187
MethodType.methodType(bufferType, int.class, bufferType,
188
int.class, int.class));
189
putBufRel = lookup.findVirtual(bufferType, "put",
190
MethodType.methodType(bufferType, bufferType));
191
192
equals = lookup.findVirtual(bufferType, "equals",
193
MethodType.methodType(boolean.class, Object.class));
194
195
nextType = lookup.findVirtual(MyRandom.class,
196
"next" + name, MethodType.methodType(elementType));
197
} catch (IllegalAccessException | NoSuchMethodException e) {
198
throw new AssertionError(e);
199
}
200
}
201
202
Buffer create(int capacity) throws Throwable {
203
204
Class<?> bufferType = typeToAttr.get(elementType).type;
205
206
try {
207
if (bufferType == ByteBuffer.class ||
208
kind == BufferKind.DIRECT || kind == BufferKind.HEAP_VIEW) {
209
int len = capacity*typeToAttr.get(elementType).bytes;
210
ByteBuffer bb = (ByteBuffer)allocBB.invoke(len);
211
byte[] bytes = new byte[len];
212
RND.nextBytes(bytes);
213
bb.put(0, bytes);
214
if (bufferType == ByteBuffer.class) {
215
return (Buffer)bb;
216
} else {
217
bb.order(order);
218
return (Buffer)asTypeBuffer.invoke(bb);
219
}
220
} else if (bufferType == CharBuffer.class &&
221
kind == BufferKind.STRING) {
222
char[] array = new char[capacity];
223
for (int i = 0; i < capacity; i++) {
224
array[i] = RND.nextChar();
225
}
226
return CharBuffer.wrap(new String(array));
227
} else {
228
Buffer buf = (Buffer)alloc.invoke(capacity);
229
for (int i = 0; i < capacity; i++) {
230
putAbs.invoke(buf, i, nextType.invoke(RND));
231
}
232
return buf;
233
}
234
} catch (Exception e) {
235
throw new AssertionError(e);
236
}
237
}
238
239
void copy(Buffer src, int srcOff, Buffer dst, int dstOff, int length)
240
throws Throwable {
241
try {
242
for (int i = 0; i < length; i++) {
243
putAbs.invoke(dst, dstOff + i, getAbs.invoke(src, srcOff + i));
244
}
245
} catch (ReadOnlyBufferException ro) {
246
throw ro;
247
} catch (Exception e) {
248
throw new AssertionError(e);
249
}
250
}
251
252
Buffer asReadOnlyBuffer(Buffer buf) throws Throwable {
253
try {
254
return (Buffer)asReadOnlyBuffer.invoke(buf);
255
} catch (Exception e) {
256
throw new AssertionError(e);
257
}
258
}
259
260
void put(Buffer src, int srcOff, Buffer dst, int dstOff, int length)
261
throws Throwable {
262
try {
263
putBufAbs.invoke(dst, dstOff, src, srcOff, length);
264
} catch (ReadOnlyBufferException ro) {
265
throw ro;
266
} catch (Exception e) {
267
throw new AssertionError(e);
268
}
269
}
270
271
void put(Buffer src, Buffer dst) throws Throwable {
272
try {
273
putBufRel.invoke(dst, src);
274
} catch (ReadOnlyBufferException ro) {
275
throw ro;
276
} catch (Exception e) {
277
throw new AssertionError(e);
278
}
279
}
280
281
boolean equals(Buffer src, Buffer dst) throws Throwable {
282
try {
283
return Boolean.class.cast(equals.invoke(dst, src));
284
} catch (Exception e) {
285
throw new AssertionError(e);
286
}
287
}
288
}
289
290
static List<BufferProxy> getProxies(Class<?> type) {
291
List proxies = new ArrayList();
292
for (BufferKind kind : getKinds(type)) {
293
for (ByteOrder order : getOrders(kind, type)) {
294
proxies.add(new BufferProxy(type, kind, order));
295
}
296
}
297
return proxies;
298
}
299
300
@DataProvider
301
static Object[][] proxies() {
302
ArrayList<Object[]> args = new ArrayList<>();
303
for (Class<?> type : typeToAttr.keySet()) {
304
List<BufferProxy> proxies = getProxies(type);
305
for (BufferProxy proxy : proxies) {
306
args.add(new Object[] {proxy});
307
}
308
}
309
return args.toArray(Object[][]::new);
310
}
311
312
@DataProvider
313
static Object[][] proxyPairs() {
314
List<Object[]> args = new ArrayList<>();
315
for (Class<?> type : typeToAttr.keySet()) {
316
List<BufferProxy> proxies = getProxies(type);
317
for (BufferProxy proxy1 : proxies) {
318
for (BufferProxy proxy2 : proxies) {
319
args.add(new Object[] {proxy1, proxy2});
320
}
321
}
322
}
323
return args.toArray(Object[][]::new);
324
}
325
326
private static void expectThrows(Class<?> exClass, Assert.ThrowingRunnable r) {
327
try {
328
r.run();
329
} catch(Throwable e) {
330
if (e.getClass() != exClass && e.getCause().getClass() != exClass) {
331
throw new RuntimeException("Expected " + exClass +
332
"; got " + e.getCause().getClass(), e);
333
}
334
}
335
}
336
337
@Test(dataProvider = "proxies")
338
public static void testExceptions(BufferProxy bp) throws Throwable {
339
int cap = 27;
340
Buffer buf = bp.create(cap);
341
342
expectThrows(IndexOutOfBoundsException.class,
343
() -> bp.put(buf, -1, buf, 0, 1));
344
expectThrows(IndexOutOfBoundsException.class,
345
() -> bp.put(buf, 0, buf, -1, 1));
346
expectThrows(IndexOutOfBoundsException.class,
347
() -> bp.put(buf, 1, buf, 0, cap));
348
expectThrows(IndexOutOfBoundsException.class,
349
() -> bp.put(buf, 0, buf, 1, cap));
350
expectThrows(IndexOutOfBoundsException.class,
351
() -> bp.put(buf, 0, buf, 0, cap + 1));
352
expectThrows(IndexOutOfBoundsException.class,
353
() -> bp.put(buf, 0, buf, 0, Integer.MAX_VALUE));
354
355
Buffer rob = buf.isReadOnly() ? buf : bp.asReadOnlyBuffer(buf);
356
expectThrows(ReadOnlyBufferException.class,
357
() -> bp.put(buf, 0, rob, 0, cap));
358
}
359
360
@Test(dataProvider = "proxies")
361
public static void testSelf(BufferProxy bp) throws Throwable {
362
for (int i = 0; i < ITERATIONS; i++) {
363
int cap = RND.nextInt(MAX_CAPACITY);
364
Buffer buf = bp.create(cap);
365
366
int lowerOffset = RND.nextInt(1 + cap/10);
367
int lowerLength = RND.nextInt(1 + cap/2);
368
if (lowerLength < 2)
369
continue;
370
Buffer lower = buf.slice(lowerOffset, lowerLength);
371
372
Buffer lowerCopy = bp.create(lowerLength);
373
if (lowerCopy.isReadOnly()) {
374
Assert.expectThrows(ReadOnlyBufferException.class,
375
() -> bp.copy(lower, 0, lowerCopy, 0, lowerLength));
376
break;
377
}
378
bp.copy(lower, 0, lowerCopy, 0, lowerLength);
379
380
int middleOffset = RND.nextInt(1 + cap/2);
381
Buffer middle = buf.slice(middleOffset, lowerLength);
382
Buffer middleCopy = bp.create(lowerLength);
383
bp.copy(middle, 0, middleCopy, 0, lowerLength);
384
385
bp.put(lower, middle);
386
middle.flip();
387
388
Assert.assertTrue(bp.equals(lowerCopy, middle),
389
String.format("%d %s %d %d %d %d%n", SEED,
390
buf.getClass().getName(), cap,
391
lowerOffset, lowerLength, middleOffset));
392
393
bp.copy(lowerCopy, 0, buf, lowerOffset, lowerLength);
394
bp.copy(middleCopy, 0, buf, middleOffset, lowerLength);
395
396
bp.put(buf, lowerOffset, buf, middleOffset, lowerLength);
397
398
Assert.assertTrue(bp.equals(lowerCopy, middle),
399
String.format("%d %s %d %d %d %d%n", SEED,
400
buf.getClass().getName(), cap,
401
lowerOffset, lowerLength, middleOffset));
402
}
403
}
404
405
@Test(dataProvider = "proxyPairs")
406
public static void testPairs(BufferProxy bp, BufferProxy sbp) throws Throwable {
407
for (int i = 0; i < ITERATIONS; i++) {
408
int cap = Math.max(4, RND.nextInt(MAX_CAPACITY));
409
int cap2 = cap/2;
410
Buffer buf = bp.create(cap);
411
412
int pos = RND.nextInt(Math.max(1, cap2));
413
buf.position(pos);
414
buf.mark();
415
int lim = pos + Math.max(1, cap - pos);
416
buf.limit(lim);
417
418
int scap = Math.max(buf.remaining(), RND.nextInt(1024));
419
Buffer src = sbp.create(scap);
420
421
int diff = scap - buf.remaining();
422
int spos = diff > 0 ? RND.nextInt(diff) : 0;
423
src.position(spos);
424
src.mark();
425
int slim = spos + buf.remaining();
426
src.limit(slim);
427
428
if (buf.isReadOnly()) {
429
Assert.expectThrows(ReadOnlyBufferException.class,
430
() -> bp.put(src, buf));
431
break;
432
}
433
434
Buffer backup = bp.create(slim - spos);
435
bp.copy(buf, pos, backup, 0, backup.capacity());
436
bp.put(src, buf);
437
438
buf.reset();
439
src.reset();
440
441
Assert.assertTrue(bp.equals(src, buf),
442
String.format("%d %s %d %d %d %s %d %d %d%n", SEED,
443
buf.getClass().getName(), cap, pos, lim,
444
src.getClass().getName(), scap, spos, slim));
445
446
src.clear();
447
buf.clear();
448
bp.copy(backup, 0, buf, pos, backup.capacity());
449
bp.put(src, spos, buf, pos, backup.capacity());
450
src.position(spos);
451
src.limit(slim);
452
buf.position(pos);
453
buf.limit(lim);
454
455
Assert.assertTrue(bp.equals(src, buf),
456
String.format("%d %s %d %d %d %s %d %d %d%n", SEED,
457
buf.getClass().getName(), cap, pos, lim,
458
src.getClass().getName(), scap, spos, slim));
459
}
460
}
461
}
462
463