aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/lua/json.cpp
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/lua/json.cpp
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'library/cpp/lua/json.cpp')
-rw-r--r--library/cpp/lua/json.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/library/cpp/lua/json.cpp b/library/cpp/lua/json.cpp
new file mode 100644
index 0000000000..da7d228459
--- /dev/null
+++ b/library/cpp/lua/json.cpp
@@ -0,0 +1,62 @@
+#include "json.h"
+#include "wrapper.h"
+
+#include <library/cpp/json/json_value.h>
+
+using namespace NJson;
+
+void NLua::PushJsonValue(TLuaStateHolder* state, const TJsonValue& json) {
+ // each recursive call will explicitly push only a single element to stack relying on subcalls to reserve stack space for themselves
+ // I.e. for a map {"a": "b"} the first call will ensure stack space for create_table, then call PushJsonValue for the string,
+ // this PushJsonValue will ensure stack space for the string. Thus only a single ensure_stack at the start of the function is enough.
+ state->ensure_stack(1);
+ switch (json.GetType()) {
+ case JSON_UNDEFINED:
+ ythrow yexception() << "cannot push undefined json value";
+
+ case JSON_NULL:
+ state->push_nil();
+ break;
+
+ case JSON_BOOLEAN:
+ state->push_bool(json.GetBoolean());
+ break;
+
+ case JSON_INTEGER:
+ state->push_number(json.GetInteger());
+ break;
+
+ case JSON_UINTEGER:
+ state->push_number(json.GetUInteger());
+ break;
+
+ case JSON_DOUBLE:
+ state->push_number(json.GetDouble());
+ break;
+
+ case JSON_STRING:
+ state->push_string(json.GetString());
+ break;
+
+ case JSON_MAP:
+ state->create_table();
+ for (const auto& pair : json.GetMap()) {
+ PushJsonValue(state, pair.second); // Recursive call tests for stack space on its own
+ state->set_field(-2, pair.first.data());
+ }
+ break;
+
+ case JSON_ARRAY: {
+ state->create_table();
+ int index = 1; // lua arrays start from 1
+ for (const auto& element : json.GetArray()) {
+ PushJsonValue(state, element); // Recursive call tests for stack space on its own, no need to double check
+ state->rawseti(-2, index++);
+ }
+ break;
+ }
+
+ default:
+ ythrow yexception() << "Unexpected json value type";
+ }
+}