summaryrefslogtreecommitdiffstats
path: root/source/compiler-core/slang-json-native.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler-core/slang-json-native.cpp')
-rw-r--r--source/compiler-core/slang-json-native.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/source/compiler-core/slang-json-native.cpp b/source/compiler-core/slang-json-native.cpp
index 9c972eba3..6e54457d0 100644
--- a/source/compiler-core/slang-json-native.cpp
+++ b/source/compiler-core/slang-json-native.cpp
@@ -252,6 +252,52 @@ SlangResult JSONToNativeConverter::convert(const JSONValue& in, const RttiInfo*
return SLANG_FAIL;
}
+SlangResult JSONToNativeConverter::convertArrayToStruct(const JSONValue& value, const RttiInfo* rttiInfo, void* out)
+{
+ // Check converting JSON array into a struct, as that's what this method supports
+ if (!(rttiInfo->m_kind == RttiInfo::Kind::Struct &&
+ value.getKind() == JSONValue::Kind::Array))
+ {
+ // If they are the wrong types then just fail
+ return SLANG_FAIL;
+ }
+
+ // Find the total amount of fields, and all the classes involved
+ Index totalFieldCount = 0;
+
+ ShortList<const StructRttiInfo*, 8> infos;
+ for (const StructRttiInfo* cur = static_cast<const StructRttiInfo*>(rttiInfo); cur; cur = cur->m_super)
+ {
+ totalFieldCount += cur->m_fieldCount;
+ infos.add(cur);
+ }
+
+ // Must have the same amount of fields
+ auto array = m_container->getArray(value);
+ if (array.getCount() != totalFieldCount)
+ {
+ return SLANG_FAIL;
+ }
+
+ Byte* dstBase = (Byte*)out;
+
+ // We work in the order from the base class to the final type
+ Index argIndex = 0;
+ for (Index i = infos.getCount() - 1; i >= 0; --i)
+ {
+ auto info = infos[i];
+
+ const Index fieldCount = info->m_fieldCount;
+ for (Index j = 0; j < fieldCount; ++j)
+ {
+ // Convert the field
+ const auto& field = info->m_fields[j];
+ SLANG_RETURN_ON_FAIL(convert(array[argIndex++], field.m_type, dstBase + field.m_offset));
+ }
+ }
+
+ return SLANG_OK;
+}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! NativeToJSONConverter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -420,4 +466,52 @@ SlangResult NativeToJSONConverter::convert(const RttiInfo* rttiInfo, const void*
return SLANG_E_NOT_IMPLEMENTED;
}
+SlangResult NativeToJSONConverter::convertStructToArray(const RttiInfo* rttiInfo, const void* in, JSONValue& out)
+{
+ if (rttiInfo->m_kind != RttiInfo::Kind::Struct)
+ {
+ // Must be a struct
+ return SLANG_FAIL;
+ }
+
+ // Work out the total amount of fields, and all invloved struct types
+ Index totalFieldsCount = 0;
+ ShortList<const StructRttiInfo*, 8> infos;
+ for (const StructRttiInfo* cur = static_cast<const StructRttiInfo*>(rttiInfo); cur; cur = cur->m_super)
+ {
+ totalFieldsCount += Index(cur->m_fieldCount);
+ infos.add(cur);
+ }
+
+ // Convert the args/params
+ List<JSONValue> argsArray;
+ argsArray.setCount(totalFieldsCount);
+
+ // NOTE! We do no special handling here around optional parameters.
+ // All fields of the input args are output
+ {
+ Index argsArrayIndex = 0;
+ const Byte* argsBase = (const Byte*)in;
+
+ // Work in the order from the base class to the actual type
+ for (Index i = infos.getCount() - 1; i >= 0; --i)
+ {
+ auto structRttiInfo = infos[i];
+ const Index fieldCount = Index(structRttiInfo->m_fieldCount);
+
+ for (Index j = 0; j < fieldCount; ++j)
+ {
+ const auto& field = structRttiInfo->m_fields[j];
+ // Convert the field
+ SLANG_RETURN_ON_FAIL(convert(field.m_type, argsBase + field.m_offset, argsArray[argsArrayIndex++]));
+ }
+ }
+ }
+
+ // Okay now we convert the List to the output, which will just be a JSON array.
+ SLANG_RETURN_ON_FAIL(convert(&argsArray, out));
+
+ return SLANG_OK;
+}
+
} // namespace Slang