diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-11-18 15:58:12 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-18 15:58:12 -0500 |
| commit | 1d5f815b3964edee8a2d701e1a6cc078c89d677f (patch) | |
| tree | aa5b4b1473344e635d7ce1d2159fc57eeb40b841 /source/compiler-core/slang-json-value.cpp | |
| parent | b482844b689eb109ee1d70c527e098400ac6d409 (diff) | |
RTTI/JSON (#2021)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Use 'Process' to communicate with an command line tool.
* Remove slang-win-stream
* Tidy up windows ProcessUtil.
* First version of BufferedReadStream.
* Windows working IPC for steams.
* Test proxy count option.
* Split Process/ProcessUtil. Process is platform dependant. ProcessUtil are functions that are platform independent.
* First implementation of Unix Process interface.
* Unix process compiles on cygwin.
* Fix typo in unix process.
* Separate unix pipe stream error of invalid access, from pipe availability.
* Fix in standard line extraction.
* Make fd non blocking.
* Fix issues with Windows Process streams.
* Added UnixPipe.
* Some fixes around UnixPipeStream.
* Make a unix stream closed explicit.
* Hack to debug linux process/stream.
* Revert to old linux pipe handling.
* Pass executable path for unit tests.
Split out CommandLine into own source.
* Small improvements in process/command line.
* Check process behavior with crash.
* Make stderr and stdout unbuffered for crash testing.
* Only turn disable buffering in crash test.
* Disable crash test on CI.
* Fix crash on clang/linux.
* Enable crash test.
Remove _appendBuffer as can use StreamUtil functionality.
* Added inital processing for http headers.
* Small improvements to HttpHeader.
* First pass HTTPPacketConnection working on windows.
* Enable other Process communication tests.
* Update comments.
* WIP JSON RPC.
* Add terminate to Process.
Made JSONRPC a Util.
* Small tidy up around HTTPPacketConnection.
* Improve process termination options.
* WIP for test-server.
* Add diagnostics error handling to test-server.
* Improved JSON support.
Parsing/creating JSON-RPC messages.
* WIP JSONRPC parsing.
* First pass RttiInfo support.
* WIP converting between JSON/native types.
* Project files.
* Split out RttiUtil.
Made RttiInfo constuction thread safe.
* WIP RTTI<->JSON.
* Add diagnostics to JSON<->native conversions.
* Make RttiInfo for structs globals. Avoids problem around derived types (like pointers), being able to cause an abort.
* Add pointer support to RTTI.
Fixed some compilation issues on linux.
* Add fixed array support.
* Added Rtti unit test.
* Add rtti unit test.
* Split out quoted/unquoted key handling.
Fix bugs in JSON value/container.
Added JSON native test.
* Make default array allocator use malloc/free.
Remove the new[] handler (doesn't work on visuals studio).
* Fix for linux warning.
* Remove some test code.
* Fix issues on x86 win.
* Fix warning on aarch64.
Diffstat (limited to 'source/compiler-core/slang-json-value.cpp')
| -rw-r--r-- | source/compiler-core/slang-json-value.cpp | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/source/compiler-core/slang-json-value.cpp b/source/compiler-core/slang-json-value.cpp index 9a2bb37f4..1e18bee39 100644 --- a/source/compiler-core/slang-json-value.cpp +++ b/source/compiler-core/slang-json-value.cpp @@ -26,6 +26,24 @@ namespace Slang { JSONValue::Kind::Object, // Object, }; +static bool _isDefault(const RttiInfo* type, const void* in) +{ + SLANG_UNUSED(type) + const JSONValue& value = *(const JSONValue*)in; + return value.getKind() == JSONValue::Kind::Invalid; +} + +static OtherRttiInfo _getJSONValueRttiInfo() +{ + OtherRttiInfo info; + info.init<JSONValue>(RttiInfo::Kind::Other); + info.m_name = "JSONValue"; + info.m_isDefaultFunc = _isDefault; + info.m_typeFuncs = GetRttiTypeFuncs<JSONValue>::getFuncs(); + return info; +} +/* static */const OtherRttiInfo JSONValue::g_rttiInfo = _getJSONValueRttiInfo(); + static JSONKeyValue _makeInvalidKeyValue() { JSONKeyValue keyValue; @@ -204,7 +222,7 @@ JSONValue JSONContainer::createArray(const JSONValue* values, Index valuesCount, JSONValue value; value.type = JSONValue::Type::Array; value.loc = loc; - value.rangeIndex = _addRange(Range::Type::Array, m_objectValues.getCount(), valuesCount); + value.rangeIndex = _addRange(Range::Type::Array, m_arrayValues.getCount(), valuesCount); m_arrayValues.addRange(values, valuesCount); return value; @@ -240,6 +258,12 @@ JSONKey JSONContainer::getKey(const UnownedStringSlice& slice) return JSONKey(m_slicePool.add(slice)); } +JSONKey JSONContainer::findKey(const UnownedStringSlice& slice) const +{ + const Index index = m_slicePool.findIndex(slice); + return (index < 0) ? JSONKey(0) : JSONKey(index); +} + ConstArrayView<JSONValue> JSONContainer::getArray(const JSONValue& in) const { SLANG_ASSERT(in.type == JSONValue::Type::Array); @@ -271,6 +295,8 @@ ArrayView<JSONValue> JSONContainer::getArray(const JSONValue& in) return ArrayView<JSONValue>((JSONValue*)nullptr, 0); } const Range& range = m_ranges[in.rangeIndex]; + SLANG_ASSERT(range.startIndex <= m_arrayValues.getCount() && range.startIndex + range.count <= m_arrayValues.getCount()); + return ArrayView<JSONValue>(m_arrayValues.getBuffer() + range.startIndex, range.count); } @@ -311,9 +337,29 @@ UnownedStringSlice JSONContainer::getLexeme(const JSONValue& in) UnownedStringSlice JSONContainer::getString(const JSONValue& in) { + if (in.type == JSONValue::Type::StringValue) + { + return getStringFromKey(in.stringKey); + } + else if (in.type == JSONValue::Type::StringLexeme) + { + auto slice = getTransientString(in); + auto handle = m_slicePool.add(slice); + return m_slicePool.getSlice(handle); + } + + SLANG_ASSERT(!"Not a string type"); + return UnownedStringSlice(); +} + +UnownedStringSlice JSONContainer::getTransientString(const JSONValue& in) +{ switch (in.type) { - case JSONValue::Type::StringValue: return getStringFromKey(in.stringKey); + case JSONValue::Type::StringValue: + { + return getStringFromKey(in.stringKey); + } case JSONValue::Type::StringLexeme: { StringEscapeHandler* handler = StringEscapeUtil::getHandler(StringEscapeUtil::Style::JSON); @@ -340,7 +386,7 @@ UnownedStringSlice JSONContainer::getString(const JSONValue& in) JSONKey JSONContainer::getStringKey(const JSONValue& in) { - return (in.type == JSONValue::Type::StringValue) ? in.stringKey : getKey(getString(in)); + return (in.type == JSONValue::Type::StringValue) ? in.stringKey : getKey(getTransientString(in)); } bool JSONContainer::asBool(const JSONValue& value) @@ -393,6 +439,19 @@ double JSONContainer::asFloat(const JSONValue& value) } } +Index JSONContainer::findObjectIndex(const JSONValue& obj, JSONKey key) const +{ + auto pairs = getObject(obj); + return pairs.findFirstIndex([key](const JSONKeyValue& pair) -> bool { return pair.key == key; }); +} + +JSONValue JSONContainer::findObjectValue(const JSONValue& obj, JSONKey key) const +{ + auto pairs = getObject(obj); + const Index index = pairs.findFirstIndex([key](const JSONKeyValue& pair) -> bool { return pair.key == key; }); + return (index >= 0) ? pairs[index].value : JSONValue::makeInvalid(); +} + JSONValue& JSONContainer::getAt(const JSONValue& array, Index index) { SLANG_ASSERT(array.type == JSONValue::Type::Array); @@ -742,6 +801,11 @@ bool JSONContainer::areEqual(const JSONKeyValue* a, const JSONKeyValue* b, Index } } +bool JSONContainer::areEqual(const JSONValue& a, const UnownedStringSlice& slice) +{ + return a.getKind() == JSONValue::Kind::String && getTransientString(a) == slice; +} + bool JSONContainer::areEqual(const JSONValue& a, const JSONValue& b) { if (&a == &b) @@ -864,7 +928,7 @@ void JSONContainer::traverseRecursively(const JSONValue& value, JSONListener* li { // Emit the key const auto keyString = getStringFromKey(objKeyValue.key); - listener->addKey(keyString, objKeyValue.keyLoc); + listener->addUnquotedKey(keyString, objKeyValue.keyLoc); // Emit the value associated with the key traverseRecursively(objKeyValue.value, listener); @@ -1035,7 +1099,16 @@ void JSONBuilder::endArray(SourceLoc loc) _add(value); } -void JSONBuilder::addKey(const UnownedStringSlice& key, SourceLoc loc) +void JSONBuilder::addQuotedKey(const UnownedStringSlice& key, SourceLoc loc) +{ + // We need to decode + m_work.Clear(); + StringEscapeHandler* handler = StringEscapeUtil::getHandler(StringEscapeUtil::Style::JSON); + StringEscapeUtil::appendUnquoted(handler, key, m_work); + addUnquotedKey(m_work.getUnownedSlice(), loc); +} + +void JSONBuilder::addUnquotedKey(const UnownedStringSlice& key, SourceLoc loc) { SLANG_ASSERT(m_keyValue.key == JSONKey(0)); m_keyValue.key = m_container->getKey(key); |
