blob: 93ccd601c13d04e65f6c7925ba191648b69ce371 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_DBUS_UTILS_WRITE_VALUE_H_
#define COMPONENTS_DBUS_UTILS_WRITE_VALUE_H_
#include <utility>
#include "base/component_export.h"
#include "base/files/scoped_file.h"
#include "components/dbus/utils/types.h"
#include "components/dbus/utils/variant.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
namespace dbus_utils::internal {
template <typename T>
void WriteValue(dbus::MessageWriter& writer, const T& value);
template <typename T>
requires IsSupportedArray<T>::value
void WriteArray(dbus::MessageWriter& writer, const T& container) {
using ElementType = typename T::value_type;
dbus::MessageWriter array_writer(nullptr);
writer.OpenArray(GetDBusTypeSignature<ElementType>(), &array_writer);
for (const auto& element : container) {
WriteValue(array_writer, element);
}
writer.CloseContainer(&array_writer);
}
template <typename T>
requires IsSupportedMap<T>::value
void WriteMap(dbus::MessageWriter& writer, const T& map_container) {
dbus::MessageWriter array_writer(nullptr);
writer.OpenArray(UNSAFE_BUFFERS(GetDBusTypeSignature<T>() + 1),
&array_writer);
for (const auto& pair : map_container) {
dbus::MessageWriter dict_entry_writer(nullptr);
array_writer.OpenDictEntry(&dict_entry_writer);
WriteValue(dict_entry_writer, pair.first);
WriteValue(dict_entry_writer, pair.second);
array_writer.CloseContainer(&dict_entry_writer);
}
writer.CloseContainer(&array_writer);
}
template <typename T>
requires IsSupportedStruct<T>::value
void WriteStruct(dbus::MessageWriter& writer, const T& structure) {
dbus::MessageWriter struct_writer(nullptr);
writer.OpenStruct(&struct_writer);
auto write_members = [&](const auto&... members) {
((WriteValue(struct_writer, members)), ...);
};
std::apply(write_members, structure);
writer.CloseContainer(&struct_writer);
}
template <typename T>
void WriteValue(dbus::MessageWriter& writer, const T& value) {
if constexpr (std::is_same_v<T, int16_t>) {
writer.AppendInt16(value);
} else if constexpr (std::is_same_v<T, uint16_t>) {
writer.AppendUint16(value);
} else if constexpr (std::is_same_v<T, int32_t>) {
writer.AppendInt32(value);
} else if constexpr (std::is_same_v<T, uint32_t>) {
writer.AppendUint32(value);
} else if constexpr (std::is_same_v<T, int64_t>) {
writer.AppendInt64(value);
} else if constexpr (std::is_same_v<T, uint64_t>) {
writer.AppendUint64(value);
} else if constexpr (std::is_same_v<T, bool>) {
writer.AppendBool(value);
} else if constexpr (std::is_same_v<T, double>) {
writer.AppendDouble(value);
} else if constexpr (std::is_same_v<T, uint8_t>) {
writer.AppendByte(value);
} else if constexpr (std::is_same_v<T, std::string>) {
writer.AppendString(value);
} else if constexpr (std::is_same_v<T, dbus::ObjectPath>) {
writer.AppendObjectPath(value);
} else if constexpr (std::is_same_v<T, base::ScopedFD>) {
writer.AppendFileDescriptor(value.get());
} else if constexpr (IsSupportedArray<T>::value) {
WriteArray(writer, value);
} else if constexpr (IsSupportedMap<T>::value) {
WriteMap(writer, value);
} else if constexpr (IsSupportedStruct<T>::value) {
WriteStruct(writer, value);
} else if constexpr (std::is_same_v<T, Variant>) {
value.Write(writer);
} else {
static_assert(false, "Unsupported type for D-Bus writing");
}
}
} // namespace dbus_utils::internal
#endif // COMPONENTS_DBUS_UTILS_WRITE_VALUE_H_