From: Philippe Proulx Date: Fri, 8 Dec 2023 20:55:05 +0000 (+0000) Subject: src/cpp-common: add bt2c::bt2ValueFromJsonVal() function X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=4a5a43f6da988c96af3e930e8a8416ee8d118820;p=babeltrace.git src/cpp-common: add bt2c::bt2ValueFromJsonVal() function 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 Change-Id: If3f0859202aa2ef329048ca5775883059e2b6e50 Reviewed-on: https://review.lttng.org/c/babeltrace/+/7486 Tested-by: jenkins Reviewed-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/12686 --- diff --git a/src/Makefile.am b/src/Makefile.am index a842780a..b38d88d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 00000000..595d7b0c --- /dev/null +++ b/src/cpp-common/bt2c/bt2-value-from-json-val.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022 Philippe Proulx + * + * 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(jsonVal); + } + + void visit(const JsonUIntVal& jsonVal) override + { + /* Explicit `unsigned long long` to `std::uint64_t` */ + this->_visitScalarVal(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 + void _visitScalarVal(const JsonValT& jsonVal) + { + _mCurBt2Val = bt2::createValue(static_cast(*jsonVal)); + } + + template + void _visitScalarVal(const JsonValT& jsonVal) + { + this->_visitScalarVal(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 index 00000000..ce1add1b --- /dev/null +++ b/src/cpp-common/bt2c/bt2-value-from-json-val.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Philippe Proulx + * + * 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 */