diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-10-26 08:16:54 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-26 08:16:54 -0400 |
| commit | cb9d679a3a93c65c44904bf77811b9d74e431e23 (patch) | |
| tree | bdc78bc01351f6eeed4714d01cd3aef6cf067109 /source/core | |
| parent | ad47fe71defcc96a7bed87a4c3a40543978f0fb8 (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.vcxproj | 2 | ||||
| -rw-r--r-- | source/core/core.vcxproj.filters | 4 | ||||
| -rw-r--r-- | source/core/slang-io.cpp | 99 | ||||
| -rw-r--r-- | source/core/slang-io.h | 11 | ||||
| -rw-r--r-- | source/core/slang-string-util.cpp | 37 | ||||
| -rw-r--r-- | source/core/slang-string-util.h | 41 |
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 |
