src/cpp-common: add bt2c::bt2ValueFromJsonVal() function
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 8 Dec 2023 20:55:05 +0000 (20:55 +0000)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 4 Sep 2024 19:05:14 +0000 (15:05 -0400)
This patch adds the bt2c::bt2ValueFromJsonVal() function which
converts a JSON value object (`bt2c::JsonVal`) to a Babeltrace 2
value object (`bt2::Value::Shared`, wrapping a shared `bt_value *`).

The JSON value classes are a superset of the Babeltrace 2 value ones:
there's a dedicated `bt2c::JsonNullVal` class, whereas
libbabeltrace2 uses a null value singleton, and `bt2c::JsonVal`
has a text location member.

This is part of an effort to support CTF2‑SPEC‑2.0 [1]. This function
will be useful to convert JSON user attributes to Babeltrace 2 values
directly (this step doesn't need validation).

[1]: https://diamon.org/ctf/CTF2-SPEC-2.0.html

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: If3f0859202aa2ef329048ca5775883059e2b6e50
Reviewed-on: https://review.lttng.org/c/babeltrace/+/7486
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/12686

src/Makefile.am
src/cpp-common/bt2c/bt2-value-from-json-val.cpp [new file with mode: 0644]
src/cpp-common/bt2c/bt2-value-from-json-val.hpp [new file with mode: 0644]

index a842780aac5803a31c35055877ba81833c377430..b38d88d27473433ba9bd2185acfe6632dac86837 100644 (file)
@@ -158,6 +158,8 @@ cpp_common_libcpp_common_la_SOURCES = \
        cpp-common/bt2/value.hpp \
        cpp-common/bt2/wrap.hpp \
        cpp-common/bt2c/align.hpp \
+       cpp-common/bt2c/bt2-value-from-json-val.cpp \
+       cpp-common/bt2c/bt2-value-from-json-val.hpp \
        cpp-common/bt2c/c-string-view.hpp \
        cpp-common/bt2c/call.hpp \
        cpp-common/bt2c/contains.hpp \
diff --git a/src/cpp-common/bt2c/bt2-value-from-json-val.cpp b/src/cpp-common/bt2c/bt2-value-from-json-val.cpp
new file mode 100644 (file)
index 0000000..595d7b0
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "bt2-value-from-json-val.hpp"
+
+namespace bt2c {
+
+/*
+ * Within an instance of this converter, `_mCurBt2Val` is always the
+ * last converted value.
+ *
+ * Therefore, with a visit() method, to convert some JSON value
+ * `jsonVal`, make `jsonVal` accept the same visitor, and then use
+ * `_mCurBt2Val`.
+ *
+ * At the end of a visit, use bt2Val() to get the root shared
+ * Babeltrace 2 value.
+ */
+class Bt2ValueFromJsonValConverter final : public JsonValVisitor
+{
+public:
+    void visit(const JsonNullVal&) override
+    {
+        _mCurBt2Val = bt2::NullValue {}.shared();
+    }
+
+    void visit(const JsonBoolVal& jsonVal) override
+    {
+        this->_visitScalarVal(jsonVal);
+    }
+
+    void visit(const JsonSIntVal& jsonVal) override
+    {
+        /* Explicit `long long` to `std::int64_t` */
+        this->_visitScalarVal<std::int64_t>(jsonVal);
+    }
+
+    void visit(const JsonUIntVal& jsonVal) override
+    {
+        /* Explicit `unsigned long long` to `std::uint64_t` */
+        this->_visitScalarVal<std::uint64_t>(jsonVal);
+    }
+
+    void visit(const JsonRealVal& jsonVal) override
+    {
+        this->_visitScalarVal(jsonVal);
+    }
+
+    void visit(const JsonStrVal& jsonVal) override
+    {
+        this->_visitScalarVal(jsonVal);
+    }
+
+    void visit(const JsonArrayVal& jsonVal) override
+    {
+        /*
+         * Create an empty Babeltrace 2 array value, fill it with
+         * converted values, and set it as the current value.
+         */
+        auto bt2ArrayVal = bt2::ArrayValue::create();
+
+        for (auto& jsonValElem : jsonVal) {
+            jsonValElem->accept(*this);
+            bt2ArrayVal->append(*_mCurBt2Val);
+        }
+
+        _mCurBt2Val = bt2ArrayVal;
+    }
+
+    void visit(const JsonObjVal& jsonVal) override
+    {
+        /*
+         * Create an empty Babeltrace 2 map value, fill it with
+         * converted values, and set it as the current value.
+         */
+        auto bt2MapVal = bt2::MapValue::create();
+
+        for (auto& keyJsonValPair : jsonVal) {
+            keyJsonValPair.second->accept(*this);
+            bt2MapVal->insert(keyJsonValPair.first, *_mCurBt2Val);
+        }
+
+        _mCurBt2Val = bt2MapVal;
+    }
+
+    bt2::Value::Shared bt2Val() noexcept
+    {
+        return _mCurBt2Val;
+    }
+
+private:
+    /*
+     * Sets `_mCurBt2Val` to a new shared Babeltrace 2 value having the
+     * raw value `*jsonVal` of type `ValT`.
+     */
+    template <typename JsonValT, typename ValT = typename JsonValT::Val>
+    void _visitScalarVal(const JsonValT& jsonVal)
+    {
+        _mCurBt2Val = bt2::createValue(static_cast<ValT>(*jsonVal));
+    }
+
+    template <typename ValT, typename JsonValT>
+    void _visitScalarVal(const JsonValT& jsonVal)
+    {
+        this->_visitScalarVal<JsonValT, ValT>(jsonVal);
+    }
+
+private:
+    bt2::Value::Shared _mCurBt2Val;
+};
+
+bt2::Value::Shared bt2ValueFromJsonVal(const JsonVal& jsonVal)
+{
+    Bt2ValueFromJsonValConverter converter;
+
+    jsonVal.accept(converter);
+    return converter.bt2Val();
+}
+
+} /* namespace bt2c */
diff --git a/src/cpp-common/bt2c/bt2-value-from-json-val.hpp b/src/cpp-common/bt2c/bt2-value-from-json-val.hpp
new file mode 100644 (file)
index 0000000..ce1add1
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2022 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2C_BT2_VALUE_FROM_JSON_VAL_HPP
+#define BABELTRACE_CPP_COMMON_BT2C_BT2_VALUE_FROM_JSON_VAL_HPP
+
+#include "cpp-common/bt2/value.hpp"
+
+#include "json-val.hpp"
+
+namespace bt2c {
+
+/*
+ * Converts the JSON value `jsonVal` to an equivalent Babeltrace 2 value
+ * object and returns it.
+ */
+bt2::Value::Shared bt2ValueFromJsonVal(const JsonVal& jsonVal);
+
+} /* namespace bt2c */
+
+#endif /* BABELTRACE_CPP_COMMON_BT2C_BT2_VALUE_FROM_JSON_VAL_HPP */
This page took 0.027057 seconds and 4 git commands to generate.