diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-10-03 21:09:16 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-03 18:09:16 -0700 |
| commit | 0b51ea6bb54b1d8a12695ccc2c259fd591069791 (patch) | |
| tree | 1ff0587eb1454891bf8421a86b95ed5e95419e75 /source/core/slang-file-system.cpp | |
| parent | cc3548c92b1cf028b94d7a264a55df83e6d4d212 (diff) | |
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.
Diffstat (limited to 'source/core/slang-file-system.cpp')
| -rw-r--r-- | source/core/slang-file-system.cpp | 163 |
1 files changed, 125 insertions, 38 deletions
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, ComPtr<ISla return style; } -// Cacluate a combined path, just using Path:: string processing +// Calcuate a combined path, just using Path:: string processing static SlangResult _calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) { String relPath; @@ -117,26 +117,42 @@ SlangResult OSFileSystem::getFileUniqueIdentity(const char* pathIn, ISlangBlob** SLANG_RETURN_ON_FAIL(_checkExt(m_style)); // By default we use the canonical path to uniquely identify a file - return getCanonicalPath(pathIn, outUniqueIdentity); + return getPath(PathKind::Canonical, pathIn, outUniqueIdentity); } -SlangResult OSFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath) +SlangResult OSFileSystem::getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) { SLANG_RETURN_ON_FAIL(_checkExt(m_style)); - String canonicalPath; - SLANG_RETURN_ON_FAIL(Path::getCanonical(_fixPathDelimiters(path), canonicalPath)); - *outCanonicalPath = StringUtil::createStringBlob(canonicalPath).detach(); - return SLANG_OK; -} - -SlangResult OSFileSystem::getSimplifiedPath(const char* pathIn, ISlangBlob** outSimplifiedPath) -{ - SLANG_RETURN_ON_FAIL(_checkExt(m_style)); + switch (pathKind) + { + case PathKind::OperatingSystem: + case PathKind::Display: + { + // It's possible canonical path fail... + if (SLANG_SUCCEEDED(getPath(PathKind::Canonical, path, outPath))) + { + return SLANG_OK; + } + // If so try simplified + return getPath(PathKind::Simplified, path, outPath); + } + case PathKind::Canonical: + { + String canonicalPath; + SLANG_RETURN_ON_FAIL(Path::getCanonical(_fixPathDelimiters(path), canonicalPath)); + *outPath = StringUtil::createStringBlob(canonicalPath).detach(); + return SLANG_OK; + } + case PathKind::Simplified: + { + String simplifiedPath = Path::simplify(path); + *outPath = StringUtil::createStringBlob(simplifiedPath).detach(); + return SLANG_OK; + } + } - String simplifiedPath = Path::simplify(pathIn); - *outSimplifiedPath = StringUtil::createStringBlob(simplifiedPath).detach(); - return SLANG_OK; + return SLANG_E_NOT_AVAILABLE; } SlangResult OSFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) @@ -223,6 +239,15 @@ SlangResult OSFileSystem::saveFile(const char* pathIn, const void* data, size_t return SLANG_OK; } +SlangResult OSFileSystem::saveFileBlob(const char* path, ISlangBlob* dataBlob) +{ + if (!dataBlob) + { + return SLANG_E_INVALID_ARG; + } + return saveFile(path, dataBlob->getBufferPointer(), 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<ISlangBlob> 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<ISlangBlob> 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<ISlangBlob> 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(); |
