diff options
Diffstat (limited to 'source/slang/slang-file-system.cpp')
| -rw-r--r-- | source/slang/slang-file-system.cpp | 135 |
1 files changed, 99 insertions, 36 deletions
diff --git a/source/slang/slang-file-system.cpp b/source/slang/slang-file-system.cpp index ef77dbf33..caaa9f56d 100644 --- a/source/slang/slang-file-system.cpp +++ b/source/slang/slang-file-system.cpp @@ -14,8 +14,8 @@ static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown; static const Guid IID_ISlangFileSystem = SLANG_UUID_ISlangFileSystem; static const Guid IID_ISlangFileSystemExt = SLANG_UUID_ISlangFileSystemExt; -// Cacluate a relative path, just using Path:: string processing -static SlangResult _calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) +// Cacluate a combined path, just using Path:: string processing +static SlangResult _calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) { String relPath; switch (fromPathType) @@ -60,9 +60,9 @@ SlangResult DefaultFileSystem::getCanoncialPath(const char* path, ISlangBlob** c return SLANG_OK; } -SlangResult DefaultFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) +SlangResult DefaultFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) { - return _calcRelativePath(fromPathType, fromPath, path, pathOut); + return _calcCombinedPath(fromPathType, fromPath, path, pathOut); } SlangResult SLANG_MCALL DefaultFileSystem::getPathType( @@ -127,12 +127,25 @@ ISlangUnknown* CacheFileSystem::getInterface(const Guid& guid) return _getInterface(this, guid); } -CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, bool useSimplifyForCanonicalPath) : +CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, CanonicalMode canonicalMode) : m_fileSystem(fileSystem), - m_useSimplifyForCanonicalPath(useSimplifyForCanonicalPath) + m_canonicalMode(canonicalMode) { // Try to get the more sophisticated interface fileSystem->queryInterface(IID_ISlangFileSystemExt, (void**)m_fileSystemExt.writeRef()); + + switch (canonicalMode) + { + case CanonicalMode::Default: + case CanonicalMode::FileSystemExt: + { + m_canonicalMode = m_fileSystemExt ? CanonicalMode::FileSystemExt : CanonicalMode::Hash; + break; + } + default: break; + } + // It can't be default + SLANG_ASSERT(m_canonicalMode != CanonicalMode::Default); } CacheFileSystem::~CacheFileSystem() @@ -143,45 +156,95 @@ CacheFileSystem::~CacheFileSystem() } } -CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfo(const String& relPath) +CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfoFromCanonical(const String& canonicalPath) { - PathInfo** infoPtr = m_pathMap.TryGetValue(relPath); + // First see if we have it.. if not add it + PathInfo** infoPtr = m_canonicalMap.TryGetValue(canonicalPath); if (infoPtr) { return *infoPtr; } - - String canonicalPath; - if (m_fileSystemExt) - { - // Try getting the canonical path - // Okay request from the underlying file system the canonical path - ComPtr<ISlangBlob> canonicalBlob; - if (SLANG_FAILED(m_fileSystemExt->getCanoncialPath(relPath.Buffer(), canonicalBlob.writeRef()))) - { - // Write in result as being null ptr so not tried again - m_pathMap.Add(relPath, nullptr); - return nullptr; - } - // Get the path as a string - canonicalPath = StringUtil::getString(canonicalBlob); - } else { - canonicalPath = m_useSimplifyForCanonicalPath ? Path::Simplify(relPath.getUnownedSlice()) : relPath; + // Create and add to canonical path + PathInfo* pathInfo = new PathInfo(canonicalPath); + m_canonicalMap.Add(canonicalPath, pathInfo); + return pathInfo; } +} - PathInfo* pathInfo; - infoPtr = m_canonicalMap.TryGetValue(canonicalPath); +CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfo(const String& relPath) +{ + PathInfo** infoPtr = m_pathMap.TryGetValue(relPath); if (infoPtr) { - pathInfo = *infoPtr; + return *infoPtr; } - else + + PathInfo* pathInfo = nullptr; + switch (m_canonicalMode) { - // Create and add to canonical path - pathInfo = new PathInfo(canonicalPath); - m_canonicalMap.Add(canonicalPath, pathInfo); + case CanonicalMode::FileSystemExt: + { + // Try getting the canonical path + // Okay request from the underlying file system the canonical path + ComPtr<ISlangBlob> canonicalBlob; + if (SLANG_FAILED(m_fileSystemExt->getCanoncialPath(relPath.Buffer(), canonicalBlob.writeRef()))) + { + // Write in result as being null ptr so not tried again + m_pathMap.Add(relPath, nullptr); + return nullptr; + } + // Get the path as a string + String canonicalPath = StringUtil::getString(canonicalBlob); + pathInfo = _getPathInfoFromCanonical(canonicalPath); + break; + } + case CanonicalMode::Path: + { + pathInfo = _getPathInfoFromCanonical(relPath); + break; + } + case CanonicalMode::SimplifiedPath: + { + pathInfo = _getPathInfoFromCanonical(Path::Simplify(relPath.getUnownedSlice())); + break; + } + case CanonicalMode::Hash: + { + // I can only see if this is the same file as already loaded by loading the file and doing a hash + ComPtr<ISlangBlob> fileBlob; + Result res = m_fileSystem->loadFile(relPath.Buffer(), fileBlob.writeRef()); + if (SLANG_FAILED(res) || fileBlob == nullptr) + { + // Write in result as being null ptr so not tried again + m_pathMap.Add(relPath, nullptr); + return nullptr; + } + + // Calculate the hash on the contents + const uint64_t hash = GetHashCode64((const char*)fileBlob->getBufferPointer(), fileBlob->getBufferSize()); + + String hashString = Path::GetFileName(relPath); + hashString = hashString.ToLower(); + + hashString.append(':'); + + // The canonical name is.. combination of name and hash + hashString.append(hash, 16); + // We'll use the 'hashString' as the canonical path + pathInfo = _getPathInfoFromCanonical(hashString); + + // We have the contents, so store it on the PathInfo, along with the result + if (pathInfo->m_loadFileResult == CompressedResult::Uninitialized) + { + // Save the contents of the saved file + pathInfo->m_loadFileResult = toCompressedResult(res); + pathInfo->m_fileBlob = fileBlob; + } + + break; + } } // Add the relPath @@ -224,17 +287,17 @@ SlangResult CacheFileSystem::getCanoncialPath(const char* path, ISlangBlob** can return SLANG_OK; } -SlangResult CacheFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) +SlangResult CacheFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) { // Just defer to contained implementation if (m_fileSystemExt) { - return m_fileSystemExt->calcRelativePath(fromPathType, fromPath, path, pathOut); + return m_fileSystemExt->calcCombinedPath(fromPathType, fromPath, path, pathOut); } else { // Just use the default implementation - return _calcRelativePath(fromPathType, fromPath, path, pathOut); + return _calcCombinedPath(fromPathType, fromPath, path, pathOut); } } @@ -272,4 +335,4 @@ SlangResult CacheFileSystem::getPathType(const char* pathIn, SlangPathType* path return toResult(info->m_getPathTypeResult); } -}
\ No newline at end of file +} |
