/** * Optimized constructor - no validations on segments are done. */ private Path(String[] segments, int separators) { // no segment validations are done for performance reasons this.segments = segments; // hash code is cached in all but the bottom three bits of the separators field this.separators = (computeHashCode() << USED_BITS) | (separators & ALL_SEPARATORS); }
/** * Destructively converts this path to its canonical form. * <p> * In its canonical form, a path does not have any "." segments, and parent references ("..") are collapsed where * possible. * * @return true if the path was modified, and false otherwise. */ private boolean canonicalize() { // look for segments that need canonicalizing for (int i = 0, max = segments.length; i < max; i++) { String segment = segments[i]; if (segment.charAt(0) == '.' && (segment.equals("..") || segment.equals("."))) { //$NON-NLS-1$ //$NON-NLS-2$ // path needs to be canonicalized collapseParentReferences(); // paths of length 0 have no trailing separator if (segments.length == 0) { separators &= HAS_LEADING; } // recompute hash because canonicalize affects hash separators = (separators & ALL_SEPARATORS) | (computeHashCode() << USED_BITS); return true; } } return false; }
/** * Initializes the current path with the given string. */ private Path initialize(String path) { assert path != null; path = collapseSlashes(path); int len = path.length(); // compute the separators array if (len < 2) { if (len == 1 && path.charAt(0) == SEPARATOR) { separators = HAS_LEADING; } else { separators = 0; } } else { boolean hasLeading = path.charAt(0) == SEPARATOR; boolean hasTrailing = path.charAt(len - 1) == SEPARATOR; separators = hasLeading ? HAS_LEADING : 0; if (hasTrailing) { separators |= HAS_TRAILING; } } // compute segments and ensure canonical form segments = computeSegments(path); if (!canonicalize()) { // compute hash now because canonicalize didn't need to do it separators = (separators & ALL_SEPARATORS) | (computeHashCode() << USED_BITS); } return this; }