Mercurial > projects > dwt2
comparison org.eclipse.equinox.common/src/org/eclipse/core/runtime/Path.d @ 105:bbe49769ec18
...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 08 Nov 2009 12:42:30 +0100 |
parents | dccb717aa902 |
children |
comparison
equal
deleted
inserted
replaced
104:88652073d1c2 | 105:bbe49769ec18 |
---|---|
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
3 * All rights reserved. This program and the accompanying materials | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | 4 * are made available under the terms of the Eclipse Public License v1.0 |
5 * which accompanies this distribution, and is available at | 5 * which accompanies this distribution, and is available at |
6 * http://www.eclipse.org/legal/epl-v10.html | 6 * http://www.eclipse.org/legal/epl-v10.html |
7 * | 7 * |
8 * Contributors: | 8 * Contributors: |
9 * IBM Corporation - initial API and implementation | 9 * IBM Corporation - initial API and implementation |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | 10 *******************************************************************************/ |
13 module org.eclipse.core.runtime.Path; | 11 // Port to the D programming language: |
14 | 12 // Frank Benoit <benoit@tionex.de> |
15 import tango.io.FilePath; | 13 module org.eclipse.core.runtimePath; |
16 static import tango.io.Path; | |
17 import org.eclipse.core.runtime.IPath; | |
18 import org.eclipse.core.runtime.Assert; | |
19 | 14 |
20 import java.lang.all; | 15 import java.lang.all; |
21 | 16 |
22 import tango.io.model.IFile; | 17 import org.eclipse.core.runtimeIPath; // packageimport |
23 | 18 import org.eclipse.core.runtimeAssert; // packageimport |
24 /** | 19 |
20 import java.io.File; | |
21 | |
22 /** | |
25 * The standard implementation of the <code>IPath</code> interface. | 23 * The standard implementation of the <code>IPath</code> interface. |
26 * Paths are always maintained in canonicalized form. That is, parent | 24 * Paths are always maintained in canonicalized form. That is, parent |
27 * references (i.e., <code>../../</code>) and duplicate separators are | 25 * references (i.e., <code>../../</code>) and duplicate separators are |
28 * resolved. For example, | 26 * resolved. For example, |
29 * <pre> new Path("/a/b").append("../foo/bar")</pre> | 27 * <pre> (new Path("/a/b")).append("../foo/bar")</pre> |
30 * will yield the path | 28 * will yield the path |
31 * <pre> /a/foo/bar</pre> | 29 * <pre> /a/foo/bar</pre> |
32 * <p> | 30 * <p> |
33 * This class can be used without OSGi running. | 31 * This class can be used without OSGi running. |
34 * </p><p> | 32 * </p><p> |
38 * @see IPath | 36 * @see IPath |
39 * @noextend This class is not intended to be subclassed by clients. | 37 * @noextend This class is not intended to be subclassed by clients. |
40 */ | 38 */ |
41 public class Path : IPath, Cloneable { | 39 public class Path : IPath, Cloneable { |
42 /** masks for separator values */ | 40 /** masks for separator values */ |
43 private static const int HAS_LEADING = 1; | 41 private static final int HAS_LEADING = 1; |
44 private static const int IS_UNC = 2; | 42 private static final int IS_UNC = 2; |
45 private static const int HAS_TRAILING = 4; | 43 private static final int HAS_TRAILING = 4; |
46 | 44 |
47 private static const int ALL_SEPARATORS = HAS_LEADING | IS_UNC | HAS_TRAILING; | 45 private static final int ALL_SEPARATORS = HAS_LEADING | IS_UNC | HAS_TRAILING; |
48 | 46 |
49 /** Constant empty string value. */ | 47 /** Constant empty string value. */ |
50 private static const String EMPTY_STRING = ""; //$NON-NLS-1$ | 48 private static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
51 | 49 |
52 /** Constant value indicating no segments */ | 50 /** Constant value indicating no segments */ |
53 private static const String[] NO_SEGMENTS = null; | 51 private static final String[] NO_SEGMENTS = new String[0]; |
54 | 52 |
55 /** Constant value containing the empty path with no device. */ | 53 /** Constant value containing the empty path with no device. */ |
56 public static const Path EMPTY; | 54 public static final Path EMPTY = new Pathcast(EMPTY_STRING); |
57 | 55 |
58 /** Mask for all bits that are involved in the hash code */ | 56 /** Mask for all bits that are involved in the hash code */ |
59 private static const int HASH_MASK = ~HAS_TRAILING; | 57 private static final int HASH_MASK = ~HAS_TRAILING; |
60 | 58 |
61 /** Constant root path string (<code>"/"</code>). */ | 59 /** Constant root path string (<code>"/"</code>). */ |
62 private static const String ROOT_STRING = "/"; //$NON-NLS-1$ | 60 private static final String ROOT_STRING = "/"; //$NON-NLS-1$ |
63 | 61 |
64 /** Constant value containing the root path with no device. */ | 62 /** Constant value containing the root path with no device. */ |
65 public static const Path ROOT; | 63 public static final Path ROOT = new Pathcast(ROOT_STRING); |
66 | 64 |
67 /** Constant value indicating if the current platform is Windows */ | 65 /** Constant value indicating if the current platform is Windows */ |
68 version(Windows){ | 66 private static final bool WINDOWS = java.io.File.separatorChar is '\\'; |
69 private static const bool WINDOWS = true; | |
70 } | |
71 else { | |
72 private static const bool WINDOWS = false; | |
73 } | |
74 | |
75 static this(){ | |
76 EMPTY = new Path(EMPTY_STRING); | |
77 ROOT = new Path(ROOT_STRING); | |
78 } | |
79 | 67 |
80 /** The device id string. May be null if there is no device. */ | 68 /** The device id string. May be null if there is no device. */ |
81 private String device = null; | 69 private String device = null; |
82 | 70 |
83 //Private implementation note: the segments and separators | 71 //Private implementation note: the segments and separators |
84 //arrays are never modified, so that they can be shared between | 72 //arrays are never modified, so that they can be shared between |
85 //path instances | 73 //path instances |
86 | 74 |
87 /** The path segments */ | 75 /** The path segments */ |
88 private String[] segments_; | 76 private String[] segments; |
89 | 77 |
90 /** flags indicating separators (has leading, is UNC, has trailing) */ | 78 /** flags indicating separators (has leading, is UNC, has trailing) */ |
91 private int separators; | 79 private int separators; |
92 | 80 |
93 /** | 81 /** |
94 * Constructs a new path from the given string path. | 82 * Constructs a new path from the given string path. |
95 * The string path must represent a valid file system path | 83 * The string path must represent a valid file system path |
96 * on the local file system. | 84 * on the local file system. |
97 * The path is canonicalized and double slashes are removed | 85 * The path is canonicalized and double slashes are removed |
98 * except at the beginning. (to handle UNC paths). All forward | 86 * except at the beginning. (to handle UNC paths). All forward |
99 * slashes ('/') are treated as segment delimiters, and any | 87 * slashes ('/') are treated as segment delimiters, and any |
100 * segment and device delimiters for the local file system are | 88 * segment and device delimiters for the local file system are |
101 * also respected. | 89 * also respected. |
106 */ | 94 */ |
107 public static IPath fromOSString(String pathString) { | 95 public static IPath fromOSString(String pathString) { |
108 return new Path(pathString); | 96 return new Path(pathString); |
109 } | 97 } |
110 | 98 |
111 /** | 99 /** |
112 * Constructs a new path from the given path string. | 100 * Constructs a new path from the given path string. |
113 * The path string must have been produced by a previous | 101 * The path string must have been produced by a previous |
114 * call to <code>IPath.toPortableString</code>. | 102 * call to <code>IPath.toPortableString</code>. |
115 * | 103 * |
116 * @param pathString the portable path string | 104 * @param pathString the portable path string |
117 * @see IPath#toPortableString() | 105 * @see IPath#toPortableString() |
118 * @since 3.1 | 106 * @since 3.1 |
119 */ | 107 */ |
120 public static IPath fromPortableString(String pathString) { | 108 public static IPath fromPortableString(String pathString) { |
121 int firstMatch = pathString.indexOf(DEVICE_SEPARATOR) + 1; | 109 int firstMatch = pathString.indexOfcast(DEVICE_SEPARATOR) + 1; |
122 //no extra work required if no device characters | 110 //no extra work required if no device characters |
123 if (firstMatch <= 0) | 111 if (firstMatch <= 0) |
124 return (new Path()).initialize(null, pathString); | 112 return (new Path()).initialize(null, pathString); |
125 //if we find a single colon, then the path has a device | 113 //if we find a single colon, then the path has a device |
126 String devicePart = null; | 114 String devicePart = null; |
127 int pathLength = pathString.length; | 115 int pathLength = pathString.length(); |
128 if (firstMatch is pathLength || pathString.charAt(firstMatch) !is DEVICE_SEPARATOR) { | 116 if (firstMatch is pathLength || pathString.charAt(firstMatch) !is DEVICE_SEPARATOR) { |
129 devicePart = pathString.substring(0, firstMatch); | 117 devicePart = pathString.substring(0, firstMatch); |
130 pathString = pathString.substring(firstMatch, pathLength); | 118 pathString = pathString.substring(firstMatch, pathLength); |
131 } | 119 } |
132 //optimize for no colon literals | 120 //optimize for no colon literals |
133 if (pathString.indexOf(DEVICE_SEPARATOR) is -1) | 121 if (pathString.indexOfcast(DEVICE_SEPARATOR) is -1) |
134 return (new Path()).initialize(devicePart, pathString); | 122 return (new Path()).initialize(devicePart, pathString); |
135 //contract colon literals | 123 //contract colon literals |
136 char[] chars = pathString/+.toCharArray()+/; | 124 char[] chars = pathString.toCharArray(); |
137 int readOffset = 0, writeOffset = 0, length = chars.length; | 125 int readOffset = 0, writeOffset = 0, length = chars.length; |
138 while (readOffset < length) { | 126 while (readOffset < length) { |
139 if (chars[readOffset] is DEVICE_SEPARATOR) | 127 if (chars[readOffset] is DEVICE_SEPARATOR) |
140 if (++readOffset >= length) | 128 if (++readOffset >= length) |
141 break; | 129 break; |
142 chars[writeOffset++] = chars[readOffset++]; | 130 chars[writeOffset++] = chars[readOffset++]; |
143 } | 131 } |
144 return (new Path()).initialize(devicePart, chars[ 0 .. writeOffset] ); | 132 return (new Path()).initialize(devicePart, new String(chars, 0, writeOffset)); |
145 } | 133 } |
146 | 134 |
147 /* (Intentionally not included in javadoc) | 135 /* (Intentionally not included in javadoc) |
148 * Private constructor. | 136 * Private constructor. |
149 */ | 137 */ |
150 private this() { | 138 private this() { |
151 // not allowed | 139 // not allowed |
152 } | 140 } |
153 | 141 |
154 /** | 142 /** |
155 * Constructs a new path from the given string path. | 143 * Constructs a new path from the given string path. |
156 * The string path must represent a valid file system path | 144 * The string path must represent a valid file system path |
157 * on the local file system. | 145 * on the local file system. |
158 * The path is canonicalized and double slashes are removed | 146 * The path is canonicalized and double slashes are removed |
159 * except at the beginning. (to handle UNC paths). All forward | 147 * except at the beginning. (to handle UNC paths). All forward |
160 * slashes ('/') are treated as segment delimiters, and any | 148 * slashes ('/') are treated as segment delimiters, and any |
161 * segment and device delimiters for the local file system are | 149 * segment and device delimiters for the local file system are |
162 * also respected (such as colon (':') and backslash ('\') on some file systems). | 150 * also respected (such as colon (':') and backslash ('\') on some file systems). |
168 String devicePart = null; | 156 String devicePart = null; |
169 if (WINDOWS) { | 157 if (WINDOWS) { |
170 //convert backslash to forward slash | 158 //convert backslash to forward slash |
171 fullPath = fullPath.indexOf('\\') is -1 ? fullPath : fullPath.replace('\\', SEPARATOR); | 159 fullPath = fullPath.indexOf('\\') is -1 ? fullPath : fullPath.replace('\\', SEPARATOR); |
172 //extract device | 160 //extract device |
173 int i = fullPath.indexOf(DEVICE_SEPARATOR); | 161 int i = fullPath.indexOfcast(DEVICE_SEPARATOR); |
174 if (i !is -1) { | 162 if (i !is -1) { |
175 //remove leading slash from device part to handle output of URL.getFile() | 163 //remove leading slash from device part to handle output of URL.getFile() |
176 int start = fullPath.charAt(0) is SEPARATOR ? 1 : 0; | 164 int start = fullPath.charAt(0) is SEPARATOR ? 1 : 0; |
177 devicePart = fullPath.substring(start, i + 1); | 165 devicePart = fullPath.substring(start, i + 1); |
178 fullPath = fullPath.substring(i + 1, fullPath.length); | 166 fullPath = fullPath.substring(i + 1, fullPath.length()); |
179 } | 167 } |
180 } | 168 } |
181 initialize(devicePart, fullPath); | 169 initialize(devicePart, fullPath); |
182 } | 170 } |
183 | 171 |
184 /** | 172 /** |
185 * Constructs a new path from the given device id and string path. | 173 * Constructs a new path from the given device id and string path. |
186 * The given string path must be valid. | 174 * The given string path must be valid. |
187 * The path is canonicalized and double slashes are removed except | 175 * The path is canonicalized and double slashes are removed except |
188 * at the beginning (to handle UNC paths). All forward | 176 * at the beginning (to handle UNC paths). All forward |
189 * slashes ('/') are treated as segment delimiters, and any | 177 * slashes ('/') are treated as segment delimiters, and any |
204 } | 192 } |
205 | 193 |
206 /* (Intentionally not included in javadoc) | 194 /* (Intentionally not included in javadoc) |
207 * Private constructor. | 195 * Private constructor. |
208 */ | 196 */ |
209 private this(String device, String[] segments_, int _separators) { | 197 private this(String device, String[] segments, int _separators) { |
210 // no segment validations are done for performance reasons | 198 // no segment validations are done for performance reasons |
211 this.segments_ = segments_; | 199 this.segments = segments; |
212 this.device = device; | 200 this.device = device; |
213 //hash code is cached in all but the bottom three bits of the separators field | 201 //hash code is cached in all but the bottom three bits of the separators field |
214 this.separators = (computeHashCode() << 3) | (_separators & ALL_SEPARATORS); | 202 this.separators = (computeHashCode() << 3) | (_separators & ALL_SEPARATORS); |
215 } | 203 } |
216 | 204 |
218 * @see IPath#addFileExtension | 206 * @see IPath#addFileExtension |
219 */ | 207 */ |
220 public IPath addFileExtension(String extension) { | 208 public IPath addFileExtension(String extension) { |
221 if (isRoot() || isEmpty() || hasTrailingSeparator()) | 209 if (isRoot() || isEmpty() || hasTrailingSeparator()) |
222 return this; | 210 return this; |
223 int len = segments_.length; | 211 int len = segments.length; |
224 String[] newSegments = new String[len]; | 212 String[] newSegments = new String[len]; |
225 System.arraycopy(segments_, 0, newSegments, 0, len - 1); | 213 System.arraycopy(segments, 0, newSegments, 0, len - 1); |
226 newSegments[len - 1] = segments_[len - 1] ~ '.' ~ extension; | 214 newSegments[len - 1] = segments[len - 1] + '.' + extension; |
227 return new Path(device, newSegments, separators); | 215 return new Path(device, newSegments, separators); |
228 } | 216 } |
229 | 217 |
230 /* (Intentionally not included in javadoc) | 218 /* (Intentionally not included in javadoc) |
231 * @see IPath#addTrailingSeparator | 219 * @see IPath#addTrailingSeparator |
234 if (hasTrailingSeparator() || isRoot()) { | 222 if (hasTrailingSeparator() || isRoot()) { |
235 return this; | 223 return this; |
236 } | 224 } |
237 //XXX workaround, see 1GIGQ9V | 225 //XXX workaround, see 1GIGQ9V |
238 if (isEmpty()) { | 226 if (isEmpty()) { |
239 return new Path(device, segments_, HAS_LEADING); | 227 return new Path(device, segments, HAS_LEADING); |
240 } | 228 } |
241 return new Path(device, segments_, separators | HAS_TRAILING); | 229 return new Path(device, segments, separators | HAS_TRAILING); |
242 } | 230 } |
243 | 231 |
244 /* (Intentionally not included in javadoc) | 232 /* (Intentionally not included in javadoc) |
245 * @see IPath#append(IPath) | 233 * @see IPath#append(IPath) |
246 */ | 234 */ |
253 return tail.setDevice(device).makeRelative().makeUNC(isUNC()); | 241 return tail.setDevice(device).makeRelative().makeUNC(isUNC()); |
254 if (this.isRoot()) | 242 if (this.isRoot()) |
255 return tail.setDevice(device).makeAbsolute().makeUNC(isUNC()); | 243 return tail.setDevice(device).makeAbsolute().makeUNC(isUNC()); |
256 | 244 |
257 //concatenate the two segment arrays | 245 //concatenate the two segment arrays |
258 int myLen = segments_.length; | 246 int myLen = segments.length; |
259 int tailLen = tail.segmentCount(); | 247 int tailLen = tail.segmentCount(); |
260 String[] newSegments = new String[myLen + tailLen]; | 248 String[] newSegments = new String[myLen + tailLen]; |
261 System.arraycopy(segments_, 0, newSegments, 0, myLen); | 249 System.arraycopy(segments, 0, newSegments, 0, myLen); |
262 for (int i = 0; i < tailLen; i++) { | 250 for (int i = 0; i < tailLen; i++) { |
263 newSegments[myLen + i] = tail.segment(i); | 251 newSegments[myLen + i] = tail.segment(i); |
264 } | 252 } |
265 //use my leading separators and the tail's trailing separator | 253 //use my leading separators and the tail's trailing separator |
266 Path result = new Path(device, newSegments, (separators & (HAS_LEADING | IS_UNC)) | (tail.hasTrailingSeparator() ? HAS_TRAILING : 0)); | 254 Path result = new Path(device, newSegments, (separators & (HAS_LEADING | IS_UNC)) | (tail.hasTrailingSeparator() ? HAS_TRAILING : 0)); |
267 String tailFirstSegment = newSegments[myLen]; | 255 String tailFirstSegment = newSegments[myLen]; |
268 if (tailFirstSegment.equals("..") || tailFirstSegment.equals(".")) { //$NON-NLS-1$ //$NON-NLS-2$ | 256 if (tailFirstSegment.opEquals("..") || tailFirstSegment.opEquals(".")) { //$NON-NLS-1$ //$NON-NLS-2$ |
269 result.canonicalize(); | 257 result.canonicalize(); |
270 } | 258 } |
271 return result; | 259 return result; |
272 } | 260 } |
273 | 261 |
274 /* (Intentionally not included in javadoc) | 262 /* (Intentionally not included in javadoc) |
275 * @see IPath#append(java.lang.String) | 263 * @see IPath#append(java.lang.String) |
276 */ | 264 */ |
277 public IPath append(String tail) { | 265 public IPath append(String tail) { |
278 //optimize addition of a single segment | 266 //optimize addition of a single segment |
279 if (tail.indexOf(SEPARATOR) is -1 && tail.indexOf("\\") is -1 && tail.indexOf(DEVICE_SEPARATOR) is -1) { //$NON-NLS-1$ | 267 if (tail.indexOfcast(SEPARATOR) is -1 && tail.indexOf("\\") is -1 && tail.indexOfcast(DEVICE_SEPARATOR) is -1) { //$NON-NLS-1$ |
280 int tailLength = tail.length; | 268 int tailLength = tail.length(); |
281 if (tailLength < 3) { | 269 if (tailLength < 3) { |
282 //some special cases | 270 //some special cases |
283 if (tailLength is 0 || ".".equals(tail)) { //$NON-NLS-1$ | 271 if (tailLength is 0 || ".".opEquals(tail)) { //$NON-NLS-1$ |
284 return this; | 272 return this; |
285 } | 273 } |
286 if ("..".equals(tail)) //$NON-NLS-1$ | 274 if ("..".opEquals(tail)) //$NON-NLS-1$ |
287 return removeLastSegments(1); | 275 return removeLastSegments(1); |
288 } | 276 } |
289 //just add the segment | 277 //just add the segment |
290 int myLen = segments_.length; | 278 int myLen = segments.length; |
291 String[] newSegments = new String[myLen + 1]; | 279 String[] newSegments = new String[myLen + 1]; |
292 System.arraycopy(segments_, 0, newSegments, 0, myLen); | 280 System.arraycopy(segments, 0, newSegments, 0, myLen); |
293 newSegments[myLen] = tail; | 281 newSegments[myLen] = tail; |
294 return new Path(device, newSegments, separators & ~HAS_TRAILING); | 282 return new Path(device, newSegments, separators & ~HAS_TRAILING); |
295 } | 283 } |
296 //go with easy implementation | 284 //go with easy implementation |
297 return append(new Path(tail)); | 285 return append(new Path(tail)); |
306 * </p> | 294 * </p> |
307 * @return true if the path was modified, and false otherwise. | 295 * @return true if the path was modified, and false otherwise. |
308 */ | 296 */ |
309 private bool canonicalize() { | 297 private bool canonicalize() { |
310 //look for segments that need canonicalizing | 298 //look for segments that need canonicalizing |
311 for (int i = 0, max = segments_.length; i < max; i++) { | 299 for (int i = 0, max = segments.length; i < max; i++) { |
312 String segment = segments_[i]; | 300 String segment = segments[i]; |
313 if (segment.charAt(0) is '.' && (segment.equals("..") || segment.equals("."))) { //$NON-NLS-1$ //$NON-NLS-2$ | 301 if (segment.charAt(0) is '.' && (segment.opEquals("..") || segment.opEquals("."))) { //$NON-NLS-1$ //$NON-NLS-2$ |
314 //path needs to be canonicalized | 302 //path needs to be canonicalized |
315 collapseParentReferences(); | 303 collapseParentReferences(); |
316 //paths of length 0 have no trailing separator | 304 //paths of length 0 have no trailing separator |
317 if (segments_.length is 0) | 305 if (segments.length is 0) |
318 separators &= (HAS_LEADING | IS_UNC); | 306 separators &= (HAS_LEADING | IS_UNC); |
319 //recompute hash because canonicalize affects hash | 307 //recompute hash because canonicalize affects hash |
320 separators = (separators & ALL_SEPARATORS) | (computeHashCode() << 3); | 308 separators = (separators & ALL_SEPARATORS) | (computeHashCode() << 3); |
321 return true; | 309 return true; |
322 } | 310 } |
325 } | 313 } |
326 | 314 |
327 /* (Intentionally not included in javadoc) | 315 /* (Intentionally not included in javadoc) |
328 * Clones this object. | 316 * Clones this object. |
329 */ | 317 */ |
330 public Path clone() { | 318 public Object clone() { |
331 return new Path(device, segments_, separators); | 319 try { |
320 return super.clone(); | |
321 } catch (CloneNotSupportedException e) { | |
322 return null; | |
323 } | |
332 } | 324 } |
333 | 325 |
334 /** | 326 /** |
335 * Destructively removes all occurrences of ".." segments from this path. | 327 * Destructively removes all occurrences of ".." segments from this path. |
336 */ | 328 */ |
337 private void collapseParentReferences() { | 329 private void collapseParentReferences() { |
338 int segmentCount = segments_.length; | 330 int segmentCount = segments.length; |
339 String[] stack = new String[segmentCount]; | 331 String[] stack = new String[segmentCount]; |
340 int stackPointer = 0; | 332 int stackPointer = 0; |
341 for (int i = 0; i < segmentCount; i++) { | 333 for (int i = 0; i < segmentCount; i++) { |
342 String segment = segments_[i]; | 334 String segment = segments[i]; |
343 if (segment.equals("..")) { //$NON-NLS-1$ | 335 if (segment.opEquals("..")) { //$NON-NLS-1$ |
344 if (stackPointer is 0) { | 336 if (stackPointer is 0) { |
345 // if the stack is empty we are going out of our scope | 337 // if the stack is empty we are going out of our scope |
346 // so we need to accumulate segments. But only if the original | 338 // so we need to accumulate segments. But only if the original |
347 // path is relative. If it is absolute then we can't go any higher than | 339 // path is relative. If it is absolute then we can't go any higher than |
348 // root so simply toss the .. references. | 340 // root so simply toss the .. references. |
349 if (!isAbsolute()) | 341 if (!isAbsolute()) |
350 stack[stackPointer++] = segment; //stack push | 342 stack[stackPointer++] = segment; //stack push |
351 } else { | 343 } else { |
352 // if the top is '..' then we are accumulating segments so don't pop | 344 // if the top is '..' then we are accumulating segments so don't pop |
353 if ("..".equals(stack[stackPointer - 1])) //$NON-NLS-1$ | 345 if ("..".opEquals(stack[stackPointer - 1])) //$NON-NLS-1$ |
354 stack[stackPointer++] = ".."; //$NON-NLS-1$ | 346 stack[stackPointer++] = ".."; //$NON-NLS-1$ |
355 else | 347 else |
356 stackPointer--; | 348 stackPointer--; |
357 //stack pop | 349 //stack pop |
358 } | 350 } |
359 //collapse current references | 351 //collapse current references |
360 } else if (!segment.equals(".") || segmentCount is 1) //$NON-NLS-1$ | 352 } else if (!segment.opEquals(".") || segmentCount is 1) //$NON-NLS-1$ |
361 stack[stackPointer++] = segment; //stack push | 353 stack[stackPointer++] = segment; //stack push |
362 } | 354 } |
363 //if the number of segments hasn't changed, then no modification needed | 355 //if the number of segments hasn't changed, then no modification needed |
364 if (stackPointer is segmentCount) | 356 if (stackPointer is segmentCount) |
365 return; | 357 return; |
366 //build the new segment array backwards by popping the stack | 358 //build the new segment array backwards by popping the stack |
367 String[] newSegments = new String[stackPointer]; | 359 String[] newSegments = new String[stackPointer]; |
368 System.arraycopy(stack, 0, newSegments, 0, stackPointer); | 360 System.arraycopy(stack, 0, newSegments, 0, stackPointer); |
369 this.segments_ = newSegments; | 361 this.segments = newSegments; |
370 } | 362 } |
371 | 363 |
372 /** | 364 /** |
373 * Removes duplicate slashes from the given path, with the exception | 365 * Removes duplicate slashes from the given path, with the exception |
374 * of leading double slash which represents a UNC path. | 366 * of leading double slash which represents a UNC path. |
375 */ | 367 */ |
376 private String collapseSlashes(String path) { | 368 private String collapseSlashes(String path) { |
377 int length = path.length; | 369 int length = path.length(); |
378 // if the path is only 0, 1 or 2 chars long then it could not possibly have illegal | 370 // if the path is only 0, 1 or 2 chars long then it could not possibly have illegal |
379 // duplicate slashes. | 371 // duplicate slashes. |
380 if (length < 3) | 372 if (length < 3) |
381 return path; | 373 return path; |
382 // check for an occurrence of // in the path. Start at index 1 to ensure we skip leading UNC // | 374 // check for an occurrence of // in the path. Start at index 1 to ensure we skip leading UNC // |
383 // If there are no // then there is nothing to collapse so just return. | 375 // If there are no // then there is nothing to collapse so just return. |
384 if (path.indexOf("//", 1) is -1) //$NON-NLS-1$ | 376 if (path.indexOf("//", 1) is -1) //$NON-NLS-1$ |
385 return path; | 377 return path; |
386 // We found an occurrence of // in the path so do the slow collapse. | 378 // We found an occurrence of // in the path so do the slow collapse. |
387 char[] result = new char[path.length]; | 379 char[] result = new char[path.length()]; |
388 int count = 0; | 380 int count = 0; |
389 bool hasPrevious = false; | 381 bool hasPrevious = false; |
390 char[] characters = path/+.toCharArray()+/; | 382 char[] characters = path.toCharArray(); |
391 for (int index = 0; index < characters.length; index++) { | 383 for (int index = 0; index < characters.length; index++) { |
392 char c = characters[index]; | 384 char c = characters[index]; |
393 if (c is SEPARATOR) { | 385 if (c is SEPARATOR) { |
394 if (hasPrevious) { | 386 if (hasPrevious) { |
395 // skip double slashes, except for beginning of UNC. | 387 // skip double slashes, except for beginning of UNC. |
407 hasPrevious = false; | 399 hasPrevious = false; |
408 result[count] = c; | 400 result[count] = c; |
409 count++; | 401 count++; |
410 } | 402 } |
411 } | 403 } |
412 return result[ 0 .. count]; | 404 return new String(result, 0, count); |
413 } | 405 } |
414 | 406 |
415 /* (Intentionally not included in javadoc) | 407 /* (Intentionally not included in javadoc) |
416 * Computes the hash code for this object. | 408 * Computes the hash code for this object. |
417 */ | 409 */ |
418 private int computeHashCode() { | 410 private int computeHashCode() { |
419 int hash = device.length is 0 ? 17 : java.lang.all.toHash(device); | 411 int hash = device is null ? 17 : device.toHash(); |
420 int segmentCount = segments_.length; | 412 int segmentCount = segments.length; |
421 for (int i = 0; i < segmentCount; i++) { | 413 for (int i = 0; i < segmentCount; i++) { |
422 //this function tends to given a fairly even distribution | 414 //this function tends to given a fairly even distribution |
423 hash = hash * 37 + java.lang.all.toHash(segments_[i]); | 415 hash = hash * 37 + segments[i].toHash(); |
424 } | 416 } |
425 return hash; | 417 return hash; |
426 } | 418 } |
427 | 419 |
428 /* (Intentionally not included in javadoc) | 420 /* (Intentionally not included in javadoc) |
429 * Returns the size of the string that will be created by toString or toOSString. | 421 * Returns the size of the string that will be created by toString or toOSString. |
430 */ | 422 */ |
431 private int computeLength() { | 423 private int computeLength() { |
432 int length = 0; | 424 int length = 0; |
433 if (device !is null) | 425 if (device !is null) |
434 length += device.length; | 426 length += device.length(); |
435 if ((separators & HAS_LEADING) !is 0) | 427 if ((separators & HAS_LEADING) !is 0) |
436 length++; | 428 length++; |
437 if ((separators & IS_UNC) !is 0) | 429 if ((separators & IS_UNC) !is 0) |
438 length++; | 430 length++; |
439 //add the segment lengths | 431 //add the segment lengths |
440 int max = segments_.length; | 432 int max = segments.length; |
441 if (max > 0) { | 433 if (max > 0) { |
442 for (int i = 0; i < max; i++) { | 434 for (int i = 0; i < max; i++) { |
443 length += segments_[i].length; | 435 length += segments[i].length(); |
444 } | 436 } |
445 //add the separator lengths | 437 //add the separator lengths |
446 length += max - 1; | 438 length += max - 1; |
447 } | 439 } |
448 if ((separators & HAS_TRAILING) !is 0) | 440 if ((separators & HAS_TRAILING) !is 0) |
452 | 444 |
453 /* (Intentionally not included in javadoc) | 445 /* (Intentionally not included in javadoc) |
454 * Returns the number of segments in the given path | 446 * Returns the number of segments in the given path |
455 */ | 447 */ |
456 private int computeSegmentCount(String path) { | 448 private int computeSegmentCount(String path) { |
457 int len = path.length; | 449 int len = path.length(); |
458 if (len is 0 || (len is 1 && path.charAt(0) is SEPARATOR)) { | 450 if (len is 0 || (len is 1 && path.charAt(0) is SEPARATOR)) { |
459 return 0; | 451 return 0; |
460 } | 452 } |
461 int count = 1; | 453 int count = 1; |
462 int prev = -1; | 454 int prev = -1; |
480 // performance sensitive --- avoid creating garbage | 472 // performance sensitive --- avoid creating garbage |
481 int segmentCount = computeSegmentCount(path); | 473 int segmentCount = computeSegmentCount(path); |
482 if (segmentCount is 0) | 474 if (segmentCount is 0) |
483 return NO_SEGMENTS; | 475 return NO_SEGMENTS; |
484 String[] newSegments = new String[segmentCount]; | 476 String[] newSegments = new String[segmentCount]; |
485 int len = path.length; | 477 int len = path.length(); |
486 // check for initial slash | 478 // check for initial slash |
487 int firstPosition = (path.charAt(0) is SEPARATOR) ? 1 : 0; | 479 int firstPosition = (path.charAt(0) is SEPARATOR) ? 1 : 0; |
488 // check for UNC | 480 // check for UNC |
489 if (firstPosition is 1 && len > 1 && (path.charAt(1) is SEPARATOR)) | 481 if (firstPosition is 1 && len > 1 && (path.charAt(1) is SEPARATOR)) |
490 firstPosition = 2; | 482 firstPosition = 2; |
491 int lastPosition = (path.charAt(len - 1) !is SEPARATOR) ? len - 1 : len - 2; | 483 int lastPosition = (path.charAt(len - 1) !is SEPARATOR) ? len - 1 : len - 2; |
492 // for non-empty paths, the number of segments is | 484 // for non-empty paths, the number of segments is |
493 // the number of slashes plus 1, ignoring any leading | 485 // the number of slashes plus 1, ignoring any leading |
494 // and trailing slashes | 486 // and trailing slashes |
495 int next = firstPosition; | 487 int next = firstPosition; |
496 for (int i = 0; i < segmentCount; i++) { | 488 for (int i = 0; i < segmentCount; i++) { |
497 int start = next; | 489 int start = next; |
509 /** | 501 /** |
510 * Returns the platform-neutral encoding of the given segment onto | 502 * Returns the platform-neutral encoding of the given segment onto |
511 * the given string buffer. This escapes literal colon characters with double colons. | 503 * the given string buffer. This escapes literal colon characters with double colons. |
512 */ | 504 */ |
513 private void encodeSegment(String string, StringBuffer buf) { | 505 private void encodeSegment(String string, StringBuffer buf) { |
514 int len = string.length; | 506 int len = string.length(); |
515 for (int i = 0; i < len; i++) { | 507 for (int i = 0; i < len; i++) { |
516 char c = string.charAt(i); | 508 char c = string.charAt(i); |
517 buf.append(c); | 509 buf.append(c); |
518 if (c is DEVICE_SEPARATOR) | 510 if (c is DEVICE_SEPARATOR) |
519 buf.append(DEVICE_SEPARATOR); | 511 buf.appendcast(DEVICE_SEPARATOR); |
520 } | 512 } |
521 } | 513 } |
522 | 514 |
523 /* (Intentionally not included in javadoc) | 515 /* (Intentionally not included in javadoc) |
524 * Compares objects for equality. | 516 * Compares objects for equality. |
525 */ | 517 */ |
526 public override int opEquals(Object obj) { | 518 public override equals_t opEquals(Object obj) { |
527 if (this is obj) | 519 if (this is obj) |
528 return true; | 520 return true; |
529 if (!(cast(Path)obj)) | 521 if (!( null !is cast(Path)obj )) |
530 return false; | 522 return false; |
531 Path target = cast(Path) obj; | 523 Path target = cast(Path) obj; |
532 //check leading separators and hash code | 524 //check leading separators and hash code |
533 if ((separators & HASH_MASK) !is (target.separators & HASH_MASK)) | 525 if ((separators & HASH_MASK) !is (target.separators & HASH_MASK)) |
534 return false; | 526 return false; |
535 String[] targetSegments = target.segments_; | 527 String[] targetSegments = target.segments; |
536 int i = segments_.length; | 528 int i = segments.length; |
537 //check segment count | 529 //check segment count |
538 if (i !is targetSegments.length) | 530 if (i !is targetSegments.length) |
539 return false; | 531 return false; |
540 //check segments in reverse order - later segments more likely to differ | 532 //check segments in reverse order - later segments more likely to differ |
541 while (--i >= 0) | 533 while (--i >= 0) |
542 if (!segments_[i].equals(targetSegments[i])) | 534 if (!segments[i].opEquals(targetSegments[i])) |
543 return false; | 535 return false; |
544 //check device last (least likely to differ) | 536 //check device last (least likely to differ) |
545 return device is target.device || (device !is null && device.equals(target.device)); | 537 return device is target.device || (device !is null && device.opEquals(target.device)); |
546 } | 538 } |
547 | 539 |
548 /* (Intentionally not included in javadoc) | 540 /* (Intentionally not included in javadoc) |
549 * @see IPath#getDevice | 541 * @see IPath#getDevice |
550 */ | 542 */ |
586 | 578 |
587 /* | 579 /* |
588 * Initialize the current path with the given string. | 580 * Initialize the current path with the given string. |
589 */ | 581 */ |
590 private IPath initialize(String deviceString, String path) { | 582 private IPath initialize(String deviceString, String path) { |
591 //Assert.isNotNull(path); // allow for SWT | 583 Assert.isNotNull(path); |
592 this.device = deviceString; | 584 this.device = deviceString; |
593 | 585 |
594 path = collapseSlashes(path); | 586 path = collapseSlashes(path); |
595 int len = path.length; | 587 int len = path.length(); |
596 | 588 |
597 //compute the separators array | 589 //compute the separators array |
598 if (len < 2) { | 590 if (len < 2) { |
599 if (len is 1 && path.charAt(0) is SEPARATOR) { | 591 if (len is 1 && path.charAt(0) is SEPARATOR) { |
600 this.separators = HAS_LEADING; | 592 this.separators = HAS_LEADING; |
611 separators |= IS_UNC; | 603 separators |= IS_UNC; |
612 if (hasTrailing) | 604 if (hasTrailing) |
613 separators |= HAS_TRAILING; | 605 separators |= HAS_TRAILING; |
614 } | 606 } |
615 //compute segments and ensure canonical form | 607 //compute segments and ensure canonical form |
616 segments_ = computeSegments(path); | 608 segments = computeSegments(path); |
617 if (!canonicalize()) { | 609 if (!canonicalize()) { |
618 //compute hash now because canonicalize didn't need to do it | 610 //compute hash now because canonicalize didn't need to do it |
619 separators = (separators & ALL_SEPARATORS) | (computeHashCode() << 3); | 611 separators = (separators & ALL_SEPARATORS) | (computeHashCode() << 3); |
620 } | 612 } |
621 return this; | 613 return this; |
632 /* (Intentionally not included in javadoc) | 624 /* (Intentionally not included in javadoc) |
633 * @see IPath#isEmpty | 625 * @see IPath#isEmpty |
634 */ | 626 */ |
635 public bool isEmpty() { | 627 public bool isEmpty() { |
636 //true if no segments and no leading prefix | 628 //true if no segments and no leading prefix |
637 return segments_.length is 0 && ((separators & ALL_SEPARATORS) !is HAS_LEADING); | 629 return segments.length is 0 && ((separators & ALL_SEPARATORS) !is HAS_LEADING); |
638 | 630 |
639 } | 631 } |
640 | 632 |
641 /* (Intentionally not included in javadoc) | 633 /* (Intentionally not included in javadoc) |
642 * @see IPath#isPrefixOf | 634 * @see IPath#isPrefixOf |
652 } | 644 } |
653 } | 645 } |
654 if (isEmpty() || (isRoot() && anotherPath.isAbsolute())) { | 646 if (isEmpty() || (isRoot() && anotherPath.isAbsolute())) { |
655 return true; | 647 return true; |
656 } | 648 } |
657 int len = segments_.length; | 649 int len = segments.length; |
658 if (len > anotherPath.segmentCount()) { | 650 if (len > anotherPath.segmentCount()) { |
659 return false; | 651 return false; |
660 } | 652 } |
661 for (int i = 0; i < len; i++) { | 653 for (int i = 0; i < len; i++) { |
662 if (!segments_[i].equals(anotherPath.segment(i))) | 654 if (!segments[i].opEquals(anotherPath.segment(i))) |
663 return false; | 655 return false; |
664 } | 656 } |
665 return true; | 657 return true; |
666 } | 658 } |
667 | 659 |
668 /* (Intentionally not included in javadoc) | 660 /* (Intentionally not included in javadoc) |
669 * @see IPath#isRoot | 661 * @see IPath#isRoot |
670 */ | 662 */ |
671 public bool isRoot() { | 663 public bool isRoot() { |
672 //must have no segments, a leading separator, and not be a UNC path. | 664 //must have no segments, a leading separator, and not be a UNC path. |
673 return this is ROOT || (segments_.length is 0 && ((separators & ALL_SEPARATORS) is HAS_LEADING)); | 665 return this is ROOT || (segments.length is 0 && ((separators & ALL_SEPARATORS) is HAS_LEADING)); |
674 } | 666 } |
675 | 667 |
676 /* (Intentionally not included in javadoc) | 668 /* (Intentionally not included in javadoc) |
677 * @see IPath#isUNC | 669 * @see IPath#isUNC |
678 */ | 670 */ |
695 | 687 |
696 /* (Intentionally not included in javadoc) | 688 /* (Intentionally not included in javadoc) |
697 * @see IPath#isValidSegment(String) | 689 * @see IPath#isValidSegment(String) |
698 */ | 690 */ |
699 public bool isValidSegment(String segment) { | 691 public bool isValidSegment(String segment) { |
700 int size = segment.length; | 692 int size = segment.length(); |
701 if (size is 0) | 693 if (size is 0) |
702 return false; | 694 return false; |
703 for (int i = 0; i < size; i++) { | 695 for (int i = 0; i < size; i++) { |
704 char c = segment.charAt(i); | 696 char c = segment.charAt(i); |
705 if (c is '/') | 697 if (c is '/') |
712 | 704 |
713 /* (Intentionally not included in javadoc) | 705 /* (Intentionally not included in javadoc) |
714 * @see IPath#lastSegment() | 706 * @see IPath#lastSegment() |
715 */ | 707 */ |
716 public String lastSegment() { | 708 public String lastSegment() { |
717 int len = segments_.length; | 709 int len = segments.length; |
718 return len is 0 ? null : segments_[len - 1]; | 710 return len is 0 ? null : segments[len - 1]; |
719 } | 711 } |
720 | 712 |
721 /* (Intentionally not included in javadoc) | 713 /* (Intentionally not included in javadoc) |
722 * @see IPath#makeAbsolute() | 714 * @see IPath#makeAbsolute() |
723 */ | 715 */ |
724 public IPath makeAbsolute() { | 716 public IPath makeAbsolute() { |
725 if (isAbsolute()) { | 717 if (isAbsolute()) { |
726 return this; | 718 return this; |
727 } | 719 } |
728 Path result = new Path(device, segments_, separators | HAS_LEADING); | 720 Path result = new Path(device, segments, separators | HAS_LEADING); |
729 //may need canonicalizing if it has leading ".." or "." segments | 721 //may need canonicalizing if it has leading ".." or "." segments |
730 if (result.segmentCount() > 0) { | 722 if (result.segmentCount() > 0) { |
731 String first = result.segment(0); | 723 String first = result.segment(0); |
732 if (first.equals("..") || first.equals(".")) { //$NON-NLS-1$ //$NON-NLS-2$ | 724 if (first.opEquals("..") || first.opEquals(".")) { //$NON-NLS-1$ //$NON-NLS-2$ |
733 result.canonicalize(); | 725 result.canonicalize(); |
734 } | 726 } |
735 } | 727 } |
736 return result; | 728 return result; |
737 } | 729 } |
741 */ | 733 */ |
742 public IPath makeRelative() { | 734 public IPath makeRelative() { |
743 if (!isAbsolute()) { | 735 if (!isAbsolute()) { |
744 return this; | 736 return this; |
745 } | 737 } |
746 return new Path(device, segments_, separators & HAS_TRAILING); | 738 return new Path(device, segments, separators & HAS_TRAILING); |
747 } | 739 } |
748 | 740 |
749 /* (Intentionally not included in javadoc) | 741 /* (Intentionally not included in javadoc) |
750 * @see IPath#makeUNC(bool) | 742 * @see IPath#makeUNC(boolean) |
751 */ | 743 */ |
752 public IPath makeUNC(bool toUNC) { | 744 public IPath makeUNC(bool toUNC) { |
753 // if we are already in the right form then just return | 745 // if we are already in the right form then just return |
754 if (!(toUNC ^ isUNC())) | 746 if (!(toUNC ^ isUNC())) |
755 return this; | 747 return this; |
759 newSeparators |= HAS_LEADING | IS_UNC; | 751 newSeparators |= HAS_LEADING | IS_UNC; |
760 } else { | 752 } else { |
761 //mask out the UNC bit | 753 //mask out the UNC bit |
762 newSeparators &= HAS_LEADING | HAS_TRAILING; | 754 newSeparators &= HAS_LEADING | HAS_TRAILING; |
763 } | 755 } |
764 return new Path(toUNC ? null : device, segments_, newSeparators); | 756 return new Path(toUNC ? null : device, segments, newSeparators); |
765 } | 757 } |
766 | 758 |
767 /* (Intentionally not included in javadoc) | 759 /* (Intentionally not included in javadoc) |
768 * @see IPath#matchingFirstSegments(IPath) | 760 * @see IPath#matchingFirstSegments(IPath) |
769 */ | 761 */ |
770 public int matchingFirstSegments(IPath anotherPath) { | 762 public int matchingFirstSegments(IPath anotherPath) { |
771 Assert.isNotNull( cast(Object) anotherPath); | 763 Assert.isNotNull(anotherPath); |
772 int anotherPathLen = anotherPath.segmentCount(); | 764 int anotherPathLen = anotherPath.segmentCount(); |
773 int max = Math.min(segments_.length, anotherPathLen); | 765 int max = Math.min(segments.length, anotherPathLen); |
774 int count = 0; | 766 int count = 0; |
775 for (int i = 0; i < max; i++) { | 767 for (int i = 0; i < max; i++) { |
776 if (!segments_[i].equals(anotherPath.segment(i))) { | 768 if (!segments[i].opEquals(anotherPath.segment(i))) { |
777 return count; | 769 return count; |
778 } | 770 } |
779 count++; | 771 count++; |
780 } | 772 } |
781 return count; | 773 return count; |
784 /* (Intentionally not included in javadoc) | 776 /* (Intentionally not included in javadoc) |
785 * @see IPath#removeFileExtension() | 777 * @see IPath#removeFileExtension() |
786 */ | 778 */ |
787 public IPath removeFileExtension() { | 779 public IPath removeFileExtension() { |
788 String extension = getFileExtension(); | 780 String extension = getFileExtension(); |
789 if (extension is null || extension.equals("")) { //$NON-NLS-1$ | 781 if (extension is null || extension.opEquals("")) { //$NON-NLS-1$ |
790 return this; | 782 return this; |
791 } | 783 } |
792 String lastSegment = lastSegment(); | 784 String lastSegment = lastSegment(); |
793 int index = lastSegment.lastIndexOf(extension) - 1; | 785 int index = lastSegment.lastIndexOf(extension) - 1; |
794 return removeLastSegments(1).append(lastSegment.substring(0, index)); | 786 return removeLastSegments(1).append(lastSegment.substring(0, index)); |
798 * @see IPath#removeFirstSegments(int) | 790 * @see IPath#removeFirstSegments(int) |
799 */ | 791 */ |
800 public IPath removeFirstSegments(int count) { | 792 public IPath removeFirstSegments(int count) { |
801 if (count is 0) | 793 if (count is 0) |
802 return this; | 794 return this; |
803 if (count >= segments_.length) { | 795 if (count >= segments.length) { |
804 return new Path(device, NO_SEGMENTS, 0); | 796 return new Path(device, NO_SEGMENTS, 0); |
805 } | 797 } |
806 Assert.isLegal(count > 0); | 798 Assert.isLegal(count > 0); |
807 int newSize = segments_.length - count; | 799 int newSize = segments.length - count; |
808 String[] newSegments = new String[newSize]; | 800 String[] newSegments = new String[newSize]; |
809 System.arraycopy(this.segments_, count, newSegments, 0, newSize); | 801 System.arraycopy(this.segments, count, newSegments, 0, newSize); |
810 | 802 |
811 //result is always a relative path | 803 //result is always a relative path |
812 return new Path(device, newSegments, separators & HAS_TRAILING); | 804 return new Path(device, newSegments, separators & HAS_TRAILING); |
813 } | 805 } |
814 | 806 |
816 * @see IPath#removeLastSegments(int) | 808 * @see IPath#removeLastSegments(int) |
817 */ | 809 */ |
818 public IPath removeLastSegments(int count) { | 810 public IPath removeLastSegments(int count) { |
819 if (count is 0) | 811 if (count is 0) |
820 return this; | 812 return this; |
821 if (count >= segments_.length) { | 813 if (count >= segments.length) { |
822 //result will have no trailing separator | 814 //result will have no trailing separator |
823 return new Path(device, NO_SEGMENTS, separators & (HAS_LEADING | IS_UNC)); | 815 return new Path(device, NO_SEGMENTS, separators & (HAS_LEADING | IS_UNC)); |
824 } | 816 } |
825 Assert.isLegal(count > 0); | 817 Assert.isLegal(count > 0); |
826 int newSize = segments_.length - count; | 818 int newSize = segments.length - count; |
827 String[] newSegments = new String[newSize]; | 819 String[] newSegments = new String[newSize]; |
828 System.arraycopy(this.segments_, 0, newSegments, 0, newSize); | 820 System.arraycopy(this.segments, 0, newSegments, 0, newSize); |
829 return new Path(device, newSegments, separators); | 821 return new Path(device, newSegments, separators); |
830 } | 822 } |
831 | 823 |
832 /* (Intentionally not included in javadoc) | 824 /* (Intentionally not included in javadoc) |
833 * @see IPath#removeTrailingSeparator() | 825 * @see IPath#removeTrailingSeparator() |
834 */ | 826 */ |
835 public IPath removeTrailingSeparator() { | 827 public IPath removeTrailingSeparator() { |
836 if (!hasTrailingSeparator()) { | 828 if (!hasTrailingSeparator()) { |
837 return this; | 829 return this; |
838 } | 830 } |
839 return new Path(device, segments_, separators & (HAS_LEADING | IS_UNC)); | 831 return new Path(device, segments, separators & (HAS_LEADING | IS_UNC)); |
840 } | 832 } |
841 | 833 |
842 /* (Intentionally not included in javadoc) | 834 /* (Intentionally not included in javadoc) |
843 * @see IPath#segment(int) | 835 * @see IPath#segment(int) |
844 */ | 836 */ |
845 public String segment(int index) { | 837 public String segment(int index) { |
846 if (index >= segments_.length) | 838 if (index >= segments.length) |
847 return null; | 839 return null; |
848 return segments_[index]; | 840 return segments[index]; |
849 } | 841 } |
850 | 842 |
851 /* (Intentionally not included in javadoc) | 843 /* (Intentionally not included in javadoc) |
852 * @see IPath#segmentCount() | 844 * @see IPath#segmentCount() |
853 */ | 845 */ |
854 public int segmentCount() { | 846 public int segmentCount() { |
855 return segments_.length; | 847 return segments.length; |
856 } | 848 } |
857 | 849 |
858 /* (Intentionally not included in javadoc) | 850 /* (Intentionally not included in javadoc) |
859 * @see IPath#segments() | 851 * @see IPath#segments() |
860 */ | 852 */ |
861 public String[] segments() { | 853 public String[] segments() { |
862 String[] segmentCopy = new String[](segments_.length); | 854 String[] segmentCopy = new String[segments.length]; |
863 System.arraycopy(segments_, 0, segmentCopy, 0, segments_.length); | 855 System.arraycopy(segments, 0, segmentCopy, 0, segments.length); |
864 return segmentCopy; | 856 return segmentCopy; |
865 } | 857 } |
866 | 858 |
867 /* (Intentionally not included in javadoc) | 859 /* (Intentionally not included in javadoc) |
868 * @see IPath#setDevice(String) | 860 * @see IPath#setDevice(String) |
869 */ | 861 */ |
870 public IPath setDevice(String value) { | 862 public IPath setDevice(String value) { |
871 if (value !is null) { | 863 if (value !is null) { |
872 Assert.isTrue(value.indexOf(IPath.DEVICE_SEPARATOR) is (value.length - 1), "Last character should be the device separator"); //$NON-NLS-1$ | 864 Assert.isTrue(value.indexOfcast(IPath.DEVICE_SEPARATOR) is (value.length() - 1), "Last character should be the device separator"); //$NON-NLS-1$ |
873 } | 865 } |
874 //return the receiver if the device is the same | 866 //return the receiver if the device is the same |
875 if (value is device || (value !is null && value.equals(device))) | 867 if (value is device || (value !is null && value.opEquals(device))) |
876 return this; | 868 return this; |
877 | 869 |
878 return new Path(value, segments_, separators); | 870 return new Path(value, segments, separators); |
879 } | 871 } |
880 | 872 |
881 /* (Intentionally not included in javadoc) | 873 /* (Intentionally not included in javadoc) |
882 * @see IPath#toFile() | 874 * @see IPath#toFile() |
883 */ | 875 */ |
884 public FilePath toFile() { | 876 public File toFile() { |
885 return new FilePath(tango.io.Path.standard(toOSString())); | 877 return new File(toOSString()); |
886 } | 878 } |
887 | 879 |
888 /* (Intentionally not included in javadoc) | 880 /* (Intentionally not included in javadoc) |
889 * @see IPath#toOSString() | 881 * @see IPath#toOSString() |
890 */ | 882 */ |
892 //Note that this method is identical to toString except | 884 //Note that this method is identical to toString except |
893 //it uses the OS file separator instead of the path separator | 885 //it uses the OS file separator instead of the path separator |
894 int resultSize = computeLength(); | 886 int resultSize = computeLength(); |
895 if (resultSize <= 0) | 887 if (resultSize <= 0) |
896 return EMPTY_STRING; | 888 return EMPTY_STRING; |
897 char FILE_SEPARATOR = FileConst.PathSeparatorChar; | 889 char FILE_SEPARATOR = File.separatorChar; |
898 char[] result = new char[resultSize]; | 890 char[] result = new char[resultSize]; |
899 int offset = 0; | 891 int offset = 0; |
900 if (device !is null) { | 892 if (device !is null) { |
901 int size = device.length; | 893 int size = device.length(); |
902 device.getChars(0, size, result, offset); | 894 device.getChars(0, size, result, offset); |
903 offset += size; | 895 offset += size; |
904 } | 896 } |
905 if ((separators & HAS_LEADING) !is 0) | 897 if ((separators & HAS_LEADING) !is 0) |
906 result[offset++] = FILE_SEPARATOR; | 898 result[offset++] = FILE_SEPARATOR; |
907 if ((separators & IS_UNC) !is 0) | 899 if ((separators & IS_UNC) !is 0) |
908 result[offset++] = FILE_SEPARATOR; | 900 result[offset++] = FILE_SEPARATOR; |
909 int len = segments_.length - 1; | 901 int len = segments.length - 1; |
910 if (len >= 0) { | 902 if (len >= 0) { |
911 //append all but the last segment, with separators | 903 //append all but the last segment, with separators |
912 for (int i = 0; i < len; i++) { | 904 for (int i = 0; i < len; i++) { |
913 int size = segments_[i].length; | 905 int size = segments[i].length(); |
914 segments_[i].getChars(0, size, result, offset); | 906 segments[i].getChars(0, size, result, offset); |
915 offset += size; | 907 offset += size; |
916 result[offset++] = FILE_SEPARATOR; | 908 result[offset++] = FILE_SEPARATOR; |
917 } | 909 } |
918 //append the last segment | 910 //append the last segment |
919 int size = segments_[len].length; | 911 int size = segments[len].length(); |
920 segments_[len].getChars(0, size, result, offset); | 912 segments[len].getChars(0, size, result, offset); |
921 offset += size; | 913 offset += size; |
922 } | 914 } |
923 if ((separators & HAS_TRAILING) !is 0) | 915 if ((separators & HAS_TRAILING) !is 0) |
924 result[offset++] = FILE_SEPARATOR; | 916 result[offset++] = FILE_SEPARATOR; |
925 return result; | 917 return new String(result); |
926 } | 918 } |
927 | 919 |
928 /* (Intentionally not included in javadoc) | 920 /* (Intentionally not included in javadoc) |
929 * @see IPath#toPortableString() | 921 * @see IPath#toPortableString() |
930 */ | 922 */ |
934 return EMPTY_STRING; | 926 return EMPTY_STRING; |
935 StringBuffer result = new StringBuffer(resultSize); | 927 StringBuffer result = new StringBuffer(resultSize); |
936 if (device !is null) | 928 if (device !is null) |
937 result.append(device); | 929 result.append(device); |
938 if ((separators & HAS_LEADING) !is 0) | 930 if ((separators & HAS_LEADING) !is 0) |
939 result.append(SEPARATOR); | 931 result.appendcast(SEPARATOR); |
940 if ((separators & IS_UNC) !is 0) | 932 if ((separators & IS_UNC) !is 0) |
941 result.append(SEPARATOR); | 933 result.appendcast(SEPARATOR); |
942 int len = segments_.length; | 934 int len = segments.length; |
943 //append all segments with separators | 935 //append all segments with separators |
944 for (int i = 0; i < len; i++) { | 936 for (int i = 0; i < len; i++) { |
945 if (segments_[i].indexOf(DEVICE_SEPARATOR) >= 0) | 937 if (segments[i].indexOfcast(DEVICE_SEPARATOR) >= 0) |
946 encodeSegment(segments_[i], result); | 938 encodeSegment(segments[i], result); |
947 else | 939 else |
948 result.append(segments_[i]); | 940 result.append(segments[i]); |
949 if (i < len - 1 || (separators & HAS_TRAILING) !is 0) | 941 if (i < len - 1 || (separators & HAS_TRAILING) !is 0) |
950 result.append(SEPARATOR); | 942 result.appendcast(SEPARATOR); |
951 } | 943 } |
952 return result.toString(); | 944 return result.toString(); |
953 } | 945 } |
954 | 946 |
955 /* (Intentionally not included in javadoc) | 947 /* (Intentionally not included in javadoc) |
956 * @see IPath#toString() | 948 * @see IPath#toString() |
957 */ | 949 */ |
958 public override String toString() { | 950 public String toString() { |
959 int resultSize = computeLength(); | 951 int resultSize = computeLength(); |
960 if (resultSize <= 0) | 952 if (resultSize <= 0) |
961 return EMPTY_STRING; | 953 return EMPTY_STRING; |
962 char[] result = new char[resultSize]; | 954 char[] result = new char[resultSize]; |
963 int offset = 0; | 955 int offset = 0; |
964 if (device !is null) { | 956 if (device !is null) { |
965 int size = device.length; | 957 int size = device.length(); |
966 device.getChars(0, size, result, offset); | 958 device.getChars(0, size, result, offset); |
967 offset += size; | 959 offset += size; |
968 } | 960 } |
969 if ((separators & HAS_LEADING) !is 0) | 961 if ((separators & HAS_LEADING) !is 0) |
970 result[offset++] = SEPARATOR; | 962 result[offset++] = SEPARATOR; |
971 if ((separators & IS_UNC) !is 0) | 963 if ((separators & IS_UNC) !is 0) |
972 result[offset++] = SEPARATOR; | 964 result[offset++] = SEPARATOR; |
973 int len = segments_.length - 1; | 965 int len = segments.length - 1; |
974 if (len >= 0) { | 966 if (len >= 0) { |
975 //append all but the last segment, with separators | 967 //append all but the last segment, with separators |
976 for (int i = 0; i < len; i++) { | 968 for (int i = 0; i < len; i++) { |
977 int size = segments_[i].length; | 969 int size = segments[i].length(); |
978 segments_[i].getChars(0, size, result, offset); | 970 segments[i].getChars(0, size, result, offset); |
979 offset += size; | 971 offset += size; |
980 result[offset++] = SEPARATOR; | 972 result[offset++] = SEPARATOR; |
981 } | 973 } |
982 //append the last segment | 974 //append the last segment |
983 int size = segments_[len].length; | 975 int size = segments[len].length(); |
984 segments_[len].getChars(0, size, result, offset); | 976 segments[len].getChars(0, size, result, offset); |
985 offset += size; | 977 offset += size; |
986 } | 978 } |
987 if ((separators & HAS_TRAILING) !is 0) | 979 if ((separators & HAS_TRAILING) !is 0) |
988 result[offset++] = SEPARATOR; | 980 result[offset++] = SEPARATOR; |
989 return result; | 981 return new String(result); |
990 } | 982 } |
991 | 983 |
992 /* (Intentionally not included in javadoc) | 984 /* (Intentionally not included in javadoc) |
993 * @see IPath#uptoSegment(int) | 985 * @see IPath#uptoSegment(int) |
994 */ | 986 */ |
995 public IPath uptoSegment(int count) { | 987 public IPath uptoSegment(int count) { |
996 if (count is 0) | 988 if (count is 0) |
997 return new Path(device, NO_SEGMENTS, separators & (HAS_LEADING | IS_UNC)); | 989 return new Path(device, NO_SEGMENTS, separators & (HAS_LEADING | IS_UNC)); |
998 if (count >= segments_.length) | 990 if (count >= segments.length) |
999 return this; | 991 return this; |
1000 Assert.isTrue(count > 0, "Invalid parameter to Path.uptoSegment"); //$NON-NLS-1$ | 992 Assert.isTrue(count > 0, "Invalid parameter to Path.uptoSegment"); //$NON-NLS-1$ |
1001 String[] newSegments = new String[count]; | 993 String[] newSegments = new String[count]; |
1002 System.arraycopy(segments_, 0, newSegments, 0, count); | 994 System.arraycopy(segments, 0, newSegments, 0, count); |
1003 return new Path(device, newSegments, separators); | 995 return new Path(device, newSegments, separators); |
1004 } | 996 } |
1005 } | 997 } |