From 0b51ea6bb54b1d8a12695ccc2c259fd591069791 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Mon, 3 Oct 2022 21:09:16 -0400 Subject: IMutableFileSystem::saveFileBlob (#2427) * #include an absolute path didn't work - because paths were taken to always be relative. * Remove ref count for Entry in RiffFileSystem. Free up backing Entry types (to work around Dictionary not doing this). * Some small improvements to RiffFileSystem. * Add testing for file systems. * Split out MemoryFileSystem. * Add some documentation around different FileSystems. * Small tiry up - removing unused headers, fixing some comments. Use StringBlob::moveCreate where appropriate. * Small improvement to MemoryFileSystem. Improve documentation comments a little. * Added PathKind * * Make MemoryFileSystem not have implicit directories * Make RelativeFileSystem only allow access to files in file system (kind of like chroot) * Added Path::simplifyAbsolute * Special handling for root of MemoryFileSystem * Improvements around paths for different impls * More improvements around RelativeFileSystem. Special case root handling. * Test archive serialization. Move testinf from compression. Remove the implicit directory test -> doesn't work on all file systems. * Small optimization that removes need for check for a parent unless an item is being *created*. * Add implicit path testing. * Add support for saveFileBlob Add testing for saveFileBlob * Removed TemporaryFileSet Added PlatformUtil::outputDebugMessage * Some small improvements around RelativeFileSystem. * Split out ImplicitDirectoryCollector so can use without requiring compression systems. * Split out StringSliceIndexMap into own files. --- source/core/slang-file-system.cpp | 163 +++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 38 deletions(-) (limited to 'source/core/slang-file-system.cpp') diff --git a/source/core/slang-file-system.cpp b/source/core/slang-file-system.cpp index 283dab712..0697810f4 100644 --- a/source/core/slang-file-system.cpp +++ b/source/core/slang-file-system.cpp @@ -53,7 +53,7 @@ static FileSystemStyle _getFileSystemStyle(ISlangFileSystem* system, ComPtrgetBufferPointer(), dataBlob->getBufferSize()); +} + SlangResult OSFileSystem::remove(const char* path) { SLANG_RETURN_ON_FAIL(_checkMutable(m_style)); @@ -702,14 +727,37 @@ SlangResult CacheFileSystem::getPathType(const char* inPath, SlangPathType* outP return _getPathType(info, inPath, outPathType); } -SlangResult CacheFileSystem::getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath) +SlangResult CacheFileSystem::getPath(PathKind kind, const char* path, ISlangBlob** outPath) +{ + switch (kind) + { + case PathKind::Simplified: return _getSimplifiedPath(path, outPath); + case PathKind::Canonical: return _getCanonicalPath(path, outPath); + default: break; + } + + if (m_fileSystemExt) + { + return m_fileSystemExt->getPath(kind, path, outPath); + } + + // If we don't have a fileSystem, we can try the canonical path + if (SLANG_SUCCEEDED(getPath(PathKind::Canonical, path, outPath))) + { + return SLANG_OK; + } + // Else we can try simplified + return getPath(PathKind::Simplified, path, outPath); +} + +SlangResult CacheFileSystem::_getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath) { // If we have a ISlangFileSystemExt we can just pass on the request to it switch (m_pathStyle) { case PathStyle::FileSystemExt: { - return m_fileSystemExt->getSimplifiedPath(path, outSimplifiedPath); + return m_fileSystemExt->getPath(PathKind::Simplified, path, outSimplifiedPath); } case PathStyle::Simplifiable: { @@ -721,7 +769,7 @@ SlangResult CacheFileSystem::getSimplifiedPath(const char* path, ISlangBlob** ou } } -SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath) +SlangResult CacheFileSystem::_getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath) { *outCanonicalPath = nullptr; @@ -742,7 +790,7 @@ SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** out // Try getting the canonicalPath by asking underlying file system ComPtr canonicalPathBlob; - SlangResult res = m_fileSystemExt->getCanonicalPath(path, canonicalPathBlob.writeRef()); + SlangResult res = m_fileSystemExt->getPath(PathKind::Canonical, path, canonicalPathBlob.writeRef()); if (SLANG_SUCCEEDED(res)) { @@ -782,10 +830,10 @@ RelativeFileSystem::RelativeFileSystem(ISlangFileSystem* fileSystem, const Strin { m_osPathKind = ext->getOSPathKind(); - // If it's direct, but we have a relative path, canonical should work + // If it's direct, but we have a relative path, "operating system" should work if (m_osPathKind == OSPathKind::Direct && relativePath.getLength()) { - m_osPathKind = OSPathKind::Canonical; + m_osPathKind = OSPathKind::OperatingSystem; } } } @@ -823,18 +871,30 @@ SlangResult RelativeFileSystem::_calcCombinedPathInner(SlangPathType fromPathTyp } } -SlangResult RelativeFileSystem::_getFixedPath(const char* path, String& outPath) +SlangResult RelativeFileSystem::_getCanonicalPath(const char* path, StringBuilder& outPath) { - ComPtr blob; if (m_stripPath) { - String strippedPath = Path::getFileName(path); - SLANG_RETURN_ON_FAIL(_calcCombinedPathInner(SLANG_PATH_TYPE_DIRECTORY, m_relativePath.getBuffer(), strippedPath.getBuffer(), blob.writeRef())); + // We are just using the filename. There is no path that could go outside of the the relative path so we can use as is + auto fileName = Path::getFileName(path); + + outPath.swapWith(fileName); } else { - SLANG_RETURN_ON_FAIL(_calcCombinedPathInner(SLANG_PATH_TYPE_DIRECTORY, m_relativePath.getBuffer(), path, blob.writeRef())); + // We want the input path to be local to this file system + SLANG_RETURN_ON_FAIL(Path::simplifyAbsolute(path, outPath)); } + return SLANG_OK; +} + +SlangResult RelativeFileSystem::_getFixedPath(const char* path, String& outPath) +{ + ComPtr blob; + + StringBuilder canonicalPath; + SLANG_RETURN_ON_FAIL(_getCanonicalPath(path, canonicalPath)); + SLANG_RETURN_ON_FAIL(_calcCombinedPathInner(SLANG_PATH_TYPE_DIRECTORY, m_relativePath.getBuffer(), canonicalPath.getBuffer(), blob.writeRef())); outPath = StringUtil::getString(blob); return SLANG_OK; @@ -878,22 +938,39 @@ SlangResult RelativeFileSystem::getPathType(const char* path, SlangPathType* out return fileSystem->getPathType(fixedPath.getBuffer(), outPathType); } -SlangResult RelativeFileSystem::getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath) -{ - auto fileSystem = _getExt(); - if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED; - - return fileSystem->getSimplifiedPath(path, outSimplifiedPath); -} - -SlangResult RelativeFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath) +SlangResult RelativeFileSystem::getPath(PathKind kind, const char* path, ISlangBlob** outPath) { auto fileSystem = _getExt(); if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED; + + switch (kind) + { + case PathKind::Simplified: + { + return fileSystem->getPath(kind, path, outPath); + } + case PathKind::Display: + { + // If not backed by OS, just use simplified path, else use the Operating system path + kind = (fileSystem->getOSPathKind() == OSPathKind::None) ? PathKind::Simplified : PathKind::OperatingSystem; + return getPath(kind, path, outPath); + } + case PathKind::Canonical: + { + StringBuilder canonicalPath; + SLANG_RETURN_ON_FAIL(_getCanonicalPath(path, canonicalPath)); + *outPath = StringBlob::moveCreate(canonicalPath).detach(); + return SLANG_OK; + } + case PathKind::OperatingSystem: + { + String fixedPath; + SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath)); + return fileSystem->getPath(kind, fixedPath.getBuffer(), outPath); + } + } - String fixedPath; - SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath)); - return fileSystem->getCanonicalPath(fixedPath.getBuffer(), outCanonicalPath); + return SLANG_FAIL; } void RelativeFileSystem::clearCache() @@ -924,6 +1001,16 @@ SlangResult RelativeFileSystem::saveFile(const char* path, const void* data, siz return fileSystem->saveFile(fixedPath.getBuffer(), data, size); } +SlangResult RelativeFileSystem::saveFileBlob(const char* path, ISlangBlob* dataBlob) +{ + auto fileSystem = _getMutable(); + if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED; + + String fixedPath; + SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath)); + return fileSystem->saveFileBlob(fixedPath.getBuffer(), dataBlob); +} + SlangResult RelativeFileSystem::remove(const char* path) { auto fileSystem = _getMutable(); -- cgit v1.2.3