//============================================================================== bool File::isAbsolutePath (StringRef path) { auto firstChar = *(path.text); return firstChar == getSeparatorChar() #if JUCE_WINDOWS || (firstChar != 0 && path.text[1] == ':'); #else || firstChar == '~';
String File::getFileNameWithoutExtension() const { auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar()) + 1; auto lastDot = fullPath.lastIndexOfChar ('.'); if (lastDot > lastSlash) return fullPath.substring (lastSlash, lastDot); return fullPath.substring (lastSlash); }
//============================================================================== String File::getPathUpToLastSlash() const { auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar()); if (lastSlash > 0) return fullPath.substring (0, lastSlash); if (lastSlash == 0) return getSeparatorString(); return fullPath; }
//============================================================================== String FileSystem::normalize(const String& path) const { if(path.empty()) { return path; } else { String ret = path; // // Replace separator characters with the appropriate type // const CharType sep = getSeparatorChar(); const CharType badSep = (sep == '/') ? '\\' : '/'; std::replace(ret.begin(), ret.end(), badSep, sep); // Replace strings of separators with a single separator // starting at position 0 for UNIX and 1 for Windows! size_t pos = (sep == '\\') ? 1 : 0; const CharType doubleSep[] = {sep, sep, 0}; while(pos != String::npos) { pos = ret.find(doubleSep, pos); if(pos != String::npos) { ret.erase(pos, 1); } } // // Remove terminating separator if any // if(sep == ret[ret.length()-1] && getPrefixLength(ret) < ret.length()) { ret = ret.erase(ret.length()-1); } return ret; } }
// If the child is absolute, then we do not resolve the child against // the parent. This seems to make the most logical sense, even though // that is not the apparent behaviour of the JDK. // // If the parent directory is empty, this is not treated as the current // working directory, but simply as the empty string. // This allows this class to be used in URL resolution where the current // directory has no meaning. //============================================================================== String FileSystem::resolve(const String& parent, const String& child) const { String normalizedChild = normalize(child); if(isAbsolute(normalizedChild)) { return normalizedChild; } else { size_t prefixLen = getPrefixLength(normalizedChild); String normalizedParent = normalize(parent); const CharType lastChar = normalizedParent[normalizedParent.length()-1]; if(lastChar == getSeparatorChar()) { return normalizedParent + normalizedChild.substr(prefixLen); } else { return normalizedParent + getSeparator() + normalizedChild.substr(prefixLen); } } }
//============================================================================== String File::getFileName() const { return fullPath.substring (fullPath.lastIndexOfChar (getSeparatorChar()) + 1); }
String File::addTrailingSeparator (const String& path) { return path.endsWithChar (getSeparatorChar()) ? path : path + getSeparatorChar(); }
String File::parseAbsolutePath (const String& p) { if (p.isEmpty()) return {}; #if JUCE_WINDOWS // Windows.. auto path = removeEllipsis (p.replaceCharacter ('/', '\\')); if (path.startsWithChar (getSeparatorChar())) { if (path[1] != getSeparatorChar()) { /* When you supply a raw string to the File object constructor, it must be an absolute path. If you're trying to parse a string that may be either a relative path or an absolute path, you MUST provide a context against which the partial path can be evaluated - you can do this by simply using File::getChildFile() instead of the File constructor. E.g. saying "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute path if that's what was supplied, or would evaluate a partial path relative to the CWD. */ jassertfalse; path = File::getCurrentWorkingDirectory().getFullPathName().substring (0, 2) + path; } } else if (! path.containsChar (':')) { /* When you supply a raw string to the File object constructor, it must be an absolute path. If you're trying to parse a string that may be either a relative path or an absolute path, you MUST provide a context against which the partial path can be evaluated - you can do this by simply using File::getChildFile() instead of the File constructor. E.g. saying "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute path if that's what was supplied, or would evaluate a partial path relative to the CWD. */ jassertfalse; return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName(); } #else // Mac or Linux.. // Yes, I know it's legal for a unix pathname to contain a backslash, but this assertion is here // to catch anyone who's trying to run code that was written on Windows with hard-coded path names. // If that's why you've ended up here, use File::getChildFile() to build your paths instead. jassert ((! p.containsChar ('\\')) || (p.indexOfChar ('/') >= 0 && p.indexOfChar ('/') < p.indexOfChar ('\\'))); auto path = removeEllipsis (p); if (path.startsWithChar ('~')) { if (path[1] == getSeparatorChar() || path[1] == 0) { // expand a name of the form "~/abc" path = File::getSpecialLocation (File::userHomeDirectory).getFullPathName() + path.substring (1); } else { // expand a name of type "~dave/abc" auto userName = path.substring (1).upToFirstOccurrenceOf ("/", false, false); if (auto* pw = getpwnam (userName.toUTF8())) path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false); } } else if (! path.startsWithChar (getSeparatorChar())) { #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS if (! (path.startsWith ("./") || path.startsWith ("../"))) { /* When you supply a raw string to the File object constructor, it must be an absolute path. If you're trying to parse a string that may be either a relative path or an absolute path, you MUST provide a context against which the partial path can be evaluated - you can do this by simply using File::getChildFile() instead of the File constructor. E.g. saying "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute path if that's what was supplied, or would evaluate a partial path relative to the CWD. */ jassertfalse; #if JUCE_LOG_ASSERTIONS Logger::writeToLog ("Illegal absolute path: " + path); #endif } #endif return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName(); } #endif while (path.endsWithChar (getSeparatorChar()) && path != getSeparatorString()) // careful not to turn a single "/" into an empty string. path = path.dropLastCharacters (1); return path; }
//============================================================================== String FileSystem::getSeparator() const { return String(1, getSeparatorChar()); }