summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-10-26 08:16:54 -0400
committerGitHub <noreply@github.com>2018-10-26 08:16:54 -0400
commitcb9d679a3a93c65c44904bf77811b9d74e431e23 (patch)
treebdc78bc01351f6eeed4714d01cd3aef6cf067109 /source/core
parentad47fe71defcc96a7bed87a4c3a40543978f0fb8 (diff)
Feature/file system cache (#692)
* First pass at caching file system. * default-file-system -> slang-file-system fix problem with location("build.linux") confusing windows build for now. * Added CompressedResult Fix problem in Result construction with it being unsigned * Add support for Path simplification. * Testing for Path::Simplify. * Refactored CacheFileSystem - automatically handles ISlangFileSystem or ISlangFileSystemExt appropriately. Removed WrapFileSystem - because wasn't possible to emulate some of the behavior if just loadFile is implemented. Split out StringBlob - so that no need to convert between ISlangBlob and String repeatidly. * Remove unwanted code in ~CompileRequest
Diffstat (limited to 'source/core')
-rw-r--r--source/core/core.vcxproj2
-rw-r--r--source/core/core.vcxproj.filters4
-rw-r--r--source/core/slang-io.cpp99
-rw-r--r--source/core/slang-io.h11
-rw-r--r--source/core/slang-string-util.cpp37
-rw-r--r--source/core/slang-string-util.h41
6 files changed, 191 insertions, 3 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj
index d1ed4715f..2d0c67342 100644
--- a/source/core/core.vcxproj
+++ b/source/core/core.vcxproj
@@ -213,7 +213,7 @@
<ClCompile Include="token-reader.cpp" />
</ItemGroup>
<ItemGroup>
- <Natvis Include="core.natvis" />
+ <None Include="core.natvis" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters
index 7936ca11b..1548217b4 100644
--- a/source/core/core.vcxproj.filters
+++ b/source/core/core.vcxproj.filters
@@ -130,8 +130,8 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
- <Natvis Include="core.natvis">
+ <None Include="core.natvis">
<Filter>Source Files</Filter>
- </Natvis>
+ </None>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index 2b443a62b..f1948200c 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -123,6 +123,105 @@ namespace Slang
return sb.ProduceString();
}
+ /* static */ bool Path::IsDriveSpecification(const UnownedStringSlice& element)
+ {
+ switch (element.size())
+ {
+ case 0:
+ {
+ // We'll just assume it is
+ return true;
+ }
+ case 2:
+ {
+ // Look for a windows like drive spec
+ const char firstChar = element[0];
+ return element[1] == ':' && ((firstChar >= 'a' && firstChar <= 'z') || (firstChar >= 'A' && firstChar <= 'Z'));
+ }
+ default: return false;
+ }
+
+ }
+
+ /* static */void Path::Split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut)
+ {
+ splitOut.Clear();
+
+ const char* start = path.begin();
+ const char* end = path.end();
+
+ while (start < end)
+ {
+ const char* cur = start;
+ // Find the split
+ while (cur < end && !IsDelimiter(*cur)) cur++;
+
+ splitOut.Add(UnownedStringSlice(start, cur));
+
+ // Next
+ start = cur + 1;
+ }
+
+ // Okay if the end is empty. And we aren't with a spec like // or c:/ , then drop the final slash
+ if (splitOut.Count() > 1 && splitOut.Last().size() == 0)
+ {
+ if (splitOut.Count() == 2 && IsDriveSpecification(splitOut[0]))
+ {
+ return;
+ }
+ // Remove the last
+ splitOut.RemoveLast();
+ }
+ }
+
+ /* static */String Path::Simplify(const UnownedStringSlice& path)
+ {
+ List<UnownedStringSlice> split;
+ Split(path, split);
+
+ // Strictly speaking we could do something about case on platforms like window, but here we won't worry about that
+ for (int i = 0; i < int(split.Count()); i++)
+ {
+ const UnownedStringSlice& cur = split[i];
+ if (cur == "." && split.Count() > 1)
+ {
+ // Just remove it
+ split.RemoveAt(i);
+ i--;
+ }
+ else if (cur == ".." && i > 0)
+ {
+ // Can we remove this and the one before ?
+ UnownedStringSlice& before = split[i - 1];
+ if (before == ".." || (i == 1 && IsDriveSpecification(before)))
+ {
+ // Can't do it
+ continue;
+ }
+ split.RemoveRange(i - 1, 2);
+ i -= 2;
+ }
+ }
+
+ // If its empty it must be .
+ if (split.Count() == 0)
+ {
+ split.Add(UnownedStringSlice::fromLiteral("."));
+ }
+
+ // Reconstruct the string
+ StringBuilder builder;
+ for (int i = 0; i < int(split.Count()); i++)
+ {
+ if (i > 0)
+ {
+ builder.Append(PathDelimiter);
+ }
+ builder.Append(split[i]);
+ }
+ return builder;
+ }
+
bool Path::CreateDir(const String & path)
{
#if defined(_WIN32)
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index ff287254c..3703aee08 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -32,6 +32,17 @@ namespace Slang
static String Combine(const String & path1, const String & path2, const String & path3);
static bool CreateDir(const String & path);
+ /// Accept either style of delimiter
+ SLANG_FORCE_INLINE static bool IsDelimiter(char c) { return c == '/' || c == '\\'; }
+
+ static bool IsDriveSpecification(const UnownedStringSlice& element);
+
+ /// Splits the path into it's individual bits
+ static void Split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut);
+ /// Strips .. and . as much as it can
+ static String Simplify(const UnownedStringSlice& path);
+ static String Simplify(const String& path) { return Simplify(path.getUnownedSlice()); }
+
static SlangResult GetPathType(const String & path, SlangPathType* pathTypeOut);
static SlangResult GetCanonical(const String & path, String& canonicalPathOut);
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index 29f8dc0ca..6d0d896a1 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -2,6 +2,19 @@
namespace Slang {
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+// Allocate static const storage for the various interface IDs that the Slang API needs to expose
+static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown;
+static const Guid IID_ISlangBlob = SLANG_UUID_ISlangBlob;
+
+/* static */ISlangUnknown* StringBlob::getInterface(const Guid& guid)
+{
+ return (guid == IID_ISlangUnknown || guid == IID_ISlangBlob) ? static_cast<ISlangBlob*>(this) : nullptr;
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!
+
/* static */void StringUtil::split(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& slicesOut)
{
slicesOut.Clear();
@@ -74,4 +87,28 @@ namespace Slang {
return builder;
}
+/* static */String StringUtil::getString(ISlangBlob* blob)
+{
+ if (blob)
+ {
+ size_t size = blob->getBufferSize();
+ if (size > 0)
+ {
+ const char* contents = (const char*)blob->getBufferPointer();
+ // Check it has terminating 0, if not we must construct as if it does
+ if (contents[size - 1] == 0)
+ {
+ size--;
+ }
+ return String(contents, contents + size);
+ }
+ }
+ return String();
+}
+
+ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
+{
+ return ComPtr<ISlangBlob>(new StringBlob(string));
+}
+
} // namespace Slang
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index fc3258490..47d92f2fe 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -6,8 +6,41 @@
#include <stdarg.h>
+#include "../../slang-com-helper.h"
+#include "../../slang-com-ptr.h"
+
namespace Slang {
+/** A blob that uses a `String` for its storage.
+*/
+class StringBlob : public ISlangBlob
+{
+public:
+ // ISlangUnknown
+ SLANG_IUNKNOWN_ALL
+
+ // ISlangBlob
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_string.Buffer(); }
+ SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_string.Length(); }
+
+ /// Get the contained string
+ SLANG_FORCE_INLINE const String& getString() const { return m_string; }
+
+ explicit StringBlob(String const& string)
+ : m_string(string)
+ {}
+
+ /// Need virtual dtor, because BlobBase is derived from and release impl used is the one in the base class (that doesn't know the derived type)
+ /// Alternatively could be implemented by always using SLANG_IUNKNOWN_RELEASE in derived types - this would make derived types slightly smaller/faster
+ virtual ~StringBlob() {}
+
+protected:
+ ISlangUnknown* getInterface(const Guid& guid);
+
+ String m_string;
+ uint32_t m_refCount = 0;
+};
+
struct StringUtil
{
/// Split in, by specified splitChar into slices out
@@ -22,6 +55,14 @@ struct StringUtil
/// Create a string from the format string applying args (like sprintf)
static String makeStringWithFormat(const char* format, ...);
+
+ /// Given a string held in a blob, returns as a String
+ /// Returns an empty string if blob is nullptr
+ static String getString(ISlangBlob* blob);
+
+ /// Create a blob from a string
+ static ComPtr<ISlangBlob> createStringBlob(const String& string);
+
};
} // namespace Slang