summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/core.vcxproj2
-rw-r--r--source/core/core.vcxproj.filters6
-rw-r--r--source/core/slang-semantic-version.cpp50
-rw-r--r--source/core/slang-semantic-version.h56
-rw-r--r--source/core/slang-string-slice-pool.cpp17
-rw-r--r--source/core/slang-string-slice-pool.h3
-rw-r--r--source/core/slang-string-util.cpp41
-rw-r--r--source/core/slang-string-util.h5
-rw-r--r--source/core/slang-string.h6
9 files changed, 186 insertions, 0 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj
index fe3d45f1b..636edb46a 100644
--- a/source/core/core.vcxproj
+++ b/source/core/core.vcxproj
@@ -197,6 +197,7 @@
<ClInclude Include="slang-render-api-util.h" />
<ClInclude Include="slang-riff.h" />
<ClInclude Include="slang-secure-crt.h" />
+ <ClInclude Include="slang-semantic-version.h" />
<ClInclude Include="slang-shared-library.h" />
<ClInclude Include="slang-smart-pointer.h" />
<ClInclude Include="slang-std-writers.h" />
@@ -230,6 +231,7 @@
<ClCompile Include="slang-random-generator.cpp" />
<ClCompile Include="slang-render-api-util.cpp" />
<ClCompile Include="slang-riff.cpp" />
+ <ClCompile Include="slang-semantic-version.cpp" />
<ClCompile Include="slang-shared-library.cpp" />
<ClCompile Include="slang-std-writers.cpp" />
<ClCompile Include="slang-stream.cpp" />
diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters
index aeac70769..49d8a1065 100644
--- a/source/core/core.vcxproj.filters
+++ b/source/core/core.vcxproj.filters
@@ -90,6 +90,9 @@
<ClInclude Include="slang-secure-crt.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-semantic-version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-shared-library.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -185,6 +188,9 @@
<ClCompile Include="slang-riff.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-semantic-version.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-shared-library.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp
new file mode 100644
index 000000000..93536e007
--- /dev/null
+++ b/source/core/slang-semantic-version.cpp
@@ -0,0 +1,50 @@
+// slang-semantic-version.cpp
+#include "slang-semantic-version.h"
+
+#include "../../slang-com-helper.h"
+
+#include "../core/slang-string-util.h"
+
+namespace Slang {
+
+SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion)
+{
+ outVersion.reset();
+
+ UnownedStringSlice slices[3];
+ Index splitCount;
+ SLANG_RETURN_ON_FAIL(StringUtil::split(value, '.', 3, slices, splitCount));
+ if (splitCount <= 0)
+ {
+ return SLANG_FAIL;
+ }
+
+ Int ints[3] = { 0, 0, 0 };
+ for (Index i = 0; i < splitCount; i++)
+ {
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[i], ints[i]));
+
+ const Int max = (i == 0) ? 0x7fffffff : 0xffff;
+ if (ints[i] < 0 || ints[i] > max)
+ {
+ return SLANG_FAIL;
+ }
+ }
+
+ outVersion.m_major = uint32_t(ints[0]);
+ outVersion.m_minor = uint16_t(ints[1]);
+ outVersion.m_patch = uint16_t(ints[2]);
+
+ return SLANG_OK;
+}
+
+void SemanticVersion::append(StringBuilder& buf) const
+{
+ buf << Int32(m_major) << "." << Int32(m_minor);
+ if (m_patch != 0)
+ {
+ buf << "." << Int32(m_patch);
+ }
+}
+
+} // namespace Slang
diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h
new file mode 100644
index 000000000..bbfcb663e
--- /dev/null
+++ b/source/core/slang-semantic-version.h
@@ -0,0 +1,56 @@
+// slang-semantic-version.h
+#ifndef SLANG_SEMANTIC_VERSION_H
+#define SLANG_SEMANTIC_VERSION_H
+
+#include "../core/slang-basic.h"
+
+namespace Slang
+{
+
+struct SemanticVersion
+{
+ typedef SemanticVersion ThisType;
+
+ typedef uint64_t IntegerType;
+
+ SemanticVersion():m_major(0), m_minor(0), m_patch(0) {}
+ SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0):
+ m_major(uint8_t(inMajor)),
+ m_minor(uint8_t(inMinor)),
+ m_patch(uint8_t(inPatch))
+ {}
+
+ void reset()
+ {
+ m_major = 0;
+ m_minor = 0;
+ m_patch = 0;
+ }
+
+ IntegerType toInteger() const { return (IntegerType(m_major) << 32) | (uint32_t(m_minor) << 16) | m_patch; }
+ void setFromInteger(IntegerType v)
+ {
+ m_major = (v >> 32);
+ m_minor = uint16_t(v >> 16);
+ m_patch = uint16_t(v);
+ }
+
+ static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion);
+ void append(StringBuilder& buf) const;
+
+ bool operator>(const ThisType& rhs) const { return toInteger() > rhs.toInteger(); }
+ bool operator>=(const ThisType& rhs) const { return toInteger() >= rhs.toInteger(); }
+
+ bool operator<(const ThisType& rhs) const { return toInteger() < rhs.toInteger(); }
+ bool operator<=(const ThisType& rhs) const { return toInteger() <= rhs.toInteger(); }
+
+ bool operator==(const ThisType& rhs) const { return toInteger() == rhs.toInteger(); }
+ bool operator!=(const ThisType& rhs) const { return toInteger() != rhs.toInteger(); }
+
+ uint32_t m_major;
+ uint16_t m_minor;
+ uint16_t m_patch;
+};
+
+}
+#endif
diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp
index be7bec785..24187ba5c 100644
--- a/source/core/slang-string-slice-pool.cpp
+++ b/source/core/slang-string-slice-pool.cpp
@@ -59,6 +59,23 @@ StringSlicePool::Handle StringSlicePool::add(const Slice& slice)
return Handle(index);
}
+bool StringSlicePool::findOrAdd(const Slice& slice, Handle& outHandle)
+{
+ Handle newHandle = Handle(m_slices.getCount());
+ const Handle* handlePtr = m_map.TryGetValueOrAdd(slice, newHandle);
+ if (handlePtr)
+ {
+ outHandle = *handlePtr;
+ return true;
+ }
+
+ // Need to add
+ UnownedStringSlice scopeSlice(m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength());
+ m_slices.add(scopeSlice);
+ outHandle = newHandle;
+ return false;
+}
+
StringSlicePool::Handle StringSlicePool::add(StringRepresentation* stringRep)
{
if (stringRep == nullptr && m_style == Style::Default)
diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h
index 2e4b41333..765119360 100644
--- a/source/core/slang-string-slice-pool.h
+++ b/source/core/slang-string-slice-pool.h
@@ -64,6 +64,9 @@ public:
/// Add a string
Handle add(const String& string) { return add(string.getUnownedSlice()); }
+ /// Returns true if found
+ bool findOrAdd(const Slice& slice, Handle& outHandle);
+
/// Empty contents
void clear();
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index 32f017f46..f961e6060 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -30,6 +30,47 @@ namespace Slang {
}
}
+/* static */Index StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices)
+{
+ Index index = 0;
+
+ const char* start = in.begin();
+ const char* end = in.end();
+
+ while (start < end && index < maxSlices)
+ {
+ // Move cur so it's either at the end or at next split character
+ const char* cur = start;
+ while (cur < end && *cur != splitChar)
+ {
+ cur++;
+ }
+
+ // Add to output
+ outSlices[index++] = UnownedStringSlice(start, cur);
+
+ // Skip the split character, if at end we are okay anyway
+ start = cur + 1;
+ }
+
+ return index;
+}
+
+/* static */SlangResult StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount)
+{
+ const Index sliceCount = split(in, splitChar, maxSlices, outSlices);
+ if (sliceCount == maxSlices && sliceCount > 0)
+ {
+ // To succeed must have parsed all of the input
+ if (in.end() != outSlices[sliceCount - 1].end())
+ {
+ return SLANG_FAIL;
+ }
+ }
+ outSlicesCount = sliceCount;
+ return SLANG_OK;
+}
+
/* static */void StringUtil::join(const List<String>& values, char separator, StringBuilder& out)
{
join(values, UnownedStringSlice(&separator, 1), out);
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index 16588bd35..ad25dc9a1 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -17,6 +17,11 @@ struct StringUtil
/// Slices contents will directly address into in, so contents will only stay valid as long as in does.
static void split(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& slicesOut);
+ /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs out of space).
+ static Index split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices);
+ /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed.
+ static SlangResult split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount);
+
/// Append the joining of in items, separated by 'separator' onto out
static void join(const List<String>& in, char separator, StringBuilder& out);
static void join(const List<String>& in, const UnownedStringSlice& separator, StringBuilder& out);
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 3fb612af3..10bc76048 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -93,6 +93,12 @@ namespace Slang
return m_end;
}
+ /// True if slice is strictly contained in memory.
+ bool isMemoryContained(const UnownedStringSlice& slice) const
+ {
+ return slice.m_begin >= m_begin && slice.m_end <= m_end;
+ }
+
Index getLength() const
{
return Index(m_end - m_begin);