Fcitx
message_details.h
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_DBUS_MESSAGE_DETAILS_H_
8 #define _FCITX_UTILS_DBUS_MESSAGE_DETAILS_H_
9 
10 // IWYU pragma: private, include "message.h"
11 
12 #include <cstdint>
13 #include <string>
14 #include <tuple>
15 #include <utility>
16 #include <vector>
17 #include <fcitx-utils/metastring.h>
18 #include <fcitx-utils/tuplehelpers.h>
19 #include <fcitx-utils/unixfd.h>
20 
21 namespace fcitx::dbus {
22 
23 template <typename T>
25  using type = std::tuple<T>;
26 };
27 
28 template <typename... Args>
29 struct MakeTupleIfNeeded<std::tuple<Args...>> {
30  using type = std::tuple<Args...>;
31 };
32 
33 template <typename T>
34 using MakeTupleIfNeededType = typename MakeTupleIfNeeded<T>::type;
35 
36 template <typename T>
38  using type = T;
39 };
40 
41 template <typename Arg>
42 struct RemoveTupleIfUnnecessary<std::tuple<Arg>> {
43  using type = Arg;
44 };
45 
46 template <typename T>
47 using RemoveTupleIfUnnecessaryType = typename RemoveTupleIfUnnecessary<T>::type;
48 
49 class ObjectPath;
50 class Variant;
51 
52 template <typename... Args>
53 struct DBusStruct;
54 
55 template <typename Key, typename Value>
56 class DictEntry;
57 
58 template <typename T>
60 
61 template <char>
63 
64 #define DBUS_SIGNATURE_TRAITS(TYPENAME, SIG) \
65  template <> \
66  struct DBusSignatureTraits<TYPENAME> { \
67  using signature = MetaString<SIG>; \
68  }; \
69  \
70  template <> \
71  struct DBusSignatureToBasicType<SIG> { \
72  using type = TYPENAME; \
73  };
74 
75 DBUS_SIGNATURE_TRAITS(std::string, 's');
76 DBUS_SIGNATURE_TRAITS(uint8_t, 'y');
77 DBUS_SIGNATURE_TRAITS(bool, 'b');
78 DBUS_SIGNATURE_TRAITS(int16_t, 'n');
79 DBUS_SIGNATURE_TRAITS(uint16_t, 'q');
80 DBUS_SIGNATURE_TRAITS(int32_t, 'i');
81 DBUS_SIGNATURE_TRAITS(uint32_t, 'u');
82 DBUS_SIGNATURE_TRAITS(int64_t, 'x');
83 DBUS_SIGNATURE_TRAITS(uint64_t, 't');
84 DBUS_SIGNATURE_TRAITS(double, 'd');
85 DBUS_SIGNATURE_TRAITS(UnixFD, 'h');
86 DBUS_SIGNATURE_TRAITS(ObjectPath, 'o');
87 DBUS_SIGNATURE_TRAITS(Variant, 'v');
88 
89 template <typename K, typename V>
90 struct DBusSignatureTraits<std::pair<K, V>> {
91  using signature =
92  ConcatMetaStringType<typename DBusSignatureTraits<K>::signature,
94 };
95 
96 template <typename Arg, typename... Args>
97 struct DBusSignatureTraits<std::tuple<Arg, Args...>> {
98  using signature = ConcatMetaStringType<
100  typename DBusSignatureTraits<std::tuple<Args...>>::signature>;
101 };
102 
103 template <>
104 struct DBusSignatureTraits<std::tuple<>> {
105  using signature = MetaString<>;
106 };
107 
108 template <typename... Args>
109 struct DBusSignatureTraits<DBusStruct<Args...>> {
110  using signature = ConcatMetaStringType<
112  typename DBusSignatureTraits<std::tuple<Args...>>::signature,
114 };
115 
116 template <typename Key, typename Value>
118  using signature = ConcatMetaStringType<
119  MetaString<'{'>,
120  typename DBusSignatureTraits<std::tuple<Key, Value>>::signature,
122 };
123 
124 template <typename T>
125 struct DBusSignatureTraits<std::vector<T>> {
126  using signature =
127  ConcatMetaStringType<MetaString<'a'>,
129 };
130 
131 template <typename T>
133 
134 template <typename... Args>
136  using signature =
137  typename DBusSignatureTraits<std::tuple<Args...>>::signature;
138 };
139 
140 template <typename Key, typename Value>
142  using signature =
143  typename DBusSignatureTraits<std::tuple<Key, Value>>::signature;
144 };
145 
146 template <typename T>
147 struct DBusContainerSignatureTraits<std::vector<T>> {
148  using signature = typename DBusSignatureTraits<T>::signature;
149 };
150 
151 template <char left, char right, int level, typename S>
153 
154 template <char left, char right, int level, char first, char... next>
155 struct SkipTillNext<left, right, level, MetaString<first, next...>> {
156  using type =
157  typename SkipTillNext<left, right, level, MetaString<next...>>::type;
158  using str = ConcatMetaStringType<
160  typename SkipTillNext<left, right, level, MetaString<next...>>::str>;
161 };
162 
163 template <char left, char right, int level, char... next>
164 struct SkipTillNext<left, right, level, MetaString<left, next...>> {
165  using type = typename SkipTillNext<left, right, level + 1,
166  MetaString<next...>>::type;
167  using str =
168  ConcatMetaStringType<MetaString<left>,
169  typename SkipTillNext<left, right, level + 1,
170  MetaString<next...>>::str>;
171 };
172 
173 template <char left, char right, int level, char... next>
174 struct SkipTillNext<left, right, level, MetaString<right, next...>> {
175  using type = typename SkipTillNext<left, right, level - 1,
176  MetaString<next...>>::type;
177  using str =
178  ConcatMetaStringType<MetaString<right>,
179  typename SkipTillNext<left, right, level - 1,
180  MetaString<next...>>::str>;
181 };
182 
183 template <char left, char right, char first, char... next>
184 struct SkipTillNext<left, right, 0, MetaString<first, next...>> {
185  using type = MetaString<first, next...>;
186  using str = MetaString<>;
187 };
188 
189 // This is required to resolve ambiguity like (i)(i), when a '(' appear
190 // immediate after a closed ')'.
191 template <char left, char right, char... next>
192 struct SkipTillNext<left, right, 0, MetaString<left, next...>> {
193  using type = MetaString<left, next...>;
194  using str = MetaString<>;
195 };
196 
197 template <char left, char right>
198 struct SkipTillNext<left, right, 0, MetaString<>> {
199  using type = MetaString<>;
200  using str = MetaString<>;
201 };
202 
203 template <char... c>
205 
206 template <char... c>
208  DBusMetaStringSignatureToTupleHelper(MetaString<c...>);
209 
210 template <typename T>
211 using DBusMetaStringSignatureToTuple = MakeTupleIfNeededType<
212  typename decltype(DBusMetaStringSignatureToTupleHelper(
213  std::declval<T>()))::type>;
214 
215 template <typename... Args>
216 DBusStruct<Args...> TupleToDBusStructHelper(std::tuple<Args...>);
217 
218 template <typename T>
219 using TupleToDBusStruct = decltype(TupleToDBusStructHelper(std::declval<T>()));
220 
221 template <typename Key, typename Value>
222 DictEntry<Key, Value> TupleToDictEntryHelper(std::tuple<Key, Value>);
223 
224 template <typename T>
225 using TupleToDictEntry = decltype(TupleToDictEntryHelper(std::declval<T>()));
226 
227 template <char... next>
229 
230 template <char first, char... nextChar>
232  using cur = typename DBusSignatureToType<first>::type;
233  using next = typename DBusSignatureToType<nextChar...>::type;
234 };
235 
236 template <char... nextChar>
239  using cur = std::vector<typename SplitType::cur>;
240  using next = typename SplitType::next;
241 };
242 
243 template <int level, typename S>
245 
246 template <int level, typename S>
247 using SkipTillNextBrace = SkipTillNext<'{', '}', level, S>;
248 
249 template <char... nextChar>
250 struct DBusSignatureGetNextSignature<'(', nextChar...> {
251  using cur = TupleToDBusStruct<DBusMetaStringSignatureToTuple<
252  RemoveMetaStringTailType<typename SkipTillNextParentheses<
253  1, MetaString<nextChar...>>::str>>>;
254  using next = DBusMetaStringSignatureToTuple<
255  typename SkipTillNextParentheses<1, MetaString<nextChar...>>::type>;
256 };
257 
258 template <char... nextChar>
259 struct DBusSignatureGetNextSignature<'{', nextChar...> {
260  using cur = TupleToDictEntry<
261  DBusMetaStringSignatureToTuple<RemoveMetaStringTailType<
262  typename SkipTillNextBrace<1, MetaString<nextChar...>>::str>>>;
263  using next = DBusMetaStringSignatureToTuple<
264  typename SkipTillNextBrace<1, MetaString<nextChar...>>::type>;
265 };
266 
267 template <char... c>
268 struct DBusSignatureToType {
269  using SplitType = DBusSignatureGetNextSignature<c...>;
270  using type = RemoveTupleIfUnnecessaryType<
271  CombineTuplesType<MakeTupleIfNeededType<typename SplitType::cur>,
272  MakeTupleIfNeededType<typename SplitType::next>>>;
273 };
274 template <char c>
275 struct DBusSignatureToType<c> {
276  using type = typename DBusSignatureToBasicType<c>::type;
277 };
278 
279 template <>
280 struct DBusSignatureToType<> {
281  using type = std::tuple<>;
282 };
283 
284 template <typename M>
285 struct MetaStringToDBusTuple;
286 
287 template <char... c>
288 struct MetaStringToDBusTuple<MetaString<c...>> {
289  using type = typename DBusSignatureToType<c...>::type;
290 };
291 
292 template <typename M>
293 using MetaStringToDBusTupleType = typename MetaStringToDBusTuple<M>::type;
294 
295 template <typename T>
296 struct DBusTupleToReturn {
297  using type = T;
298 };
299 
300 template <>
301 struct DBusTupleToReturn<std::tuple<>> {
302  using type = void;
303 };
304 
305 template <typename T>
306 using DBusTupleToReturnType = typename DBusTupleToReturn<T>::type;
307 
308 #define FCITX_STRING_TO_DBUS_TUPLE(STRING) \
309  ::fcitx::dbus::MakeTupleIfNeededType< \
310  ::fcitx::dbus::MetaStringToDBusTupleType<fcitxMakeMetaString(STRING)>>
311 #define FCITX_STRING_TO_DBUS_TYPE(STRING) \
312  ::fcitx::dbus::DBusTupleToReturnType< \
313  ::fcitx::dbus::MetaStringToDBusTupleType<fcitxMakeMetaString(STRING)>>
314 } // namespace fcitx::dbus
315 
316 #endif // _FCITX_UTILS_DBUS_MESSAGE_DETAILS_H_
Class wrap around the unix fd.
Definition: unixfd.h:22
Describe a Key in fcitx.
Definition: key.h:41
Definition: matchrule.h:78
Utility class to handle unix file decriptor.
Iter nextChar(Iter iter)
Move iter over next one character.
Definition: utf8.h:141
A type to represent DBus dict entry.
Definition: message.h:116
Variant type to be used to box or unbox the dbus variant type.
Definition: variant.h:65
String like type object path &#39;o&#39;.
Definition: message.h:151
A type to represent DBus struct.
Definition: message.h:44
Static string based on template argument.