Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java
32288 views
1
/*
2
* Copyright (c) 2008, 2011, 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.fs;
27
28
import java.nio.file.InvalidPathException;
29
30
/**
31
* A parser of Windows path strings
32
*/
33
34
class WindowsPathParser {
35
private WindowsPathParser() { }
36
37
/**
38
* The result of a parse operation
39
*/
40
static class Result {
41
private final WindowsPathType type;
42
private final String root;
43
private final String path;
44
45
Result(WindowsPathType type, String root, String path) {
46
this.type = type;
47
this.root = root;
48
this.path = path;
49
}
50
51
/**
52
* The path type
53
*/
54
WindowsPathType type() {
55
return type;
56
}
57
58
/**
59
* The root component
60
*/
61
String root() {
62
return root;
63
}
64
65
/**
66
* The normalized path (includes root)
67
*/
68
String path() {
69
return path;
70
}
71
}
72
73
/**
74
* Parses the given input as a Windows path
75
*/
76
static Result parse(String input) {
77
return parse(input, true);
78
}
79
80
/**
81
* Parses the given input as a Windows path where it is known that the
82
* path is already normalized.
83
*/
84
static Result parseNormalizedPath(String input) {
85
return parse(input, false);
86
}
87
88
/**
89
* Parses the given input as a Windows path.
90
*
91
* @param requireToNormalize
92
* Indicates if the path requires to be normalized
93
*/
94
private static Result parse(String input, boolean requireToNormalize) {
95
String root = "";
96
WindowsPathType type = null;
97
98
int len = input.length();
99
int off = 0;
100
if (len > 1) {
101
char c0 = input.charAt(0);
102
char c1 = input.charAt(1);
103
char c = 0;
104
int next = 2;
105
if (isSlash(c0) && isSlash(c1)) {
106
// UNC: We keep the first two slash, collapse all the
107
// following, then take the hostname and share name out,
108
// meanwhile collapsing all the redundant slashes.
109
type = WindowsPathType.UNC;
110
off = nextNonSlash(input, next, len);
111
next = nextSlash(input, off, len);
112
if (off == next)
113
throw new InvalidPathException(input, "UNC path is missing hostname");
114
String host = input.substring(off, next); //host
115
off = nextNonSlash(input, next, len);
116
next = nextSlash(input, off, len);
117
if (off == next)
118
throw new InvalidPathException(input, "UNC path is missing sharename");
119
root = "\\\\" + host + "\\" + input.substring(off, next) + "\\";
120
off = next;
121
} else {
122
if (isLetter(c0) && c1 == ':') {
123
char c2;
124
if (len > 2 && isSlash(c2 = input.charAt(2))) {
125
// avoid concatenation when root is "D:\"
126
if (c2 == '\\') {
127
root = input.substring(0, 3);
128
} else {
129
root = input.substring(0, 2) + '\\';
130
}
131
off = 3;
132
type = WindowsPathType.ABSOLUTE;
133
} else {
134
root = input.substring(0, 2);
135
off = 2;
136
type = WindowsPathType.DRIVE_RELATIVE;
137
}
138
}
139
}
140
}
141
if (off == 0) {
142
if (len > 0 && isSlash(input.charAt(0))) {
143
type = WindowsPathType.DIRECTORY_RELATIVE;
144
root = "\\";
145
} else {
146
type = WindowsPathType.RELATIVE;
147
}
148
}
149
150
if (requireToNormalize) {
151
StringBuilder sb = new StringBuilder(input.length());
152
sb.append(root);
153
return new Result(type, root, normalize(sb, input, off));
154
} else {
155
return new Result(type, root, input);
156
}
157
}
158
159
/**
160
* Remove redundant slashes from the rest of the path, forcing all slashes
161
* into the preferred slash.
162
*/
163
private static String normalize(StringBuilder sb, String path, int off) {
164
int len = path.length();
165
off = nextNonSlash(path, off, len);
166
int start = off;
167
char lastC = 0;
168
while (off < len) {
169
char c = path.charAt(off);
170
if (isSlash(c)) {
171
if (lastC == ' ')
172
throw new InvalidPathException(path,
173
"Trailing char <" + lastC + ">",
174
off - 1);
175
sb.append(path, start, off);
176
off = nextNonSlash(path, off, len);
177
if (off != len) //no slash at the end of normalized path
178
sb.append('\\');
179
start = off;
180
} else {
181
if (isInvalidPathChar(c))
182
throw new InvalidPathException(path,
183
"Illegal char <" + c + ">",
184
off);
185
lastC = c;
186
off++;
187
}
188
}
189
if (start != off) {
190
if (lastC == ' ')
191
throw new InvalidPathException(path,
192
"Trailing char <" + lastC + ">",
193
off - 1);
194
sb.append(path, start, off);
195
}
196
return sb.toString();
197
}
198
199
private static final boolean isSlash(char c) {
200
return (c == '\\') || (c == '/');
201
}
202
203
private static final int nextNonSlash(String path, int off, int end) {
204
while (off < end && isSlash(path.charAt(off))) { off++; }
205
return off;
206
}
207
208
private static final int nextSlash(String path, int off, int end) {
209
char c;
210
while (off < end && !isSlash(c=path.charAt(off))) {
211
if (isInvalidPathChar(c))
212
throw new InvalidPathException(path,
213
"Illegal character [" + c + "] in path",
214
off);
215
off++;
216
}
217
return off;
218
}
219
220
private static final boolean isLetter(char c) {
221
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
222
}
223
224
// Reserved characters for window path name
225
private static final String reservedChars = "<>:\"|?*";
226
private static final boolean isInvalidPathChar(char ch) {
227
return ch < '\u0020' || reservedChars.indexOf(ch) != -1;
228
}
229
}
230
231