summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/core/hash.h15
-rw-r--r--source/slang/slang-file-system.cpp135
-rw-r--r--source/slang/slang-file-system.h23
-rw-r--r--source/slang/slang.cpp14
4 files changed, 137 insertions, 50 deletions
diff --git a/source/core/hash.h b/source/core/hash.h
index ca6172fc7..fc0bca737 100644
--- a/source/core/hash.h
+++ b/source/core/hash.h
@@ -43,7 +43,18 @@ namespace Slang
}
return hash;
}
-
+
+ inline uint64_t GetHashCode64(const char * buffer, size_t numChars)
+ {
+ // Use uints because hash requires wrap around behavior and int is undefined on over/underflows
+ uint64_t hash = 0;
+ for (size_t i = 0; i < numChars; ++i)
+ {
+ hash = uint64_t(int64_t(buffer[i])) + (hash << 6) + (hash << 16) - hash;
+ }
+ return hash;
+ }
+
template<int IsInt>
class Hash
{
@@ -111,4 +122,4 @@ namespace Slang
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/source/slang/slang-file-system.cpp b/source/slang/slang-file-system.cpp
index ef77dbf33..caaa9f56d 100644
--- a/source/slang/slang-file-system.cpp
+++ b/source/slang/slang-file-system.cpp
@@ -14,8 +14,8 @@ static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown;
static const Guid IID_ISlangFileSystem = SLANG_UUID_ISlangFileSystem;
static const Guid IID_ISlangFileSystemExt = SLANG_UUID_ISlangFileSystemExt;
-// Cacluate a relative path, just using Path:: string processing
-static SlangResult _calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+// Cacluate a combined path, just using Path:: string processing
+static SlangResult _calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
{
String relPath;
switch (fromPathType)
@@ -60,9 +60,9 @@ SlangResult DefaultFileSystem::getCanoncialPath(const char* path, ISlangBlob** c
return SLANG_OK;
}
-SlangResult DefaultFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult DefaultFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
{
- return _calcRelativePath(fromPathType, fromPath, path, pathOut);
+ return _calcCombinedPath(fromPathType, fromPath, path, pathOut);
}
SlangResult SLANG_MCALL DefaultFileSystem::getPathType(
@@ -127,12 +127,25 @@ ISlangUnknown* CacheFileSystem::getInterface(const Guid& guid)
return _getInterface(this, guid);
}
-CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, bool useSimplifyForCanonicalPath) :
+CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, CanonicalMode canonicalMode) :
m_fileSystem(fileSystem),
- m_useSimplifyForCanonicalPath(useSimplifyForCanonicalPath)
+ m_canonicalMode(canonicalMode)
{
// Try to get the more sophisticated interface
fileSystem->queryInterface(IID_ISlangFileSystemExt, (void**)m_fileSystemExt.writeRef());
+
+ switch (canonicalMode)
+ {
+ case CanonicalMode::Default:
+ case CanonicalMode::FileSystemExt:
+ {
+ m_canonicalMode = m_fileSystemExt ? CanonicalMode::FileSystemExt : CanonicalMode::Hash;
+ break;
+ }
+ default: break;
+ }
+ // It can't be default
+ SLANG_ASSERT(m_canonicalMode != CanonicalMode::Default);
}
CacheFileSystem::~CacheFileSystem()
@@ -143,45 +156,95 @@ CacheFileSystem::~CacheFileSystem()
}
}
-CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfo(const String& relPath)
+CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfoFromCanonical(const String& canonicalPath)
{
- PathInfo** infoPtr = m_pathMap.TryGetValue(relPath);
+ // First see if we have it.. if not add it
+ PathInfo** infoPtr = m_canonicalMap.TryGetValue(canonicalPath);
if (infoPtr)
{
return *infoPtr;
}
-
- String canonicalPath;
- if (m_fileSystemExt)
- {
- // Try getting the canonical path
- // Okay request from the underlying file system the canonical path
- ComPtr<ISlangBlob> canonicalBlob;
- if (SLANG_FAILED(m_fileSystemExt->getCanoncialPath(relPath.Buffer(), canonicalBlob.writeRef())))
- {
- // Write in result as being null ptr so not tried again
- m_pathMap.Add(relPath, nullptr);
- return nullptr;
- }
- // Get the path as a string
- canonicalPath = StringUtil::getString(canonicalBlob);
- }
else
{
- canonicalPath = m_useSimplifyForCanonicalPath ? Path::Simplify(relPath.getUnownedSlice()) : relPath;
+ // Create and add to canonical path
+ PathInfo* pathInfo = new PathInfo(canonicalPath);
+ m_canonicalMap.Add(canonicalPath, pathInfo);
+ return pathInfo;
}
+}
- PathInfo* pathInfo;
- infoPtr = m_canonicalMap.TryGetValue(canonicalPath);
+CacheFileSystem::PathInfo* CacheFileSystem::_getPathInfo(const String& relPath)
+{
+ PathInfo** infoPtr = m_pathMap.TryGetValue(relPath);
if (infoPtr)
{
- pathInfo = *infoPtr;
+ return *infoPtr;
}
- else
+
+ PathInfo* pathInfo = nullptr;
+ switch (m_canonicalMode)
{
- // Create and add to canonical path
- pathInfo = new PathInfo(canonicalPath);
- m_canonicalMap.Add(canonicalPath, pathInfo);
+ case CanonicalMode::FileSystemExt:
+ {
+ // Try getting the canonical path
+ // Okay request from the underlying file system the canonical path
+ ComPtr<ISlangBlob> canonicalBlob;
+ if (SLANG_FAILED(m_fileSystemExt->getCanoncialPath(relPath.Buffer(), canonicalBlob.writeRef())))
+ {
+ // Write in result as being null ptr so not tried again
+ m_pathMap.Add(relPath, nullptr);
+ return nullptr;
+ }
+ // Get the path as a string
+ String canonicalPath = StringUtil::getString(canonicalBlob);
+ pathInfo = _getPathInfoFromCanonical(canonicalPath);
+ break;
+ }
+ case CanonicalMode::Path:
+ {
+ pathInfo = _getPathInfoFromCanonical(relPath);
+ break;
+ }
+ case CanonicalMode::SimplifiedPath:
+ {
+ pathInfo = _getPathInfoFromCanonical(Path::Simplify(relPath.getUnownedSlice()));
+ break;
+ }
+ case CanonicalMode::Hash:
+ {
+ // I can only see if this is the same file as already loaded by loading the file and doing a hash
+ ComPtr<ISlangBlob> fileBlob;
+ Result res = m_fileSystem->loadFile(relPath.Buffer(), fileBlob.writeRef());
+ if (SLANG_FAILED(res) || fileBlob == nullptr)
+ {
+ // Write in result as being null ptr so not tried again
+ m_pathMap.Add(relPath, nullptr);
+ return nullptr;
+ }
+
+ // Calculate the hash on the contents
+ const uint64_t hash = GetHashCode64((const char*)fileBlob->getBufferPointer(), fileBlob->getBufferSize());
+
+ String hashString = Path::GetFileName(relPath);
+ hashString = hashString.ToLower();
+
+ hashString.append(':');
+
+ // The canonical name is.. combination of name and hash
+ hashString.append(hash, 16);
+ // We'll use the 'hashString' as the canonical path
+ pathInfo = _getPathInfoFromCanonical(hashString);
+
+ // We have the contents, so store it on the PathInfo, along with the result
+ if (pathInfo->m_loadFileResult == CompressedResult::Uninitialized)
+ {
+ // Save the contents of the saved file
+ pathInfo->m_loadFileResult = toCompressedResult(res);
+ pathInfo->m_fileBlob = fileBlob;
+ }
+
+ break;
+ }
}
// Add the relPath
@@ -224,17 +287,17 @@ SlangResult CacheFileSystem::getCanoncialPath(const char* path, ISlangBlob** can
return SLANG_OK;
}
-SlangResult CacheFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult CacheFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
{
// Just defer to contained implementation
if (m_fileSystemExt)
{
- return m_fileSystemExt->calcRelativePath(fromPathType, fromPath, path, pathOut);
+ return m_fileSystemExt->calcCombinedPath(fromPathType, fromPath, path, pathOut);
}
else
{
// Just use the default implementation
- return _calcRelativePath(fromPathType, fromPath, path, pathOut);
+ return _calcCombinedPath(fromPathType, fromPath, path, pathOut);
}
}
@@ -272,4 +335,4 @@ SlangResult CacheFileSystem::getPathType(const char* pathIn, SlangPathType* path
return toResult(info->m_getPathTypeResult);
}
-} \ No newline at end of file
+}
diff --git a/source/slang/slang-file-system.h b/source/slang/slang-file-system.h
index b22dc4cb9..c949c66ff 100644
--- a/source/slang/slang-file-system.h
+++ b/source/slang/slang-file-system.h
@@ -30,7 +30,7 @@ public:
const char* path,
ISlangBlob** canonicalPathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcRelativePath(
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
SlangPathType fromPathType,
const char* fromPath,
const char* path,
@@ -68,6 +68,15 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
{
public:
+ enum CanonicalMode
+ {
+ Default, ///< If passed, will default to the others depending on what kind of ISlangFileSystem is passed in
+ Path, ///< Just use the path as is
+ SimplifiedPath, ///< Use the input path 'simplified' (ie removing . and .. aspects)
+ Hash, ///< Use hashing
+ FileSystemExt, ///< Use the file system extended interface.
+ };
+
/* Cannot change order/add members without changing s_compressedResultToResult */
enum class CompressedResult: uint8_t
{
@@ -92,7 +101,7 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
const char* path,
ISlangBlob** canonicalPathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcRelativePath(
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
SlangPathType fromPathType,
const char* fromPath,
const char* path,
@@ -103,7 +112,7 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
SlangPathType* pathTypeOut) SLANG_OVERRIDE;
/// Ctor
- CacheFileSystem(ISlangFileSystem* fileSystem, bool useSimplifyForCanonicalPath = false);
+ CacheFileSystem(ISlangFileSystem* fileSystem, CanonicalMode canonicalMode = CanonicalMode::Default);
/// Dtor
virtual ~CacheFileSystem();
@@ -123,6 +132,8 @@ protected:
m_loadFileResult = CompressedResult::Uninitialized;
m_getPathTypeResult = CompressedResult::Uninitialized;
+
+ m_pathType = SLANG_PATH_TYPE_FILE;
}
~PathInfo()
{
@@ -140,6 +151,8 @@ protected:
/// For a given relPath gets a PathInfo
PathInfo* _getPathInfo(const String& relPath);
+ /// Get path from a canonical path
+ PathInfo* _getPathInfoFromCanonical(const String& canonicalPath);
/* TODO: This may be improved by mapping to a ISlangBlob. This makes output fast and easy, and if constructed
as a StringBlob, we can just static_cast to get as a string to use internally, instead of constantly converting.
@@ -149,7 +162,7 @@ protected:
Dictionary<String, PathInfo*> m_pathMap; ///< Maps a path to a canonical path
Dictionary<String, PathInfo*> m_canonicalMap; ///< Maps a canonical path to a files contents. This OWNs the PathInfo.
- bool m_useSimplifyForCanonicalPath; ///< If set will use Path::Simplify to create 'canonical' paths
+ CanonicalMode m_canonicalMode; ///< Determines how 'canonicalPath' is produced. Cannot be Default in usage.
ComPtr<ISlangFileSystem> m_fileSystem; ///< Must always be set
ComPtr<ISlangFileSystemExt> m_fileSystemExt; ///< Optionally set -> if not will fall back on the m_fileSystem
@@ -157,4 +170,4 @@ protected:
}
-#endif // SLANG_FILE_SYSTEM_H_INCLUDED \ No newline at end of file
+#endif // SLANG_FILE_SYSTEM_H_INCLUDED
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 38b417960..23f7a4e47 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -102,16 +102,16 @@ struct IncludeHandlerImpl : IncludeHandler
ISlangFileSystemExt* fileSystemExt = _getFileSystemExt();
// Get relative path
- ComPtr<ISlangBlob> relPathBlob;
- SLANG_RETURN_ON_FAIL(fileSystemExt->calcRelativePath(fromPathType, fromPath.begin(), path.begin(), relPathBlob.writeRef()));
- String relPath(StringUtil::getString(relPathBlob));
- if (relPath.Length() <= 0)
+ ComPtr<ISlangBlob> combinedPathBlob;
+ SLANG_RETURN_ON_FAIL(fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef()));
+ String combinedPath(StringUtil::getString(combinedPathBlob));
+ if (combinedPath.Length() <= 0)
{
return SLANG_FAIL;
}
SlangPathType pathType;
- SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(relPath.begin(), &pathType));
+ SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(combinedPath.begin(), &pathType));
if (pathType != SLANG_PATH_TYPE_FILE)
{
return SLANG_E_NOT_FOUND;
@@ -119,7 +119,7 @@ struct IncludeHandlerImpl : IncludeHandler
// Get the canonical path
ComPtr<ISlangBlob> canonicalPathBlob;
- SLANG_RETURN_ON_FAIL(fileSystemExt->getCanoncialPath(relPath.begin(), canonicalPathBlob.writeRef()));
+ SLANG_RETURN_ON_FAIL(fileSystemExt->getCanoncialPath(combinedPath.begin(), canonicalPathBlob.writeRef()));
// If the rel path exists -> the canonical path MUST exists too
String canonicalPath(StringUtil::getString(canonicalPathBlob));
@@ -130,7 +130,7 @@ struct IncludeHandlerImpl : IncludeHandler
}
pathInfoOut.type = PathInfo::Type::Normal;
- pathInfoOut.foundPath = relPath;
+ pathInfoOut.foundPath = combinedPath;
pathInfoOut.canonicalPath = canonicalPath;
return SLANG_OK;
}