1#ifndef ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
2#define ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
3
4#include <cstdint>
5#include <tuple>
6#include <type_traits>
7
8#include <pdx/rpc/serialization.h>
9#include <pdx/service.h>
10
11namespace android {
12namespace pdx {
13namespace rpc {
14
15// Provides automatic serialization of argument lists and return
16// values by analyzing the supplied function signature types.
17// Examples:
18//     ArgumentEncoder<int(int, float)> encoder(writer);
19//     encoder.EncodeArguments(1, 1.0);
20
21template <typename T>
22class ArgumentEncoder;
23
24// Specialization of ArgumentEncoder for void return types.
25template <typename... Args>
26class ArgumentEncoder<void(Args...)> {
27 public:
28  explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
29
30  // Serializes the arguments as a tuple.
31  void EncodeArguments(Args... args) {
32    Serialize(std::forward_as_tuple(args...), writer_);
33  }
34
35 private:
36  MessageWriter* writer_;
37};
38
39// Specialization of ArgumentEncoder for non-void return types.
40template <typename Return, typename... Args>
41class ArgumentEncoder<Return(Args...)> {
42 public:
43  // Simplified types with reference and cv removed.
44  using ReturnType = typename std::decay<Return>::type;
45
46  explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
47
48  // Serializes the arguments as a tuple.
49  void EncodeArguments(Args... args) {
50    Serialize(std::forward_as_tuple(args...), writer_);
51  }
52
53  // Serializes the return value for rvalue references.
54  void EncodeReturn(const ReturnType& return_value) {
55    Serialize(return_value, writer_);
56  }
57
58 private:
59  MessageWriter* writer_;
60};
61
62// Utility to build an ArgumentEncoder from a function pointer and a message
63// writer.
64template <typename Return, typename... Args>
65inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
66    Return (*)(Args...), MessageWriter* writer) {
67  return ArgumentEncoder<Return(Args...)>(writer);
68}
69
70// Utility to build an ArgumentEncoder from a method pointer and a message
71// writer.
72template <typename Class, typename Return, typename... Args>
73inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
74    Return (Class::*)(Args...), MessageWriter* writer) {
75  return ArgumentEncoder<Return(Args...)>(writer);
76}
77
78// Utility to build an ArgumentEncoder from a const method pointer and a
79// message writer.
80template <typename Class, typename Return, typename... Args>
81inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
82    Return (Class::*)(Args...) const, MessageWriter* writer) {
83  return ArgumentEncoder<Return(Args...)>(writer);
84}
85
86// Utility to build an ArgumentEncoder from a function type and a message
87// writer.
88template <typename Signature>
89inline ArgumentEncoder<Signature> MakeArgumentEncoder(MessageWriter* writer) {
90  return ArgumentEncoder<Signature>(writer);
91}
92
93//////////////////////////////////////////////////////////////////////////////
94// Provides automatic deserialization of argument lists and return
95// values by analyzing the supplied function signature types.
96// Examples:
97//     auto decoder = MakeArgumentDecoder<std::string(void)>(reader);
98//     ErrorType error = decoder.DecodeReturn(&return_value);
99
100template <typename T>
101class ArgumentDecoder;
102
103// Specialization of ArgumentDecoder for void return types.
104template <typename... Args>
105class ArgumentDecoder<void(Args...)> {
106 public:
107  // Simplified types with reference and cv removed.
108  using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
109
110  explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
111
112  // Deserializes arguments into a tuple.
113  ArgsTupleType DecodeArguments(ErrorType* error) {
114    ArgsTupleType value;
115    *error = Deserialize(&value, reader_);
116    return value;
117  }
118
119 private:
120  MessageReader* reader_;
121};
122
123// Specialization of ArgumentDecoder for non-void return types.
124template <typename Return, typename... Args>
125class ArgumentDecoder<Return(Args...)> {
126 public:
127  // Simplified types with reference and cv removed.
128  using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
129  using ReturnType = typename std::decay<Return>::type;
130
131  explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
132
133  // Deserializes arguments into a tuple.
134  ArgsTupleType DecodeArguments(ErrorType* error) {
135    ArgsTupleType value;
136    *error = Deserialize(&value, reader_);
137    return value;
138  }
139
140  // Deserializes the return value.
141  ErrorType DecodeReturn(ReturnType* value) {
142    return Deserialize(value, reader_);
143  }
144
145 private:
146  MessageReader* reader_;
147};
148
149// Utility to build an ArgumentDecoder from a function pointer and a message
150// reader.
151template <typename Return, typename... Args>
152inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
153    Return (*)(Args...), MessageReader* reader) {
154  return ArgumentDecoder<Return(Args...)>(reader);
155}
156
157// Utility to build an ArgumentDecoder from a method pointer and a message
158// reader.
159template <typename Class, typename Return, typename... Args>
160inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
161    Return (Class::*)(Args...), MessageReader* reader) {
162  return ArgumentDecoder<Return(Args...)>(reader);
163}
164
165// Utility to build an ArgumentDecoder from a const method pointer and a
166// message reader.
167template <typename Class, typename Return, typename... Args>
168inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
169    Return (Class::*)(Args...) const, MessageReader* reader) {
170  return ArgumentDecoder<Return(Args...)>(reader);
171}
172
173// Utility to build an ArgumentDecoder from a function type and a message
174// reader.
175template <typename Signature>
176inline ArgumentDecoder<Signature> MakeArgumentDecoder(MessageReader* reader) {
177  return ArgumentDecoder<Signature>(reader);
178}
179
180}  // namespace rpc
181}  // namespace pdx
182}  // namespace android
183
184#endif  // ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
185