Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/io/pathNames/General.java
41149 views
1
/*
2
* Copyright (c) 1998, 2017, 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
/*
25
@summary Common definitions for general exhaustive pathname tests
26
@author Mark Reinhold
27
*/
28
29
import java.io.*;
30
import java.util.*;
31
import java.nio.file.*;
32
33
34
public class General {
35
36
public static boolean debug = false;
37
38
private static boolean win32 = (File.separatorChar == '\\');
39
40
private static int gensymCounter = 0;
41
42
protected static final String userDir = System.getProperty("user.dir");
43
protected static final String workSubDir = "tmp";
44
45
protected static String baseDir = null;
46
protected static String relative = null;
47
48
/* Generate a filename unique to this run */
49
private static String gensym() {
50
return "x." + ++gensymCounter;
51
}
52
53
/**
54
* Create files and folders in the test working directory.
55
* The purpose is to make sure the test will not go out of
56
* its user dir when walking the file tree.
57
*
58
* @param depth The number of directory levels to be created under
59
* the user directory. It should be the maximum value
60
* of the depths passed to checkNames method (including
61
* direct or indirect calling) in a whole test.
62
*/
63
protected static void initTestData(int depth) throws IOException {
64
File parent = new File(userDir + File.separator + workSubDir);
65
if (!parent.mkdir()) {
66
throw new IOException("Fail to create directory: " + parent);
67
}
68
for (int i = 0; i < depth; i++) {
69
File tmp = new File(parent, gensym());
70
tmp.createNewFile();
71
tmp = new File(parent, gensym());
72
if (tmp.mkdir())
73
parent = tmp;
74
else
75
throw new IOException("Fail to create directory, " + tmp);
76
}
77
baseDir = parent.getAbsolutePath();
78
relative = baseDir.substring(userDir.length() + 1);
79
}
80
81
/**
82
* Find a file in the given subdirectory, or descend into further
83
* subdirectories, if any, if no file is found here. Return null if no
84
* file can be found anywhere beneath the given subdirectory.
85
* @param dir Directory at which we started
86
* @param subdir Subdirectory that we're exploring
87
* @param dl Listing of subdirectory
88
*/
89
private static String findSomeFile(String dir, String subdir, String[] dl) {
90
for (int i = 0; i < dl.length; i++) {
91
File f = new File(subdir, dl[i]);
92
File df = new File(dir, f.getPath());
93
if (Files.isRegularFile(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
94
return f.getPath();
95
}
96
}
97
for (int i = 0; i < dl.length; i++) {
98
File f = (subdir.length() == 0) ? new File(dl[i])
99
: new File(subdir, dl[i]);
100
File df = new File(dir, f.getPath());
101
if (Files.isDirectory(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
102
String[] dl2 = df.list();
103
if (dl2 != null) {
104
String ff = findSomeFile(dir, f.getPath(), dl2);
105
if (ff != null) return ff;
106
}
107
}
108
}
109
return null;
110
}
111
112
113
/**
114
* Construct a string that names a file in the given directory. If create
115
* is true, then create a file if none is found, and throw an exception if
116
* that is not possible; otherwise, return null if no file can be found.
117
*/
118
private static String findSomeFile(String dir, boolean create) {
119
File d = new File(dir);
120
String[] dl = d.list();
121
if (dl == null) {
122
throw new RuntimeException("Can't list " + dir);
123
}
124
for (int i = 0; i < dl.length; i++) {
125
File f = new File(dir, dl[i]);
126
if (Files.isRegularFile(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
127
return dl[i];
128
}
129
}
130
String f = findSomeFile(dir, "", dl);
131
if (f != null) {
132
return f;
133
}
134
if (create) {
135
File nf = new File(d, gensym());
136
OutputStream os;
137
try {
138
os = new FileOutputStream(nf);
139
os.close();
140
} catch (IOException x) {
141
throw new RuntimeException("Can't create a file in " + dir);
142
}
143
return nf.getName();
144
}
145
return null;
146
}
147
148
149
/**
150
* Construct a string that names a subdirectory of the given directory.
151
* If create is true, then create a subdirectory if none is found, and
152
* throw an exception if that is not possible; otherwise, return null if
153
* no subdirectory can be found.
154
*/
155
private static String findSomeDir(String dir, boolean create) {
156
File d = new File(dir);
157
String[] dl = d.list();
158
if (dl == null) {
159
throw new RuntimeException("Can't list " + dir);
160
}
161
for (int i = 0; i < dl.length; i++) {
162
File f = new File(d, dl[i]);
163
if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
164
String[] dl2 = f.list();
165
if (dl2 == null || dl2.length >= 250) {
166
/* Heuristic to avoid scanning huge directories */
167
continue;
168
}
169
return dl[i];
170
}
171
}
172
if (create) {
173
File sd = new File(d, gensym());
174
if (sd.mkdir()) return sd.getName();
175
}
176
return null;
177
}
178
179
180
/** Construct a string that does not name a file in the given directory */
181
private static String findNon(String dir) {
182
File d = new File(dir);
183
String[] x = new String[] { "foo", "bar", "baz" };
184
for (int i = 0; i < x.length; i++) {
185
File f = new File(d, x[i]);
186
if (!f.exists()) {
187
return x[i];
188
}
189
}
190
for (int i = 0; i < 1024; i++) {
191
String n = "xx" + Integer.toString(i);
192
File f = new File(d, n);
193
if (!f.exists()) {
194
return n;
195
}
196
}
197
throw new RuntimeException("Can't find a non-existent file in " + dir);
198
}
199
200
201
/** Ensure that the named file does not exist */
202
public static void ensureNon(String fn) {
203
if ((new File(fn)).exists()) {
204
throw new RuntimeException("Test path " + fn + " exists");
205
}
206
}
207
208
209
/** Tell whether the given character is a "slash" on this platform */
210
private static boolean isSlash(char x) {
211
if (x == File.separatorChar) return true;
212
if (win32 && (x == '/')) return true;
213
return false;
214
}
215
216
217
/**
218
* Trim trailing slashes from the given string, but leave singleton slashes
219
* alone (they denote root directories)
220
*/
221
private static String trimTrailingSlashes(String s) {
222
int n = s.length();
223
if (n == 0) return s;
224
n--;
225
while ((n > 0) && isSlash(s.charAt(n))) {
226
if ((n >= 1) && s.charAt(n - 1) == ':') break;
227
n--;
228
}
229
return s.substring(0, n + 1);
230
}
231
232
233
/** Concatenate two paths, trimming slashes as needed */
234
private static String pathConcat(String a, String b) {
235
if (a.length() == 0) return b;
236
if (b.length() == 0) return a;
237
if (isSlash(a.charAt(a.length() - 1))
238
|| isSlash(b.charAt(0))
239
|| (win32 && (a.charAt(a.length() - 1) == ':'))) {
240
return a + b;
241
} else {
242
return a + File.separatorChar + b;
243
}
244
}
245
246
247
248
/** Hash table of input pathnames, used to detect duplicates */
249
private static Hashtable<String, String> checked = new Hashtable<>();
250
251
/**
252
* Check the given pathname. Its canonical pathname should be the given
253
* answer. If the path names a file that exists and is readable, then
254
* FileInputStream and RandomAccessFile should both be able to open it.
255
*/
256
public static void check(String answer, String path) throws IOException {
257
String ans = trimTrailingSlashes(answer);
258
if (path.length() == 0) return;
259
if (checked.get(path) != null) {
260
System.err.println("DUP " + path);
261
return;
262
}
263
checked.put(path, path);
264
265
String cpath;
266
try {
267
File f = new File(path);
268
cpath = f.getCanonicalPath();
269
if (f.exists() && f.isFile() && f.canRead()) {
270
InputStream in = new FileInputStream(path);
271
in.close();
272
RandomAccessFile raf = new RandomAccessFile(path, "r");
273
raf.close();
274
}
275
} catch (IOException x) {
276
System.err.println(ans + " <-- " + path + " ==> " + x);
277
if (debug) return;
278
else throw x;
279
}
280
if (cpath.equals(ans)) {
281
System.err.println(ans + " <== " + path);
282
} else {
283
System.err.println(ans + " <-- " + path + " ==> " + cpath + " MISMATCH");
284
if (!debug) {
285
throw new RuntimeException("Mismatch: " + path + " ==> " + cpath +
286
", should be " + ans);
287
}
288
}
289
}
290
291
292
293
/*
294
* The following three mutually-recursive methods generate and check a tree
295
* of filenames of arbitrary depth. Each method has (at least) these
296
* arguments:
297
*
298
* int depth Remaining tree depth
299
* boolean create Controls whether test files and directories
300
* will be created as needed
301
* String ans Expected answer for the check method (above)
302
* String ask Input pathname to be passed to the check method
303
*/
304
305
306
/** Check a single slash case, plus its children */
307
private static void checkSlash(int depth, boolean create,
308
String ans, String ask, String slash)
309
throws Exception
310
{
311
check(ans, ask + slash);
312
checkNames(depth, create,
313
ans.endsWith(File.separator) ? ans : ans + File.separator,
314
ask + slash);
315
}
316
317
318
/** Check slash cases for the given ask string */
319
public static void checkSlashes(int depth, boolean create,
320
String ans, String ask)
321
throws Exception
322
{
323
check(ans, ask);
324
if (depth == 0) return;
325
326
checkSlash(depth, create, ans, ask, "/");
327
checkSlash(depth, create, ans, ask, "//");
328
checkSlash(depth, create, ans, ask, "///");
329
if (win32) {
330
checkSlash(depth, create, ans, ask, "\\");
331
checkSlash(depth, create, ans, ask, "\\\\");
332
checkSlash(depth, create, ans, ask, "\\/");
333
checkSlash(depth, create, ans, ask, "/\\");
334
checkSlash(depth, create, ans, ask, "\\\\\\");
335
}
336
}
337
338
339
/** Check name cases for the given ask string */
340
public static void checkNames(int depth, boolean create,
341
String ans, String ask)
342
throws Exception
343
{
344
int d = depth - 1;
345
File f = new File(ans);
346
String n;
347
348
/* Normal name */
349
if (f.exists()) {
350
if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS) && f.list() != null) {
351
if ((n = findSomeFile(ans, create)) != null)
352
checkSlashes(d, create, ans + n, ask + n);
353
if ((n = findSomeDir(ans, create)) != null)
354
checkSlashes(d, create, ans + n, ask + n);
355
}
356
n = findNon(ans);
357
checkSlashes(d, create, ans + n, ask + n);
358
} else {
359
n = "foo" + depth;
360
checkSlashes(d, create, ans + n, ask + n);
361
}
362
363
/* "." */
364
checkSlashes(d, create, trimTrailingSlashes(ans), ask + ".");
365
366
/* ".." */
367
if ((n = f.getParent()) != null) {
368
String n2;
369
if (win32
370
&& ((n2 = f.getParentFile().getParent()) != null)
371
&& n2.equals("\\\\")) {
372
/* Win32 resolves \\foo\bar\.. to \\foo\bar */
373
checkSlashes(d, create, ans, ask + "..");
374
} else {
375
checkSlashes(d, create, n, ask + "..");
376
}
377
}
378
else {
379
if (win32)
380
checkSlashes(d, create, ans, ask + "..");
381
else {
382
// Fix for 4237875. We must ensure that we are sufficiently
383
// deep in the path hierarchy to test parents this high up
384
File thisPath = new File(ask);
385
File nextPath = new File(ask + "..");
386
if (!thisPath.getCanonicalPath().equals(nextPath.getCanonicalPath()))
387
checkSlashes(d, create, ans + "..", ask + "..");
388
}
389
}
390
}
391
}
392
393