Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/nio/channels/FileChannel/Transfers.java
38828 views
1
/*
2
* Copyright (c) 2002, 2010, 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
/* @test
25
* @summary Comprehensive test for FileChannel.transfer{From,To}
26
* @bug 4708120
27
* @author Mark Reinhold
28
*/
29
30
import java.io.*;
31
import java.nio.*;
32
import java.nio.channels.*;
33
import java.util.*;
34
35
36
public class Transfers {
37
38
static PrintStream out = System.out;
39
40
private static class Failure
41
extends RuntimeException
42
{
43
44
Failure(Exception x) {
45
super(x);
46
}
47
48
Failure(String s) {
49
super(s);
50
}
51
52
}
53
54
55
// -- Writing and reading random bytes --
56
57
private static void writeBytes(byte[] ba, FileChannel fc,
58
int off, int len)
59
throws IOException
60
{
61
fc.position(off);
62
if (fc.write(ByteBuffer.wrap(ba, 0, len)) != len)
63
throw new IOException("Incomplete write");
64
fc.position(0);
65
}
66
67
private static void writeRandomBytes(long seed,
68
FileChannel fc, int off, int len)
69
throws IOException
70
{
71
Random r = new Random(seed);
72
byte[] ba = new byte[len];
73
r.nextBytes(ba);
74
writeBytes(ba, fc, off, len);
75
}
76
77
private static void writeZeroBytes(FileChannel fc, int off, int len)
78
throws IOException
79
{
80
byte[] ba = new byte[len];
81
writeBytes(ba, fc, off, len);
82
}
83
84
private static void checkBytes(FileChannel fc, int off, int len,
85
byte[] bytes)
86
throws IOException
87
{
88
ByteBuffer bb = ByteBuffer.allocate(len);
89
fc.position(off);
90
if (fc.read(bb) != len)
91
throw new IOException("Incomplete read");
92
bb.flip();
93
ByteBuffer bab = ByteBuffer.wrap(bytes, 0, len);
94
if (!bb.equals(bab))
95
throw new Failure("Wrong data written");
96
}
97
98
private static void checkRandomBytes(FileChannel fc, int off, int len,
99
long seed)
100
throws IOException
101
{
102
byte[] ba = new byte[len];
103
Random r = new Random(seed);
104
r.nextBytes(ba);
105
checkBytes(fc, off, len, ba);
106
}
107
108
private static void checkZeroBytes(FileChannel fc, int off, int len)
109
throws IOException
110
{
111
byte[] ba = new byte[len];
112
checkBytes(fc, off, len, ba);
113
}
114
115
// For debugging
116
//
117
private static void dump(FileChannel fc)
118
throws IOException
119
{
120
int sz = (int)fc.size();
121
ByteBuffer bb = ByteBuffer.allocate(sz);
122
fc.position(0);
123
if (fc.read(bb) != sz)
124
throw new IOException("Incomplete read");
125
bb.flip();
126
byte prev = -1;
127
int r = 0; // Repeats
128
int n = 0;
129
while (bb.hasRemaining() && (n < 32)) {
130
byte b = bb.get();
131
if (b == prev) {
132
r++;
133
continue;
134
}
135
if (r > 0) {
136
int c = prev & 0xff;
137
if (c < 0x10)
138
out.print('0');
139
out.print(Integer.toHexString(c));
140
if (r > 1) {
141
out.print("[");
142
out.print(r);
143
out.print("]");
144
}
145
n++;
146
}
147
prev = b;
148
r = 1;
149
}
150
if (r > 0) {
151
int c = prev & 0xff;
152
if (c < 0x10)
153
out.print('0');
154
out.print(Integer.toHexString(c));
155
if (r > 1) {
156
out.print("[");
157
out.print(r);
158
out.print("]");
159
}
160
n++;
161
}
162
if (bb.hasRemaining())
163
out.print("...");
164
out.println();
165
}
166
167
168
169
static File sourceFile;
170
static File targetFile;
171
172
// -- Self-verifying sources and targets --
173
174
static abstract class Source {
175
176
protected final int size;
177
protected final long seed;
178
private final String name;
179
180
Source(int size, long seed, String name) {
181
this.size = size;
182
this.seed = seed;
183
this.name = name;
184
}
185
186
String name() {
187
return name;
188
}
189
190
abstract ReadableByteChannel channel();
191
192
abstract void verify() throws IOException;
193
194
}
195
196
static class FileSource
197
extends Source
198
{
199
private final File fn;
200
private final RandomAccessFile raf;
201
private final FileChannel fc;
202
203
FileSource(int size, long seed) throws IOException {
204
super(size, seed, "FileChannel");
205
fn = sourceFile;
206
raf = new RandomAccessFile(fn, "rw");
207
fc = raf.getChannel();
208
fc.position(0);
209
writeRandomBytes(seed, fc, 0, size);
210
}
211
212
ReadableByteChannel channel() {
213
return fc;
214
}
215
216
void verify() throws IOException {
217
if (fc.position() != size)
218
throw new Failure("Wrong position: "
219
+ fc.position() + " (expected " + size +
220
")");
221
checkRandomBytes(fc, 0, size, seed);
222
fc.close();
223
raf.close(); // Bug in 1.4.0
224
}
225
226
}
227
228
static class UserSource
229
extends Source
230
{
231
private ReadableByteChannel ch;
232
private final ByteBuffer src;
233
234
UserSource(int size, long seed) {
235
super(size, seed, "UserChannel");
236
237
final byte[] bytes = new byte[size + 1];
238
Random r = new Random(seed);
239
r.nextBytes(bytes);
240
src = ByteBuffer.wrap(bytes);
241
242
ch = new ReadableByteChannel() {
243
public int read(ByteBuffer dst) {
244
if (!src.hasRemaining())
245
return -1;
246
int nr = Math.min(src.remaining(), dst.remaining());
247
ByteBuffer s = src.duplicate();
248
s.limit(s.position() + nr);
249
dst.put(s);
250
src.position(src.position() + nr);
251
return nr;
252
}
253
public boolean isOpen() {
254
return true;
255
}
256
public void close() { }
257
};
258
}
259
260
ReadableByteChannel channel() {
261
return ch;
262
}
263
264
void verify() {
265
if (src.remaining() != 1)
266
throw new Failure("Source has " + src.remaining()
267
+ " bytes remaining (expected 1)");
268
}
269
270
}
271
272
static abstract class Target {
273
274
protected final int size;
275
protected final long seed;
276
private final String name;
277
278
Target(int size, long seed, String name) {
279
this.size = size;
280
this.seed = seed;
281
this.name = name;
282
}
283
284
String name() {
285
return name;
286
}
287
288
abstract WritableByteChannel channel();
289
290
abstract void verify() throws IOException;
291
292
}
293
294
static class FileTarget
295
extends Target
296
{
297
private final File fn;
298
private final RandomAccessFile raf;
299
private final FileChannel fc;
300
301
FileTarget(int size, long seed) throws IOException {
302
super(size, seed, "FileChannel");
303
fn = targetFile;
304
raf = new RandomAccessFile(fn, "rw");
305
fc = raf.getChannel();
306
fc.position(0);
307
}
308
309
WritableByteChannel channel() {
310
return fc;
311
}
312
313
void verify() throws IOException {
314
if (fc.position() != size)
315
throw new Failure("Wrong position: "
316
+ fc.position() + " (expected " + size + ")");
317
checkRandomBytes(fc, 0, size, seed);
318
fc.close();
319
raf.close(); // Bug in 1.4.0
320
}
321
322
}
323
324
static class UserTarget
325
extends Target
326
{
327
private WritableByteChannel ch;
328
private final ByteBuffer dst;
329
330
UserTarget(int size, long seed) {
331
super(size, seed, "UserChannel");
332
dst = ByteBuffer.wrap(new byte[size + 1]);
333
334
ch = new WritableByteChannel() {
335
public int write(ByteBuffer src) {
336
int nr = Math.min(src.remaining(), dst.remaining());
337
ByteBuffer s = src.duplicate();
338
s.limit(s.position() + nr);
339
dst.put(s);
340
src.position(src.position() + nr);
341
return nr;
342
}
343
public boolean isOpen() {
344
return true;
345
}
346
public void close() { }
347
};
348
}
349
350
WritableByteChannel channel() {
351
return ch;
352
}
353
354
void verify() {
355
if (dst.remaining() != 1)
356
throw new Failure("Destination has " + dst.remaining()
357
+ " bytes remaining (expected 1)");
358
byte[] ba = new byte[size];
359
Random r = new Random(seed);
360
r.nextBytes(ba);
361
dst.flip();
362
ByteBuffer rbb = ByteBuffer.wrap(ba, 0, size);
363
if (!dst.equals(rbb))
364
throw new Failure("Wrong data written");
365
}
366
367
}
368
369
370
// Generates a sequence of ints of the form 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
371
// 15, 16, 17, 31, 32, 33, ..., 2^i-1, 2^i, 2^i+1, ..., max.
372
373
static class IntGenerator {
374
375
private int max;
376
private int cur = -1;
377
private int p2 = 8;
378
379
IntGenerator(int max) {
380
this.max = max;
381
}
382
383
boolean hasNext() {
384
return cur < max;
385
}
386
387
int next() {
388
if (cur >= max)
389
throw new IllegalStateException();
390
if (cur < 6) {
391
cur++;
392
return cur;
393
}
394
if (cur == p2 + 1) {
395
p2 <<= 1;
396
cur = p2 - 1;
397
return cur;
398
}
399
cur++;
400
return cur;
401
}
402
403
}
404
405
406
// -- Tests --
407
408
private static final int MAX_XFER_SIZE = 1 << 14;
409
private static final int MAX_FILE_SIZE = MAX_XFER_SIZE << 1;
410
411
private static boolean debug = false;
412
private static boolean verbose = false;
413
414
static void show(String dir, String channelName, int off, int len) {
415
if (!verbose)
416
return;
417
out.println(dir + " " + channelName +
418
": offset " + off + ", length " + len);
419
}
420
421
static void testTo(long seed, FileChannel fc, int off, int len, Target tgt)
422
throws IOException
423
{
424
show("To", tgt.name(), off, len);
425
426
// Clear source, then randomize just the source region
427
writeZeroBytes(fc, 0, MAX_FILE_SIZE);
428
writeRandomBytes(seed, fc, off, len);
429
430
// Randomize position
431
int pos = (int)seed & 0xfff;
432
fc.position(pos);
433
434
int n = (int)fc.transferTo(off, len, tgt.channel());
435
if (n != len)
436
throw new Failure("Incorrect transfer length: " + n
437
+ " (expected " + len + ")");
438
439
// Check that source wasn't changed
440
if (fc.position() != pos)
441
throw new Failure("Position changed");
442
if (debug)
443
dump(fc);
444
checkRandomBytes(fc, off, len, seed);
445
writeZeroBytes(fc, off, len);
446
checkZeroBytes(fc, 0, MAX_FILE_SIZE);
447
448
// Check that target was updated correctly
449
tgt.verify();
450
}
451
452
static void testFrom(long seed, Source src, FileChannel fc, int off, int len)
453
throws IOException
454
{
455
show("From", src.name(), off, len);
456
457
// Clear target
458
writeZeroBytes(fc, 0, MAX_FILE_SIZE);
459
460
// Randomize position
461
int pos = (int)seed & 0xfff;
462
fc.position(pos);
463
464
int n = (int)fc.transferFrom(src.channel(), off, len);
465
if (n != len)
466
throw new Failure("Incorrect transfer length: " + n
467
+ " (expected " + len + ")");
468
469
// Check that source didn't change, and was read correctly
470
src.verify();
471
472
// Check that target was updated correctly
473
if (fc.position() != pos)
474
throw new Failure("Position changed");
475
if (debug)
476
dump(fc);
477
checkRandomBytes(fc, off, len, seed);
478
writeZeroBytes(fc, off, len);
479
checkZeroBytes(fc, 0, MAX_FILE_SIZE);
480
}
481
482
public static void main(String[] args)
483
throws Exception
484
{
485
if (args.length > 0) {
486
if (args[0].indexOf('v') >= 0)
487
verbose = true;
488
if (args[0].indexOf('d') >= 0)
489
debug = verbose = true;
490
}
491
492
sourceFile = File.createTempFile("xfer.src.", "");
493
sourceFile.deleteOnExit();
494
targetFile = File.createTempFile("xfer.tgt.", "");
495
targetFile.deleteOnExit();
496
497
File fn = File.createTempFile("xfer.fch.", "");
498
fn.deleteOnExit();
499
FileChannel fc = new RandomAccessFile(fn, "rw").getChannel();
500
501
Random rnd = new Random();
502
int failures = 0;
503
504
for (boolean to = false;; to = true) {
505
for (boolean user = false;; user = true) {
506
if (!verbose)
507
out.print((to ? "To " : "From ") +
508
(user ? "user channel" : "file channel")
509
+ ":");
510
IntGenerator offGen = new IntGenerator(MAX_XFER_SIZE + 2);
511
while (offGen.hasNext()) {
512
int off = offGen.next();
513
if (!verbose) out.print(" " + off);
514
IntGenerator lenGen = new IntGenerator(MAX_XFER_SIZE + 2);
515
while (lenGen.hasNext()) {
516
int len = lenGen.next();
517
long s = rnd.nextLong();
518
String chName = null;
519
try {
520
if (to) {
521
Target tgt;
522
if (user)
523
tgt = new UserTarget(len, s);
524
else
525
tgt = new FileTarget(len, s);
526
chName = tgt.name();
527
testTo(s, fc, off, len, tgt);
528
}
529
else {
530
Source src;
531
if (user)
532
src = new UserSource(len, s);
533
else
534
src = new FileSource(len, s);
535
chName = src.name();
536
testFrom(s, src, fc, off, len);
537
}
538
} catch (Failure x) {
539
out.println();
540
out.println("FAILURE: " + chName
541
+ ", offset " + off
542
+ ", length " + len);
543
x.printStackTrace(out);
544
failures++;
545
}
546
}
547
}
548
if (!verbose)
549
out.println();
550
if (user)
551
break;
552
}
553
if (to)
554
break;
555
}
556
557
sourceFile.delete();
558
targetFile.delete();
559
fn.delete();
560
561
if (failures > 0) {
562
out.println();
563
throw new RuntimeException("Some tests failed");
564
}
565
566
}
567
568
}
569
570