summaryrefslogtreecommitdiffstats
path: root/source/core/slang-string-util.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-06-01 16:58:07 -0400
committerGitHub <noreply@github.com>2021-06-01 16:58:07 -0400
commit7a3c87b58de2683c077bd5341052c2e3cebeb048 (patch)
tree8641667ebcfecd728bfe8b572822751fae1c55bd /source/core/slang-string-util.cpp
parent67486ee516ddc33806003727682cbfc68ab1f726 (diff)
JSONValue / Container (#1864)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP JSONWriter/JSONParser. * Checking different Layout styles for JSON. * Add slang-json-parser.h/.cpp * WIP JSONValue. * Added JSONValue::destroy/Recursive. * Improvement to JSONValue. * Improve text double conversion precision. Testing. * Simplify double parsing (just use atof). JSON comparison More testing of conversions and start of JSONValue. * Add <math.h> for isnan, isinf etc. * Small improvement with object comparison. * Fix typo in getArgsByName. * Removed use of isnan and isinf as includes don't work on linux. * Improve JSON unit test. * Added asInteger/asFloat/asBool to JSONValue. * Change comment to trigger CI build.
Diffstat (limited to 'source/core/slang-string-util.cpp')
-rw-r--r--source/core/slang-string-util.cpp100
1 files changed, 96 insertions, 4 deletions
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index 7a142f643..b2886c413 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -458,9 +458,31 @@ ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
}
}
-SLANG_FORCE_INLINE static bool _isDigit(char c)
+/* static */SlangResult StringUtil::parseDouble(const UnownedStringSlice& text, double& out)
{
- return (c >= '0' && c <= '9');
+ const Index bufSize = 32;
+
+ const auto len = text.getLength();
+
+ if (len > bufSize - 1)
+ {
+ List<char> work;
+ work.setCount(len + 1);
+ char* dst = work.getBuffer();
+
+ ::memcpy(dst, text.begin(), len * sizeof(char));
+ dst[len] = 0;
+
+ out = atof(dst);
+ }
+ else
+ {
+ char buf[bufSize];
+ ::memcpy(buf, text.begin(), len * sizeof(char));
+ buf[len] = 0;
+ out = atof(buf);
+ }
+ return SLANG_OK;
}
/* static */SlangResult StringUtil::parseInt(const UnownedStringSlice& in, Int& outValue)
@@ -476,7 +498,7 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
}
// We need at least one digit
- if (cur >= end || !_isDigit(*cur))
+ if (cur >= end || !CharUtil::isDigit(*cur))
{
return SLANG_FAIL;
}
@@ -486,7 +508,7 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
for (; cur < end; ++cur)
{
const char c = *cur;
- if (!_isDigit(c))
+ if (!CharUtil::isDigit(c))
{
return SLANG_FAIL;
}
@@ -499,4 +521,74 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
return SLANG_OK;
}
+/* static */SlangResult StringUtil::parseInt64(const UnownedStringSlice& text, int64_t& out)
+{
+ bool negate = false;
+
+ const char* cur = text.begin();
+ const char* end = text.end();
+
+ if (cur < end)
+ {
+ if (*cur == '-')
+ {
+ negate = true;
+ cur++;
+ }
+ else if (*cur == '+')
+ {
+ cur++;
+ }
+ }
+
+ // Must have at least one digit
+ if (cur >= end || !CharUtil::isDigit(*cur))
+ {
+ return SLANG_FAIL;
+ }
+
+ uint64_t value = 0;
+ // We can have 20 digits, but the last digit can cause overflow.
+ // Lets do the easy first digits first
+ Index numSimple = 19;
+ for (; cur < end && CharUtil::isDigit(*cur) && numSimple > 0; ++cur, --numSimple)
+ {
+ value = value * 10 + (*cur - '0');
+ }
+
+ if (cur < end && CharUtil::isDigit(*cur))
+ {
+ const auto prevValue = value;
+ value = value * 10 + (*cur - '0');
+ cur++;
+
+ if (value < prevValue)
+ {
+ // We have overflow
+ return SLANG_FAIL;
+ }
+ }
+
+ if (negate)
+ {
+ if (value > ~((~uint64_t(0)) >> 1))
+ {
+ // Overflow
+ return SLANG_FAIL;
+ }
+ out = -int64_t(value);
+ }
+ else
+ {
+ if (value > ((~uint64_t(0)) >> 1))
+ {
+ // Overflow
+ return SLANG_FAIL;
+ }
+ out = value;
+ }
+
+ return (cur == end) ? SLANG_OK : SLANG_FAIL;
+}
+
} // namespace Slang