diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-06-01 16:58:07 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-01 16:58:07 -0400 |
| commit | 7a3c87b58de2683c077bd5341052c2e3cebeb048 (patch) | |
| tree | 8641667ebcfecd728bfe8b572822751fae1c55bd /source/core/slang-string-util.cpp | |
| parent | 67486ee516ddc33806003727682cbfc68ab1f726 (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.cpp | 100 |
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 |
