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
qpipewire_propertydict.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
6#include <pipewire/extensions/metadata.h>
7
8#include <QtCore/qspan.h>
9
10#include <cstdint>
11
12QT_BEGIN_NAMESPACE
13
14#ifndef PW_KEY_DEVICE_SYSFS_PATH
15# define PW_KEY_DEVICE_SYSFS_PATH "device.sysfs.path"
16#endif
17#ifndef PW_KEY_OBJECT_SERIAL
18# define PW_KEY_OBJECT_SERIAL "object.serial"
19#endif
20
21namespace QtPipeWire {
22
23PwPropertiesHandle makeProperties(QSpan<const spa_dict_item> keyValuePairs)
24{
25 struct spa_dict info = SPA_DICT_INIT(keyValuePairs.data(), uint32_t(keyValuePairs.size()));
26
27 return PwPropertiesHandle{
28 pw_properties_new_dict(&info),
29 };
30}
31
32PwPropertyDict toPropertyDict(const spa_dict &dict)
33{
34 QSpan<const spa_dict_item> items{ dict.items, dict.n_items };
35
36 PwPropertyDict map;
37 for (const spa_dict_item &item : items)
38 map.emplace(item.key, item.value);
39 return map;
40}
41
42namespace {
43
44std::optional<std::string_view> resolveInDictionary(const PwPropertyDict &dict,
45 std::string_view key)
46{
47 if (auto it = dict.find(key); it != dict.end())
48 return it->second;
49 return std::nullopt;
50}
51
52template <typename Converter>
53auto resolveInDictionaryHelper(const PwPropertyDict &dict, std::string_view key,
54 Converter &&convert)
55{
56 using ResultType = decltype(convert(std::declval<std::string_view>()));
57
58 if (auto it = dict.find(key); it != dict.end())
59 return convert(it->second);
60 return ResultType{ std::nullopt };
61}
62
63template <typename T>
64struct Converter
65{
66};
67
68template <>
69struct Converter<uint32_t>
70{
71 std::optional<uint32_t> operator()(std::string_view sv) const
72 {
73 bool ok{};
74 uint32_t ret = QLatin1StringView(sv).toInt(&ok);
75 if (ok)
76 return ret;
77
78 return std::nullopt;
79 }
80};
81
82template <>
83struct Converter<uint64_t>
84{
85 std::optional<uint64_t> operator()(std::string_view sv) const
86 {
87 static_assert(sizeof(qulonglong) == sizeof(uint64_t));
88
89 bool ok{};
90 uint64_t ret = QLatin1StringView(sv).toULongLong(&ok);
91 if (ok)
92 return ret;
93
94 return std::nullopt;
95 }
96};
97
98template <typename T>
99std::optional<T> resolveInDictionary(const PwPropertyDict &dict, std::string_view key)
100{
101 return resolveInDictionaryHelper(dict, key, Converter<T>{});
102}
103
104} // namespace
105
106std::optional<std::string_view> getMediaClass(const PwPropertyDict &dict)
107{
108 return resolveInDictionary(dict, PW_KEY_MEDIA_CLASS);
109}
110
111std::optional<std::string_view> getNodeName(const PwPropertyDict &dict)
112{
113 return resolveInDictionary(dict, PW_KEY_NODE_NAME);
114}
115
116std::optional<std::string_view> getNodeDescription(const PwPropertyDict &dict)
117{
118 return resolveInDictionary(dict, PW_KEY_NODE_DESCRIPTION);
119}
120
121std::optional<ObjectId> getDeviceId(const PwPropertyDict &dict)
122{
123 auto resolvedUint32 = resolveInDictionary<uint32_t>(dict, PW_KEY_DEVICE_ID);
124 if (resolvedUint32)
125 return ObjectId{ *resolvedUint32 };
126 return std::nullopt;
127}
128
129std::optional<std::string_view> getDeviceSysfsPath(const PwPropertyDict &dict)
130{
131 return resolveInDictionary(dict, PW_KEY_DEVICE_SYSFS_PATH);
132}
133
134std::optional<std::string_view> getDeviceName(const PwPropertyDict &dict)
135{
136 return resolveInDictionary(dict, PW_KEY_DEVICE_NAME);
137}
138
139std::optional<std::string_view> getDeviceDescription(const PwPropertyDict &dict)
140{
141 return resolveInDictionary(dict, PW_KEY_DEVICE_DESCRIPTION);
142}
143
144std::optional<ObjectSerial> getObjectSerial(const PwPropertyDict &dict)
145{
146 auto resolvedUint64 = resolveInDictionary<uint64_t>(dict, PW_KEY_OBJECT_SERIAL);
147 if (resolvedUint64)
148 return ObjectSerial{ *resolvedUint64 };
149 return std::nullopt;
150}
151
152std::optional<std::string_view> getMetadataName(const PwPropertyDict &dict)
153{
154 return resolveInDictionary(dict, PW_KEY_METADATA_NAME);
155}
156
157} // namespace QtPipeWire
158
159QT_END_NAMESPACE
std::optional< std::string_view > getMetadataName(const PwPropertyDict &)
std::optional< ObjectSerial > getObjectSerial(const PwPropertyDict &)
std::optional< std::string_view > getNodeName(const PwPropertyDict &)
PwPropertyDict toPropertyDict(const spa_dict &)
std::optional< std::string_view > getDeviceSysfsPath(const PwPropertyDict &)
std::optional< std::string_view > getDeviceName(const PwPropertyDict &)
StrongIdType< uint32_t, ObjectIdTag > ObjectId
std::optional< std::string_view > getDeviceDescription(const PwPropertyDict &)
StrongIdType< uint64_t, ObjectSerialTag > ObjectSerial
std::optional< std::string_view > getMediaClass(const PwPropertyDict &)
std::optional< ObjectId > getDeviceId(const PwPropertyDict &)
std::optional< std::string_view > getNodeDescription(const PwPropertyDict &)
PwPropertiesHandle makeProperties(QSpan< const spa_dict_item >)
#define PW_KEY_DEVICE_SYSFS_PATH
#define PW_KEY_OBJECT_SERIAL