OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium 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 #ifndef DBUS_MESSAGE_H_ | |
6 #define DBUS_MESSAGE_H_ | |
7 #pragma once | |
8 | |
9 #include <string> | |
10 #include <vector> | |
11 #include <dbus/dbus.h> | |
12 | |
13 #include "base/basictypes.h" | |
14 | |
15 namespace dbus { | |
16 | |
17 class MessageWriter; | |
18 class MessageReader; | |
19 | |
20 // Message is the base class of D-Bus message types. Client code should | |
21 // usually use sub classes such as MethodCall and Response instead. | |
22 // | |
23 // The class name Message is very generic, but there should be no problem | |
24 // as the class is inside 'dbus' namespace. We chose to name this way, as | |
25 // libdbus defines lots of types starting with DBus, such as | |
26 // DBusMessage. We should avoid confusion and conflict with these types. | |
27 class Message { | |
28 public: | |
29 // The message type used in D-Bus. Redefined here so client code | |
30 // doesn't need to use raw D-Bus macros. DBUS_MESSAGE_TYPE_INVALID | |
31 // etc. are #define macros. Having an enum type here makes code a bit | |
32 // more type-safe: | |
33 // | |
34 // MessageType GetMessageType() vs. int GetMessageType() | |
35 // | |
stevenjb
2011/07/29 20:27:12
nit: vs. expample probably unnecessary; hopefully
satorux1
2011/07/29 22:08:20
Done.
| |
36 enum MessageType { | |
37 MESSAGE_INVALID = DBUS_MESSAGE_TYPE_INVALID, | |
38 MESSAGE_METHOD_CALL = DBUS_MESSAGE_TYPE_METHOD_CALL, | |
39 MESSAGE_METHOD_RETURN = DBUS_MESSAGE_TYPE_METHOD_RETURN, | |
40 MESSAGE_SIGNAL = DBUS_MESSAGE_TYPE_SIGNAL, | |
41 MESSAGE_ERROR = DBUS_MESSAGE_TYPE_ERROR, | |
42 }; | |
43 | |
44 // The data type used in the D-Bus type system. See the comment at | |
45 // MessageType for why we are redefined data types here. | |
stevenjb
2011/07/29 20:27:12
nit: s/redefined/redefining
satorux1
2011/07/29 22:08:20
Done.
| |
46 enum DataType { | |
47 INVALID_DATA = DBUS_TYPE_INVALID, | |
48 BYTE = DBUS_TYPE_BYTE, | |
49 BOOL = DBUS_TYPE_BOOLEAN, | |
50 INT16 = DBUS_TYPE_INT16, | |
51 UINT16 = DBUS_TYPE_UINT16, | |
52 INT32 = DBUS_TYPE_INT32, | |
53 UINT32 = DBUS_TYPE_UINT32, | |
54 INT64 = DBUS_TYPE_INT64, | |
55 UINT64 = DBUS_TYPE_UINT64, | |
56 DOUBLE = DBUS_TYPE_DOUBLE, | |
57 STRING = DBUS_TYPE_STRING, | |
58 OBJECT_PATH = DBUS_TYPE_OBJECT_PATH, | |
59 ARRAY = DBUS_TYPE_ARRAY, | |
60 STRUCT = DBUS_TYPE_STRUCT, | |
61 DICT_ENTRY = DBUS_TYPE_DICT_ENTRY, | |
62 VARIANT = DBUS_TYPE_VARIANT, | |
63 }; | |
64 | |
65 // Creates a Message. The internal raw message is NULL until it's set | |
66 // from outside by reset_raw_message(). | |
67 Message(); | |
68 virtual ~Message(); | |
69 | |
70 // Returns the type of the message. Returns MESSAGE_INVALID if | |
71 // raw_message_ is NULL. | |
72 MessageType GetMessageType(); | |
73 | |
74 DBusMessage* raw_message() { return raw_message_; } | |
75 | |
76 // Resets raw_message_ with the given raw message. Takes the ownership | |
77 // of raw_message. raw_message_ will be unref'ed in the destructor. | |
78 void reset_raw_message(DBusMessage* raw_message); | |
79 | |
80 // Returns the string representation of this message. Useful for | |
81 // debugging. The returned string consists of message headers such as | |
82 // destination if any, followed by a blank line, and the message | |
83 // payload. For example, a MethodCall's ToString() will look like: | |
84 // | |
85 // destination: com.example.Service | |
86 // path: /com/example/Object | |
87 // interface: com.example.Interface | |
88 // member: SomeMethod | |
89 // | |
90 // string \"payload\" | |
91 // ... | |
stevenjb
2011/07/29 20:27:12
nit: Probably don't need this much detail for a de
satorux1
2011/07/29 22:08:20
Done.
| |
92 std::string ToString(); | |
93 | |
94 private: | |
95 // Helper function used in ToString(). | |
96 std::string ToStringInternal(const std::string& indent, | |
97 MessageReader* reader); | |
98 | |
99 DBusMessage* raw_message_; | |
100 DISALLOW_COPY_AND_ASSIGN(Message); | |
101 }; | |
102 | |
103 // MessageCall is a type of message used for calling a method via D-Bus. | |
104 class MethodCall : public Message { | |
105 public: | |
106 // Creates a method call message for the specified interface name and | |
107 // the method name. | |
108 // | |
109 // For instance, to call "Get" method of DBUS_INTERFACE_INTROSPECTABLE | |
110 // interface ("org.freedesktop.DBus.Introspectable"), create a method | |
111 // call like this: | |
112 // | |
113 // MethodCall method_call(DBUS_INTERFACE_INTROSPECTABLE, "Get"); | |
114 // | |
115 // The constructor creates the internal raw_message_, so the client | |
116 // doesn't need to set this by reset_raw_message(). | |
stevenjb
2011/07/29 20:27:12
not: s/by/with
satorux1
2011/07/29 22:08:20
Done.
| |
117 MethodCall(const std::string& interface_name, | |
118 const std::string& method_name); | |
119 | |
120 const std::string& interface_name() { return interface_name_; } | |
121 const std::string& method_name() { return method_name_; } | |
122 | |
123 // Sets the service name. This will be handled by the object proxy. | |
124 void SetServiceName(const std::string& service_name); | |
125 // Sets the object path. This will be handled by the object proxy. | |
126 void SetObjectPath(const std::string& object_path); | |
127 | |
128 std::string interface_name_; | |
129 std::string method_name_; | |
130 | |
131 DISALLOW_COPY_AND_ASSIGN(MethodCall); | |
132 }; | |
133 | |
134 // Response is a type of message used for receiving a response from a | |
135 // method via D-Bus. | |
136 class Response : public Message { | |
137 public: | |
138 // Creates a Response message. The internal raw message is | |
139 // NULL. ObjectProxy will set it properly once it gets a response from | |
stevenjb
2011/07/29 20:27:12
This is the only reference here to 'ObjectProxy'.
satorux1
2011/07/29 22:08:20
Done.
| |
140 // the server. | |
141 Response(); | |
142 | |
143 private: | |
144 DISALLOW_COPY_AND_ASSIGN(Response); | |
145 }; | |
146 | |
147 // MessageWriter is used to write outgoing messages for calling methods | |
148 // and sending signals. | |
149 class MessageWriter { | |
150 public: | |
151 // The data will be written into the given message. | |
stevenjb
2011/07/29 20:27:12
'The data' is unclear. Maybe something like "Data
satorux1
2011/07/29 22:08:20
Done.
| |
152 MessageWriter(Message* message); | |
153 ~MessageWriter(); | |
154 | |
155 // Appends a byte to the message. | |
156 void AppendByte(uint8 value); | |
157 void AppendBool(bool value); | |
158 void AppendInt16(int16 value); | |
159 void AppendUint16(uint16 value); | |
160 void AppendInt32(int32 value); | |
161 void AppendUint32(uint32 value); | |
162 void AppendInt64(int64 value); | |
163 void AppendUint64(uint64 value); | |
164 void AppendDouble(double value); | |
165 void AppendString(const std::string& value); | |
166 void AppendObjectPath(const std::string& value); | |
167 | |
168 // Opens an array. The array contents can be added to the array with | |
169 // |sub_writer|. The client code should close the array with | |
stevenjb
2011/07/29 20:27:12
s/should/must
satorux1
2011/07/29 22:08:20
Done.
| |
170 // CloseContainer(), once all contents are added. | |
171 // | |
172 // |signature| parameter is used to supply the D-Bus type signature of | |
173 // the array contents. For instance, if you want an array of strings, | |
174 // then you pass "s" as the signature. | |
175 // | |
176 // See the spec for details about the type signatures. | |
177 // http://dbus.freedesktop.org/doc/dbus-specification.html | |
178 // #message-protocol-signatures | |
179 // | |
180 void OpenArray(const std::string& signature, MessageWriter* sub_writer); | |
181 // Do the same for a variant. | |
182 void OpenVariant(const std::string& signature, MessageWriter* sub_writer); | |
183 // Do the same for Struct and dict entry. They don't need the signature. | |
184 void OpenStruct(MessageWriter* sub_writer); | |
185 void OpenDictEntry(MessageWriter* sub_writer); | |
186 | |
187 // Close the container for a array/variant/struct/dict entry. | |
188 void CloseContainer(MessageWriter* sub_writer); | |
189 | |
190 // Appends the array of bytes. Arrays of bytes are often used for | |
191 // exchanging binary blobs hence it's worth having a specialized | |
192 // function. | |
193 void AppendArrayOfBytes(const uint8* values, size_t length); | |
194 | |
195 // Appends the byte wrapped in a variant data container. Variants are | |
196 // widely used in D-Bus services so it's worth having a specialized | |
197 // function. For instance, The third parameter of | |
198 // "org.freedesktop.DBus.Properties.Set" is a variant. | |
199 void AppendVariantOfByte(uint8 value); | |
200 void AppendVariantOfBool(bool value); | |
201 void AppendVariantOfInt16(int16 value); | |
202 void AppendVariantOfUint16(uint16 value); | |
203 void AppendVariantOfInt32(int32 value); | |
204 void AppendVariantOfUint32(uint32 value); | |
205 void AppendVariantOfInt64(int64 value); | |
206 void AppendVariantOfUint64(uint64 value); | |
207 void AppendVariantOfDouble(double value); | |
208 void AppendVariantOfString(const std::string& value); | |
209 void AppendVariantOfObjectPath(const std::string& value); | |
210 | |
211 private: | |
212 // Helper function used to implement AppendByte etc. | |
213 void AppendBasic(int dbus_type, const void* value); | |
214 | |
215 // Helper function used to implement AppendVariantOfByte() etc. | |
216 void AppendVariantOfBasic(int dbus_type, const void* value); | |
217 | |
218 Message* message_; | |
219 DBusMessageIter raw_message_iter_; | |
220 bool container_is_open_; | |
221 | |
222 DISALLOW_COPY_AND_ASSIGN(MessageWriter); | |
223 }; | |
224 | |
225 // MessageReader is used to read incoming messages such as responses for | |
226 // method calls. | |
227 // | |
228 // MessageReader manages an internal iterator to read data. All functions | |
229 // starting with Pop advance the iterator on success. | |
230 // | |
231 // The main design goal of MessageReader and MessageWriter classes is to | |
232 // provide a type safe API. In the past, there was a Chrome OS blocker | |
233 // bug, that took days to fix, that would have been prevented if the API | |
234 // was type-safe. | |
235 // | |
236 // For instance, instead of doing something like: | |
237 // | |
238 // // We shouldn't add '&' to str here, but it compiles with '&' added. | |
239 // dbus_g_proxy_call(..., G_TYPE_STRING, str, G_TYPE_INVALID, ...) | |
240 // | |
241 // We want to do something like: | |
242 // | |
243 // writer.AppendString(str); | |
stevenjb
2011/07/29 20:27:12
Move this comment (starting with 'The main design
satorux1
2011/07/29 22:08:20
Done.
| |
244 // | |
245 class MessageReader { | |
246 public: | |
247 // The data will be read from the given message. | |
248 MessageReader(Message* message); | |
249 ~MessageReader(); | |
250 | |
251 // Returns true if the reader has more data to read. The function is | |
252 // used to iterate contents in a container like: | |
253 // | |
254 // while (reader.HasMoreData()) | |
255 // reader.PopString(&value); | |
256 bool HasMoreData(); | |
257 | |
258 // Gets the byte at the current iterator position. On success, advances | |
259 // the iterator and returns true. It's an error if the actual data type | |
260 // is not a byte, so false will be returned in this case. | |
261 bool PopByte(uint8* value); | |
262 bool PopBool(bool* value); | |
263 bool PopInt16(int16* value); | |
264 bool PopUint16(uint16* value); | |
265 bool PopInt32(int32* value); | |
266 bool PopUint32(uint32* value); | |
267 bool PopInt64(int64* value); | |
268 bool PopUint64(uint64* value); | |
269 bool PopDouble(double* value); | |
270 bool PopString(std::string* value); | |
271 bool PopObjectPath(std::string* value); | |
272 | |
273 // Sets up the given message reader to read an array at the current | |
274 // iterator position. On success, advances the iterator and returns | |
275 // true. It's an error if the actual data type is not an array, so false | |
276 // will be returned in this case. | |
stevenjb
2011/07/29 20:27:12
nit: separate line for return values:
Returns tru
satorux1
2011/07/29 22:08:20
Done.
| |
277 bool PopArray(MessageReader* sub_reader); | |
278 // The following functions do the same for other container types. | |
279 bool PopStruct(MessageReader* sub_reader); | |
280 bool PopDictEntry(MessageReader* sub_reader); | |
281 bool PopVariant(MessageReader* sub_reader); | |
282 | |
283 // Gets the array of bytes at the current iterator position. On success, | |
284 // advances the iterator and returns true. Arrays of bytes are often | |
stevenjb
2011/07/29 20:27:12
nit: Separate line for return value:
Returns true
| |
285 // used for exchanging binary blobs hence it's worth having a | |
286 // specialized function. | |
287 // | |
288 // |bytes| will point to the beginning of the array in the underlying | |
289 // message. You should copy bytes to something like a vector, if you are | |
290 // going to use the data after the destruction of the message, | |
stevenjb
2011/07/29 20:27:12
Trailing comma. Maybe say something like '|bytes|
satorux1
2011/07/29 22:08:20
Done.
| |
291 bool PopArrayOfBytes(uint8** bytes, size_t* length); | |
292 | |
293 // Gets the array of object paths at the current iterator position. On | |
294 // success, advances the iterator and returns true. Arrays of object | |
stevenjb
2011/07/29 20:27:12
nit: separate line for return value.
satorux1
2011/07/29 22:08:20
Done.
| |
295 // paths are often used to communicate with D-Bus services like | |
296 // NetworkManager, hence it's worth having a specialized function. | |
297 bool PopArrayOfObjectPaths(std::vector<std::string>* object_paths); | |
298 | |
299 // Gets the byte from the variant data container at the current iterator | |
300 // position. On success, returns true and advances the | |
stevenjb
2011/07/29 20:27:12
nit: separate line for return value.
satorux1
2011/07/29 22:08:20
Done.
| |
301 // iterator. Variants are widely used in D-Bus services so it's worth | |
302 // having a specialized function. For instance, The return value type of | |
303 // "org.freedesktop.DBus.Properties.Get" is a variant. | |
304 bool PopVariantOfByte(uint8* value); | |
305 bool PopVariantOfBool(bool* value); | |
306 bool PopVariantOfInt16(int16* value); | |
307 bool PopVariantOfUint16(uint16* value); | |
308 bool PopVariantOfInt32(int32* value); | |
309 bool PopVariantOfUint32(uint32* value); | |
310 bool PopVariantOfInt64(int64* value); | |
311 bool PopVariantOfUint64(uint64* value); | |
312 bool PopVariantOfDouble(double* value); | |
313 bool PopVariantOfString(std::string* value); | |
314 bool PopVariantOfObjectPath(std::string* value); | |
315 | |
316 // Get the data type of the value at the current iterator | |
317 // position. INVALID_DATA will be returned if the iterator points to the | |
318 // end of the message. | |
319 Message::DataType GetDataType(); | |
320 | |
321 private: | |
322 // Returns true if the data type at the current iterator position | |
323 // matches the given D-Bus type, such as DBUS_TYPE_BYTE. | |
324 bool CheckDataType(int dbus_type); | |
325 | |
326 // Helper function used to implement PopByte() etc. | |
327 bool PopBasic(int dbus_type, void *value); | |
328 | |
329 // Helper function used to implement PopArray() etc. | |
330 bool PopContainer(int dbus_type, MessageReader* sub_reader); | |
331 | |
332 // Helper function used to implement PopVariantOfByte() etc. | |
333 bool PopVariantOfBasic(int dbus_type, void* value); | |
334 | |
335 Message* message_; | |
336 DBusMessageIter raw_message_iter_; | |
337 | |
338 DISALLOW_COPY_AND_ASSIGN(MessageReader); | |
339 }; | |
340 | |
341 } // namespace dbus | |
342 | |
343 #endif // DBUS_MESSAGE_H_ | |
OLD | NEW |