summaryrefslogtreecommitdiffstats
path: root/source/core/slang-file-system.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-10-03 21:09:16 -0400
committerGitHub <noreply@github.com>2022-10-03 18:09:16 -0700
commit0b51ea6bb54b1d8a12695ccc2c259fd591069791 (patch)
tree1ff0587eb1454891bf8421a86b95ed5e95419e75 /source/core/slang-file-system.cpp
parentcc3548c92b1cf028b94d7a264a55df83e6d4d212 (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.cpp163
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();