1 // Copyright 2014 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // DBusParamWriter::Append(writer, ...) provides functionality opposite
6 // to that of DBusParamReader. It writes each of the arguments to D-Bus message
7 // writer and return true if successful.
8 
9 // DBusParamWriter::AppendDBusOutParams(writer, ...) is similar to Append()
10 // but is used to send out the D-Bus OUT (pointer type) parameters in a D-Bus
11 // method response message. This method skips any non-pointer parameters and
12 // only appends the data for arguments that are pointers.
13 
14 #ifndef LIBBRILLO_BRILLO_DBUS_DBUS_PARAM_WRITER_H_
15 #define LIBBRILLO_BRILLO_DBUS_DBUS_PARAM_WRITER_H_
16 
17 #include <brillo/dbus/data_serialization.h>
18 #include <dbus/message.h>
19 
20 namespace brillo {
21 namespace dbus_utils {
22 
23 class DBusParamWriter final {
24  public:
25   // Generic writer method that takes 1 or more arguments. It recursively calls
26   // itself (each time with one fewer arguments) until no more is left.
27   template<typename ParamType, typename... RestOfParams>
Append(dbus::MessageWriter * writer,const ParamType & param,const RestOfParams &...rest)28   static void Append(dbus::MessageWriter* writer,
29                      const ParamType& param,
30                      const RestOfParams&... rest) {
31     // Append the current |param| to D-Bus, then call Append() with one
32     // fewer arguments, until none is left and stand-alone version of
33     // Append(dbus::MessageWriter*) is called to end the iteration.
34     DBusType<ParamType>::Write(writer, param);
35     Append(writer, rest...);
36   }
37 
38   // The final overload of DBusParamWriter::Append() used when no more
39   // parameters are remaining to be written.
40   // Does nothing and finishes meta-recursion.
Append(dbus::MessageWriter *)41   static void Append(dbus::MessageWriter* /*writer*/) {}
42 
43   // Generic writer method that takes 1 or more arguments. It recursively calls
44   // itself (each time with one fewer arguments) until no more is left.
45   // Handles non-pointer parameter by just skipping over it.
46   template<typename ParamType, typename... RestOfParams>
AppendDBusOutParams(dbus::MessageWriter * writer,const ParamType &,const RestOfParams &...rest)47   static void AppendDBusOutParams(dbus::MessageWriter* writer,
48                                   const ParamType& /* param */,
49                                   const RestOfParams&... rest) {
50     // Skip the current |param| and call Append() with one fewer arguments,
51     // until none is left and stand-alone version of
52     // AppendDBusOutParams(dbus::MessageWriter*) is called to end the iteration.
53     AppendDBusOutParams(writer, rest...);
54   }
55 
56   // Generic writer method that takes 1 or more arguments. It recursively calls
57   // itself (each time with one fewer arguments) until no more is left.
58   // Handles only a parameter of pointer type and writes the data pointed to
59   // to the output message buffer.
60   template<typename ParamType, typename... RestOfParams>
AppendDBusOutParams(dbus::MessageWriter * writer,ParamType * param,const RestOfParams &...rest)61   static void AppendDBusOutParams(dbus::MessageWriter* writer,
62                                   ParamType* param,
63                                   const RestOfParams&... rest) {
64     // Append the current |param| to D-Bus, then call Append() with one
65     // fewer arguments, until none is left and stand-alone version of
66     // Append(dbus::MessageWriter*) is called to end the iteration.
67     DBusType<ParamType>::Write(writer, *param);
68     AppendDBusOutParams(writer, rest...);
69   }
70 
71   // The final overload of DBusParamWriter::AppendDBusOutParams() used when no
72   // more parameters are remaining to be written.
73   // Does nothing and finishes meta-recursion.
AppendDBusOutParams(dbus::MessageWriter *)74   static void AppendDBusOutParams(dbus::MessageWriter* /*writer*/) {}
75 };
76 
77 }  // namespace dbus_utils
78 }  // namespace brillo
79 
80 #endif  // LIBBRILLO_BRILLO_DBUS_DBUS_PARAM_WRITER_H_
81