Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosjsonconversions.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/qjsonarray.h>
6#include <QtCore/qjsonvalue.h>
7#include <QtCore/qstring.h>
8#include <cstdint>
9#include <napi.h>
10
11QT_BEGIN_NAMESPACE
12
13namespace QtOhos {
14
15namespace {
16
17constexpr int napiToJsonMappingNestingLimit = 1024;
18
19QJsonValue mapNapiValueToJsonValue(const QNapi::Value &napiValue, int remainingNestingLevels);
20QJsonObject mapNapiObjectToJsonObjectImpl(const QNapi::Object &napiObject, int remainingNestingLevels);
21QNapi::Value mapJsonValueToNapiValue(napi_env env, const QJsonValue &jsonValue);
22
23void checkNapiToJsonMappingRemainingNestingLevels(napi_env env, int remainingNestingLevels)
24{
25 if (remainingNestingLevels == 0)
26 throw QNapi::makeLoggedException(env, "JS value nested too deeply to be mapped to JSON");
27}
28
29QJsonArray mapNapiArrayToJsonArray(const QNapi::Array &napiArray, int remainingNestingLevels)
30{
31 checkNapiToJsonMappingRemainingNestingLevels(napiArray.Env(), remainingNestingLevels);
32 QJsonArray jsonArray;
33 const std::uint32_t arrayLength = napiArray.Length();
34 for (std::uint32_t i = 0; i < arrayLength; ++i) {
35 Napi::HandleScope elementScope(napiArray.Env());
36 auto jsonValue = mapNapiValueToJsonValue(napiArray.Get(i), remainingNestingLevels);
37 jsonArray.append(jsonValue.isUndefined() ? QJsonValue(QJsonValue::Null) : jsonValue);
38 }
39 return jsonArray;
40}
41
42QNapi::Array mapJsonArrayToNapiArray(napi_env env, const QJsonArray &jsonArray)
43{
44 return QNapi::runEscapingHandleScope<QNapi::Array>(
45 env,
46 [&]() {
47 const auto arrayLength = static_cast<std::uint32_t>(jsonArray.size());
48 auto napiArray = QNapi::Array::New(env, arrayLength);
49 for (std::uint32_t i = 0; i < arrayLength; ++i)
50 napiArray.Set(i, mapJsonValueToNapiValue(env, jsonArray.at(i)));
51 return napiArray;
52 });
53}
54
55QJsonValue mapNapiValueToJsonValue(const QNapi::Value &napiValue, int remainingNestingLevels)
56{
57 if (napiValue.IsNull())
58 return QJsonValue(QJsonValue::Null);
59 if (napiValue.IsBoolean())
60 return QJsonValue(QNapi::checkedCast<QNapi::Boolean>(napiValue).Value());
61 if (napiValue.IsNumber())
62 return QJsonValue(QNapi::checkedCast<QNapi::Number>(napiValue).DoubleValue());
63 if (napiValue.IsString())
64 return QJsonValue(QString::fromStdString(QNapi::checkedCast<QNapi::String>(napiValue)));
65 if (napiValue.IsArray())
66 return mapNapiArrayToJsonArray(QNapi::checkedCast<QNapi::Array>(napiValue), remainingNestingLevels - 1);
67 if (napiValue.IsObject() && !napiValue.IsFunction())
68 return mapNapiObjectToJsonObjectImpl(QNapi::checkedCast<QNapi::Object>(napiValue), remainingNestingLevels - 1);
69 return QJsonValue(QJsonValue::Undefined);
70}
71
72QNapi::Value mapJsonValueToNapiValue(napi_env env, const QJsonValue &jsonValue)
73{
74 switch (jsonValue.type()) {
75 case QJsonValue::Null:
76 case QJsonValue::Undefined:
77 return Napi::Env(env).Null();
78 case QJsonValue::Bool:
79 return QNapi::Boolean::New(env, jsonValue.toBool());
80 case QJsonValue::Double:
81 return QNapi::Number::New(env, jsonValue.toDouble());
82 case QJsonValue::String:
83 return QNapi::String::New(env, jsonValue.toString().toStdString());
84 case QJsonValue::Array:
85 return mapJsonArrayToNapiArray(env, jsonValue.toArray());
86 case QJsonValue::Object:
87 return mapJsonObjectToNapiObject(env, jsonValue.toObject());
88 }
89 Q_UNREACHABLE_RETURN(QNapi::Value());
90}
91
92QJsonObject mapNapiObjectToJsonObjectImpl(const QNapi::Object &napiObject, int remainingNestingLevels)
93{
94 checkNapiToJsonMappingRemainingNestingLevels(napiObject.Env(), remainingNestingLevels);
95 QJsonObject jsonObject;
96 for (const auto &property : napiObject) {
97 if (!property.first.IsString())
98 continue;
99 auto jsonValue = mapNapiValueToJsonValue(property.second, remainingNestingLevels);
100 if (!jsonValue.isUndefined())
101 jsonObject.insert(QString::fromStdString(QNapi::checkedCast<QNapi::String>(property.first)), jsonValue);
102 }
103 return jsonObject;
104}
105
106}
107
108QJsonObject mapNapiObjectToJsonObject(const QNapi::Object &napiObject)
109{
110 return mapNapiObjectToJsonObjectImpl(napiObject, napiToJsonMappingNestingLimit);
111}
112
113QNapi::Object mapJsonObjectToNapiObject(napi_env env, const QJsonObject &jsonObject)
114{
115 return QNapi::runEscapingHandleScope<QNapi::Object>(
116 env,
117 [&]() {
118 auto napiObject = QNapi::Object::New(env);
119 for (auto propertyIter = jsonObject.begin(); propertyIter != jsonObject.end(); ++propertyIter)
120 napiObject.Set(propertyIter.key().toStdString(), mapJsonValueToNapiValue(env, propertyIter.value()));
121 return napiObject;
122 });
123}
124
125}
126
127QT_END_NAMESPACE
QJsonObject mapNapiObjectToJsonObject(const QNapi::Object &napiObject)
QNapi::Object mapJsonObjectToNapiObject(napi_env env, const QJsonObject &jsonObject)