summaryrefslogtreecommitdiff
path: root/source/core/slang-riff-file-system.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-09-29 14:12:15 -0400
committerGitHub <noreply@github.com>2022-09-29 14:12:15 -0400
commit9296405a2e15c07b5a8b7a002a2fa082232d559b (patch)
tree9dd7bff82645e04f1dc53fbff8f5e366bda49cb9 /source/core/slang-riff-file-system.cpp
parent8e0750fb193a8d2b9e8c3a0d81e367d6a9bdeb30 (diff)
Split out MemoryFileSystem (#2422)
* #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.
Diffstat (limited to 'source/core/slang-riff-file-system.cpp')
-rw-r--r--source/core/slang-riff-file-system.cpp243
1 files changed, 14 insertions, 229 deletions
diff --git a/source/core/slang-riff-file-system.cpp b/source/core/slang-riff-file-system.cpp
index 9402a2b4e..da73cb2a5 100644
--- a/source/core/slang-riff-file-system.cpp
+++ b/source/core/slang-riff-file-system.cpp
@@ -3,11 +3,7 @@
#include "../../slang-com-helper.h"
#include "../../slang-com-ptr.h"
-#include "slang-io.h"
-#include "slang-string-util.h"
#include "slang-blob.h"
-#include "slang-string-slice-pool.h"
-#include "slang-uint-set.h"
// Compression systems
#include "slang-deflate-compression-system.h"
@@ -23,13 +19,9 @@ RiffFileSystem::RiffFileSystem(ICompressionSystem* compressionSystem):
void* RiffFileSystem::getInterface(const Guid& guid)
{
- if ( guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangCastable::getTypeGuid() ||
- guid == ISlangFileSystem::getTypeGuid() ||
- guid == ISlangFileSystemExt::getTypeGuid() ||
- guid == ISlangMutableFileSystem::getTypeGuid())
+ if (auto ptr = Super::getInterface(guid))
{
- return static_cast<ISlangMutableFileSystem*>(this);
+ return ptr;
}
else if (guid == IArchiveFileSystem::getTypeGuid())
{
@@ -53,183 +45,40 @@ void* RiffFileSystem::castAs(const Guid& guid)
return getObject(guid);
}
-SlangResult RiffFileSystem::_calcCanonicalPath(const char* path, StringBuilder& out)
-{
- List<UnownedStringSlice> splitPath;
- Path::split(UnownedStringSlice(path), splitPath);
-
- // If the first part of a path is "", it means path of form "/some/path". Turn into "some/path".
- if (splitPath.getCount() > 1 && splitPath[0].getLength() == 0)
- {
- splitPath.removeAt(0);
- }
-
- Path::simplify(splitPath);
-
- if (splitPath.indexOf(UnownedStringSlice::fromLiteral("..")) >= 0)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- if (splitPath.getCount() == 0)
- {
- // It's an empty path;
- return SLANG_FAIL;
- }
-
- Path::join(splitPath.getBuffer(), splitPath.getCount(), out);
- return SLANG_OK;
-}
-
-RiffFileSystem::Entry* RiffFileSystem::_getEntryFromCanonicalPath(const String& canonicalPath)
-{
- return m_entries.TryGetValue(canonicalPath);
-}
-
-RiffFileSystem::Entry* RiffFileSystem::_getEntryFromPath(const char* path, String* outPath)
-{
- StringBuilder buffer;
- if (SLANG_FAILED(_calcCanonicalPath(path, buffer)))
- {
- return nullptr;
- }
-
- if (outPath)
- {
- *outPath = buffer;
- }
- return _getEntryFromCanonicalPath(buffer);
-}
-
SlangResult RiffFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
{
- Entry* entry = _getEntryFromPath(path);
- if (entry == nullptr || entry->m_type != SLANG_PATH_TYPE_FILE)
- {
- return SLANG_E_NOT_FOUND;
- }
+ Entry* entry;
+ SLANG_RETURN_ON_FAIL(_loadFile(path, &entry));
+
+ ISlangBlob* contents = entry->m_contents;
if (m_compressionSystem)
{
// Okay lets decompress into a blob
ScopedAllocation alloc;
void* dst = alloc.allocateTerminated(entry->m_uncompressedSizeInBytes);
-
- ISlangBlob* compressedData = entry->m_contents;
- SLANG_RETURN_ON_FAIL(m_compressionSystem->decompress(compressedData->getBufferPointer(), compressedData->getBufferSize(), entry->m_uncompressedSizeInBytes, dst));
+ SLANG_RETURN_ON_FAIL(m_compressionSystem->decompress(contents->getBufferPointer(), contents->getBufferSize(), entry->m_uncompressedSizeInBytes, dst));
auto blob = RawBlob::moveCreate(alloc);
*outBlob = blob.detach();
+ return SLANG_OK;
}
else
{
- // We don't have any compression, so can just return the blob
- ISlangBlob* contents = entry->m_contents;
+ // Just return as is
contents->addRef();
*outBlob = contents;
+ return SLANG_OK;
}
-
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
-{
- return getCanonicalPath(path, outUniqueIdentity);
-}
-
-SlangResult RiffFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
-{
- String combinedPath;
- switch (fromPathType)
- {
- case SLANG_PATH_TYPE_FILE:
- {
- combinedPath = Path::combine(Path::getParentDirectory(fromPath), path);
- break;
- }
- case SLANG_PATH_TYPE_DIRECTORY:
- {
- combinedPath = Path::combine(fromPath, path);
- break;
- }
- }
-
- *pathOut = StringUtil::createStringBlob(combinedPath).detach();
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::getPathType(const char* path, SlangPathType* outPathType)
-{
- String canonicalPath;
- Entry* entry = _getEntryFromPath(path, &canonicalPath);
- if (entry == nullptr)
- {
- // Could be an implicit path
- ImplicitDirectoryCollector collector(canonicalPath);
- for (const auto& pair : m_entries)
- {
- const Entry* childEntry = &pair.Value;
- collector.addPath(childEntry->m_type, childEntry->m_canonicalPath.getUnownedSlice());
- // If on adding a path we determine a directory exists, then we are done
- if (collector.getDirectoryExists())
- {
- *outPathType = SLANG_PATH_TYPE_DIRECTORY;
- return SLANG_OK;
- }
- }
-
- // If not implicit or explicit we are done.
- return SLANG_E_NOT_FOUND;
- }
-
- // Explicit type
- *outPathType = entry->m_type;
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath)
-{
- String simplifiedPath = Path::simplify(path);
- *outSimplifiedPath = StringUtil::createStringBlob(simplifiedPath).detach();
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath)
-{
- StringBuilder buffer;
- SLANG_RETURN_ON_FAIL(_calcCanonicalPath(path, buffer));
- *outCanonicalPath = StringUtil::createStringBlob(buffer).detach();
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
-{
- String canonicalPath;
- Entry* entry = _getEntryFromPath(path, &canonicalPath);
-
- const bool foundDirectory = (entry && entry->m_type == SLANG_PATH_TYPE_DIRECTORY);
-
- // We allow implicit directories, so this works even if there isn't an explicit one
- ImplicitDirectoryCollector collector(canonicalPath, foundDirectory);
-
- // If it is a directory, we need to see if there is anything in it
- for (const auto& pair : m_entries)
- {
- const Entry* childEntry = &pair.Value;
- collector.addPath(childEntry->m_type, childEntry->m_canonicalPath.getUnownedSlice());
- }
-
- return collector.enumerate(callback, userData);
}
SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t size)
-{
- StringBuilder canonicalPath;
- SLANG_RETURN_ON_FAIL(_calcCanonicalPath(path, canonicalPath));
+{
+ Entry* entry;
+ SLANG_RETURN_ON_FAIL(_requireFile(path, &entry));
ComPtr<ISlangBlob> contents;
-
if (m_compressionSystem)
{
// Lets try compressing the input
@@ -240,71 +89,7 @@ SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t
// Just store the data directly.
contents = RawBlob::create(data, size);
}
-
- if (Entry* foundEntry = _getEntryFromCanonicalPath(canonicalPath))
- {
- if (foundEntry->m_type != SLANG_PATH_TYPE_FILE)
- {
- // Can only set if it's already a file, if it's anything else it's an error
- return SLANG_FAIL;
- }
-
- foundEntry->setContents(size, contents);
- }
- else
- {
- Entry entry;
- entry.initFile(canonicalPath, size, contents);
- m_entries.Add(canonicalPath, entry);
- }
-
- return SLANG_OK;
-}
-
-SlangResult RiffFileSystem::remove(const char* path)
-{
- String canonicalPath;
- Entry* entry = _getEntryFromPath(path, &canonicalPath);
-
- if (entry)
- {
- if (entry->m_type == SLANG_PATH_TYPE_DIRECTORY)
- {
- ImplicitDirectoryCollector collector(canonicalPath);
-
- // If it is a directory, we need to see if there is anything in it
- for (const auto& pair : m_entries)
- {
- const Entry* childEntry = &pair.Value;
- collector.addPath(childEntry->m_type, childEntry->m_canonicalPath.getUnownedSlice());
- if (collector.hasContent())
- {
- // Directory is not empty
- return SLANG_FAIL;
- }
- }
- }
-
- // Reset so doesn't hold references/keep memory in scope
- entry->reset();
- m_entries.Remove(canonicalPath);
- return SLANG_OK;
- }
-
- return SLANG_E_NOT_FOUND;
-}
-
-SlangResult RiffFileSystem::createDirectory(const char* path)
-{
- String canonicalPath;
- if (_getEntryFromPath(path, &canonicalPath))
- {
- return SLANG_FAIL;
- }
-
- Entry entry;
- entry.initDirectory(canonicalPath);
- m_entries.Add(canonicalPath, entry);
+ entry->setContents(size, contents);
return SLANG_OK;
}