summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-04-20 14:04:31 -0400
committerGitHub <noreply@github.com>2021-04-20 14:04:31 -0400
commit6bba674f9d732eccc27dcf004611e6a8eb9bc14e (patch)
treee78757692346c19e614df35330a41134c2c67758
parent778428fecc0548af565e92745cf1344bcf19367f (diff)
Small filesystem improvements (#1802)
* #include an absolute path didn't work - because paths were taken to always be relative. * Small improvements around uniqueIdentify and CacheFileSystem
-rw-r--r--slang.h14
-rw-r--r--source/core/slang-file-system.cpp32
-rw-r--r--source/core/slang-file-system.h4
3 files changed, 40 insertions, 10 deletions
diff --git a/slang.h b/slang.h
index a813cd969..060ac2dce 100644
--- a/slang.h
+++ b/slang.h
@@ -1006,23 +1006,27 @@ extern "C"
/** Get a uniqueIdentity which uniquely identifies an object of the file system.
- Given a path, returns a 'uniqueIdentity' which ideally is the same value for the same file on the file system.
+ Given a path, returns a 'uniqueIdentity' which ideally is the same value for the same object on the file system.
- The uniqueIdentity is used to compare if files are the same - which allows slang to cache source contents internally. It is also used
- for #pragma once functionality.
+ The uniqueIdentity is used to compare if two paths are the same - which amongst other things allows Slang to
+ cache source contents internally. It is also used for #pragma once functionality.
A *requirement* is for any implementation is that two paths can only return the same uniqueIdentity if the
- contents of the two files are *identical*. If an implementation breaks this constraint it can produce incorrect compilation.
+ contents of the two files are *identical*h. If an implementation breaks this constraint it can produce incorrect compilation.
If an implementation cannot *strictly* identify *the same* files, this will only have an effect on #pragma once behavior.
The string for the uniqueIdentity is held zero terminated in the ISlangBlob of outUniqueIdentity.
Note that there are many ways a uniqueIdentity may be generated for a file. For example it could be the
- 'canonical path' - assuming it is available and unambitious for a file system. Another possible mechanism
+ 'canonical path' - assuming it is available and unambiguous for a file system. Another possible mechanism
could be to store the filename combined with the file date time to uniquely identify it.
The client must ensure the blob be released when no longer used, otherwise memory will leak.
+ NOTE! Ideally this method would be called 'getPathUniqueIdentity' but for historical reasons and
+ backward compatibility it's name remains with 'File' even though an implementation should be made to work
+ with directories too.
+
@param path
@param outUniqueIdentity
@returns A `SlangResult` to indicate success or failure getting the uniqueIdentity.
diff --git a/source/core/slang-file-system.cpp b/source/core/slang-file-system.cpp
index 91dd09ff9..8dd01ebf0 100644
--- a/source/core/slang-file-system.cpp
+++ b/source/core/slang-file-system.cpp
@@ -473,19 +473,43 @@ SlangResult CacheFileSystem::_calcUniqueIdentity(const String& path, String& out
case UniqueIdentityMode::SimplifyPathAndHash:
case UniqueIdentityMode::Hash:
{
+ // If m_uniqueIdentityMode is SimplifyPathAndHash, the path will already be simplified before this function is hit (and it hasn't been found
+ // via path lookup). That being the case only option left is to 'hash' (or fallback to backing impls uniqueIdentity impl)
+
// If we don't have a file system -> assume cannot be found
if (m_fileSystem == nullptr)
{
return SLANG_E_NOT_FOUND;
}
- // I can only see if this is the same file as already loaded by loading the file and doing a hash
+ // First attempt to load as a file
Result res = m_fileSystem->loadFile(path.getBuffer(), outFileContents.writeRef());
- if (SLANG_FAILED(res) || outFileContents == nullptr)
+
+ // If it succeeded but there is no contents, then make the result NOT_FOUND
+ res = (SLANG_SUCCEEDED(res) && outFileContents == nullptr) ? SLANG_E_NOT_FOUND : res;
+
+ // If that failed, we may be able to do something if m_fileSystemExt is available
+ if (SLANG_FAILED(res))
{
- return SLANG_FAIL;
+ // If we have m_fileSystemExt interface we can just use it's implementation, as a fallback.
+ // Doing so will mean the uniqueIdentity will work if say it's a directory
+ if (m_fileSystemExt)
+ {
+ ComPtr<ISlangBlob> uniqueIdentity;
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(path.getBuffer(), uniqueIdentity.writeRef()));
+ // Get the path as a string
+ outUniqueIdentity = StringUtil::getString(uniqueIdentity);
+ return SLANG_OK;
+ }
+
+ // If we can't access as a file (or use the backing implementations impl), we are in a tricky situation.
+ // The ISlangFileSystem interface provides no way to determine if the path is a directory for example -
+ // so there is no way of determining if something along the path exists.
+ //
+ // So we just return the error.
+ return res;
}
-
+
// Calculate the hash on the contents
const uint64_t hash = getHashCode64((const char*)outFileContents->getBufferPointer(), outFileContents->getBufferSize());
diff --git a/source/core/slang-file-system.h b/source/core/slang-file-system.h
index 1a27ddc83..8a9cfb811 100644
--- a/source/core/slang-file-system.h
+++ b/source/core/slang-file-system.h
@@ -176,7 +176,9 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
protected:
- /// Given a path, works out a uniqueIdentity, based on the uniqueIdentityMode. outFileContents will be set if file had to be read to produce the uniqueIdentity (ie with Hash)
+ /// Given a path, works out a uniqueIdentity, based on the uniqueIdentityMode.
+ /// outFileContents will be set if file had to be read to produce the uniqueIdentity (ie with Hash)
+ /// If the file doesn't have to be read, then outFileContents will be nullptr, even if it is backed by a file.
SlangResult _calcUniqueIdentity(const String& path, String& outUniqueIdentity, ComPtr<ISlangBlob>& outFileContents);
/// For a given path gets a PathInfo. Can return nullptr, if it is not possible to create the PathInfo for some reason