diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-04-20 14:04:31 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-20 14:04:31 -0400 |
| commit | 6bba674f9d732eccc27dcf004611e6a8eb9bc14e (patch) | |
| tree | e78757692346c19e614df35330a41134c2c67758 | |
| parent | 778428fecc0548af565e92745cf1344bcf19367f (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.h | 14 | ||||
| -rw-r--r-- | source/core/slang-file-system.cpp | 32 | ||||
| -rw-r--r-- | source/core/slang-file-system.h | 4 |
3 files changed, 40 insertions, 10 deletions
@@ -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 |
