diff options
author | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-10 22:34:02 +0000 |
---|---|---|
committer | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-10 22:34:02 +0000 |
commit | 9cce2d32f708024bb24d0036e98a2ded583a9552 (patch) | |
tree | fb80fe7896ce20361a777ae429bc74475f039f11 | |
parent | db6d774d0055bc4d1f79ced2b93dd2ea2a56fe9b (diff) | |
download | chromium_src-9cce2d32f708024bb24d0036e98a2ded583a9552.zip chromium_src-9cce2d32f708024bb24d0036e98a2ded583a9552.tar.gz chromium_src-9cce2d32f708024bb24d0036e98a2ded583a9552.tar.bz2 |
Add utility functions to Message classes.
The new functions will be used to implement other classes
that will be added in a separate patch.
BUG=90036
TEST=run unit tests
Review URL: http://codereview.chromium.org/7569020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96231 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | dbus/message.cc | 191 | ||||
-rw-r--r-- | dbus/message.h | 64 | ||||
-rw-r--r-- | dbus/message_unittest.cc | 90 |
3 files changed, 298 insertions, 47 deletions
diff --git a/dbus/message.cc b/dbus/message.cc index 8118202..79c1b77 100644 --- a/dbus/message.cc +++ b/dbus/message.cc @@ -9,6 +9,31 @@ #include "base/logging.h" #include "base/stringprintf.h" +namespace { + +// Appends the header name and the value to |output|, if the value is +// not empty. +static void AppendStringHeader(const std::string& header_name, + const std::string& header_value, + std::string* output) { + if (!header_value.empty()) { + *output += header_name + ": " + header_value + "\n"; + } +} + +// Appends the header name and the value to |output|, if the value is +// nonzero. +static void AppendUint32Header(const std::string& header_name, + uint32 header_value, + std::string* output) { + if (header_value != 0) { + *output += (header_name + ": " + base::StringPrintf("%u", header_value) + + "\n"); + } +} + +} // namespace + namespace dbus { Message::Message() @@ -178,31 +203,106 @@ std::string Message::ToString() { // Generate headers first. std::string headers; + AppendStringHeader("destination", GetDestination(), &headers); + AppendStringHeader("path", GetPath(), &headers); + AppendStringHeader("interface", GetInterface(), &headers); + AppendStringHeader("member", GetMember(), &headers); + AppendStringHeader("error_name", GetErrorName(), &headers); + AppendStringHeader("sender", GetSender(), &headers); + AppendStringHeader("signature", GetSignature(), &headers); + AppendUint32Header("serial", GetSerial(), &headers); + AppendUint32Header("reply_serial", GetReplySerial(), &headers); + + // Generate the payload. + MessageReader reader(this); + return headers + "\n" + ToStringInternal("", &reader); +} + +void Message::SetDestination(const std::string& destination) { + const bool success = dbus_message_set_destination(raw_message_, + destination.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetPath(const std::string& path) { + const bool success = dbus_message_set_path(raw_message_, + path.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetInterface(const std::string& interface) { + const bool success = dbus_message_set_interface(raw_message_, + interface.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetMember(const std::string& member) { + const bool success = dbus_message_set_member(raw_message_, + member.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetErrorName(const std::string& error_name) { + const bool success = dbus_message_set_error_name(raw_message_, + error_name.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetSender(const std::string& sender) { + const bool success = dbus_message_set_sender(raw_message_, + sender.c_str()); + CHECK(success) << "Unable to allocate memory"; +} + +void Message::SetSerial(uint32 serial) { + dbus_message_set_serial(raw_message_, serial); +} + +void Message::SetReplySerial(uint32 reply_serial) { + dbus_message_set_reply_serial(raw_message_, reply_serial); +} + +std::string Message::GetDestination() { const char* destination = dbus_message_get_destination(raw_message_); - if (destination) - headers += base::StringPrintf("destination: %s\n", destination); + return destination ? destination : ""; +} + +std::string Message::GetPath() { const char* path = dbus_message_get_path(raw_message_); - if (path) - headers += base::StringPrintf("path: %s\n", path); + return path ? path : ""; +} + +std::string Message::GetInterface() { const char* interface = dbus_message_get_interface(raw_message_); - if (interface) - headers += base::StringPrintf("interface: %s\n", interface); + return interface ? interface : ""; +} + +std::string Message::GetMember() { const char* member = dbus_message_get_member(raw_message_); - if (member) - headers += base::StringPrintf("member: %s\n", member); + return member ? member : ""; +} + +std::string Message::GetErrorName() { const char* error_name = dbus_message_get_error_name(raw_message_); - if (error_name) - headers += base::StringPrintf("error_name: %s\n", error_name); + return error_name ? error_name : ""; +} + +std::string Message::GetSender() { const char* sender = dbus_message_get_sender(raw_message_); - if (sender) - headers += base::StringPrintf("sender: %s\n", sender); + return sender ? sender : ""; +} + +std::string Message::GetSignature() { const char* signature = dbus_message_get_signature(raw_message_); - if (signature) - headers += base::StringPrintf("signature: %s\n", signature); + return signature ? signature : ""; +} - // Generate the payload. - MessageReader reader(this); - return headers + "\n" + ToStringInternal("", &reader); +uint32 Message::GetSerial() { + return dbus_message_get_serial(raw_message_); +} + +uint32 Message::GetReplySerial() { + return dbus_message_get_reply_serial(raw_message_); } // @@ -211,29 +311,24 @@ std::string Message::ToString() { MethodCall::MethodCall(const std::string& interface_name, const std::string& method_name) - : Message(), - interface_name_(interface_name), - method_name_(method_name) { + : Message() { reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL)); - bool success = dbus_message_set_interface(raw_message(), - interface_name.c_str()); - CHECK(success) << "Unable to allocate memory"; - - success = dbus_message_set_member(raw_message(), method_name.c_str()); - CHECK(success) << "Unable to allocate memory"; + SetInterface(interface_name); + SetMember(method_name); } -void MethodCall::SetServiceName(const std::string& service_name) { - const bool success = dbus_message_set_destination(raw_message(), - service_name.c_str()); - CHECK(success) << "Unable to allocate memory"; -} +MethodCall* MethodCall::FromRawMessage(DBusMessage* raw_message) { + DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message)); -void MethodCall::SetObjectPath(const std::string& object_path) { - const bool success = dbus_message_set_path(raw_message(), - object_path.c_str()); - CHECK(success) << "Unable to allocate memory"; + const char* interface = dbus_message_get_interface(raw_message); + const char* member = dbus_message_get_member(raw_message); + std::string interface_string = interface ? interface : ""; + std::string member_string = member ? member : ""; + + MethodCall* method_call = new MethodCall(interface_string, member_string); + method_call->reset_raw_message(raw_message); + return method_call; } // @@ -243,6 +338,32 @@ void MethodCall::SetObjectPath(const std::string& object_path) { Response::Response() : Message() { } +Response* Response::FromMethodCall(MethodCall* method_call) { + Response* response = new Response; + response->reset_raw_message( + dbus_message_new_method_return(method_call->raw_message())); + return response; +} + +// +// ErrorResponse implementation. +// + +ErrorResponse::ErrorResponse() : Message() { +} + +ErrorResponse* ErrorResponse::FromMethodCall( + MethodCall* method_call, + const std::string& error_name, + const std::string& error_message) { + ErrorResponse* response = new ErrorResponse; + response->reset_raw_message( + dbus_message_new_error(method_call->raw_message(), + error_name.c_str(), + error_message.c_str())); + return response; +} + // // MessageWriter implementation. // diff --git a/dbus/message.h b/dbus/message.h index 501f99a..31887a1 100644 --- a/dbus/message.h +++ b/dbus/message.h @@ -74,6 +74,30 @@ class Message { // of raw_message. raw_message_ will be unref'ed in the destructor. void reset_raw_message(DBusMessage* raw_message); + // Sets the destination, the path, the interface, the member, etc. + void SetDestination(const std::string& destination); + void SetPath(const std::string& path); + void SetInterface(const std::string& interface); + void SetMember(const std::string& member); + void SetErrorName(const std::string& error_name); + void SetSender(const std::string& sender); + void SetSerial(uint32 serial); + void SetReplySerial(uint32 reply_serial); + // SetSignature() does not exist as we cannot do it. + + // Gets the destination, the path, the interface, the member, etc. + // If not set, an empty string is returned. + std::string GetDestination(); + std::string GetPath(); + std::string GetInterface(); + std::string GetMember(); + std::string GetErrorName(); + std::string GetSender(); + std::string GetSignature(); + // Gets the serial and reply serial numbers. Returns 0 if not set. + uint32 GetSerial(); + uint32 GetReplySerial(); + // Returns the string representation of this message. Useful for // debugging. std::string ToString(); @@ -104,16 +128,10 @@ class MethodCall : public Message { MethodCall(const std::string& interface_name, const std::string& method_name); - const std::string& interface_name() { return interface_name_; } - const std::string& method_name() { return method_name_; } - - // Sets the service name. This will be handled by the object proxy. - void SetServiceName(const std::string& service_name); - // Sets the object path. This will be handled by the object proxy. - void SetObjectPath(const std::string& object_path); - - std::string interface_name_; - std::string method_name_; + // Returns a newly created MethodCall from the given raw message of the + // type DBUS_MESSAGE_TYPE_METHOD_CALL. The caller must delete the + // returned object. Takes the ownership of |raw_message|. + static MethodCall* FromRawMessage(DBusMessage* raw_message); DISALLOW_COPY_AND_ASSIGN(MethodCall); }; @@ -127,10 +145,36 @@ class Response : public Message { // response is received from the server. See object_proxy.h. Response(); + // Returns a newly created Response from the given method call. The + // caller must delete the returned object. Used for implementing + // exported methods. + static Response* FromMethodCall(MethodCall* method_call); + private: DISALLOW_COPY_AND_ASSIGN(Response); }; +// ErrorResponse is a type of message used to return an error to the +// caller of a method. +class ErrorResponse: public Message { + public: + // Creates a ErrorResponse message. The internal raw message is NULL. + // Classes that implment method calls need to set the raw message once a + // response is received from the server. See object_proxy.h. + ErrorResponse(); + + // Returns a newly created ErrorResponse from the given method call, the + // error name, and the error message. The error name looks like + // "org.freedesktop.DBus.Error.Failed". Used for returning an error to a + // failed method call. + static ErrorResponse* FromMethodCall(MethodCall* method_call, + const std::string& error_name, + const std::string& error_message); + + private: + DISALLOW_COPY_AND_ASSIGN(ErrorResponse); +}; + // MessageWriter is used to write outgoing messages for calling methods // and sending signals. // diff --git a/dbus/message_unittest.cc b/dbus/message_unittest.cc index 54a14e9..22cc309 100644 --- a/dbus/message_unittest.cc +++ b/dbus/message_unittest.cc @@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" // Test that a byte can be properly written and read. We only have this @@ -344,8 +345,8 @@ TEST(MessageTest, MethodCall) { dbus::MethodCall method_call("com.example.Interface", "SomeMethod"); EXPECT_TRUE(method_call.raw_message() != NULL); EXPECT_EQ(dbus::Message::MESSAGE_METHOD_CALL, method_call.GetMessageType()); - method_call.SetServiceName("com.example.Service"); - method_call.SetObjectPath("/com/example/Object"); + method_call.SetDestination("com.example.Service"); + method_call.SetPath("/com/example/Object"); dbus::MessageWriter writer(&method_call); writer.AppendString("payload"); @@ -360,6 +361,17 @@ TEST(MessageTest, MethodCall) { method_call.ToString()); } +TEST(MessageTest, MethodCall_FromRawMessage) { + DBusMessage* raw_message = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL); + dbus_message_set_interface(raw_message, "com.example.Interface"); + dbus_message_set_member(raw_message, "SomeMethod"); + + scoped_ptr<dbus::MethodCall> method_call( + dbus::MethodCall::FromRawMessage(raw_message)); + EXPECT_EQ("com.example.Interface", method_call->GetInterface()); + EXPECT_EQ("SomeMethod", method_call->GetMember()); +} + TEST(MessageTest, Response) { dbus::Response response; EXPECT_TRUE(response.raw_message() == NULL); @@ -368,7 +380,81 @@ TEST(MessageTest, Response) { EXPECT_EQ(dbus::Message::MESSAGE_METHOD_RETURN, response.GetMessageType()); } +TEST(MergeTest, Response_FromMethodCall) { + const uint32 kSerial = 123; + dbus::MethodCall method_call("com.example.Interface", "SomeMethod"); + method_call.SetSerial(kSerial); + + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(&method_call)); + EXPECT_EQ(dbus::Message::MESSAGE_METHOD_RETURN, response->GetMessageType()); + // The serial should be copied to the reply serial. + EXPECT_EQ(kSerial, response->GetReplySerial()); +} + +TEST(MergeTest, ErrorResponse) { + dbus::ErrorResponse error_response; + EXPECT_TRUE(error_response.raw_message() == NULL); + error_response.reset_raw_message( + dbus_message_new(DBUS_MESSAGE_TYPE_ERROR)); + EXPECT_EQ(dbus::Message::MESSAGE_ERROR, error_response.GetMessageType()); +} + +TEST(MergeTest, ErrorResponse_FromMethodCall) { + const uint32 kSerial = 123; +const char kErrorMessage[] = "error message"; + + dbus::MethodCall method_call("com.example.Interface", "SomeMethod"); + method_call.SetSerial(kSerial); + + scoped_ptr<dbus::ErrorResponse> error_response( + dbus::ErrorResponse::FromMethodCall(&method_call, + DBUS_ERROR_FAILED, + kErrorMessage)); + EXPECT_EQ(dbus::Message::MESSAGE_ERROR, error_response->GetMessageType()); + // The serial should be copied to the reply serial. + EXPECT_EQ(kSerial, error_response->GetReplySerial()); + + // Error message should be added to the payload. + dbus::MessageReader reader(error_response.get()); + std::string error_message; + ASSERT_TRUE(reader.PopString(&error_message)); + EXPECT_EQ(kErrorMessage, error_message); +} + TEST(MessageTest, ToString_EmptyMessage) { dbus::Message message; EXPECT_EQ("", message.ToString()); } + +TEST(MessageTest, GetAndSetHeaders) { + dbus::Message message; + message.reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL)); + + EXPECT_EQ("", message.GetDestination()); + EXPECT_EQ("", message.GetPath()); + EXPECT_EQ("", message.GetInterface()); + EXPECT_EQ("", message.GetMember()); + EXPECT_EQ("", message.GetErrorName()); + EXPECT_EQ("", message.GetSender()); + EXPECT_EQ(0U, message.GetSerial()); + EXPECT_EQ(0U, message.GetReplySerial()); + + message.SetDestination("org.chromium.destination"); + message.SetPath("/org/chromium/path"); + message.SetInterface("org.chromium.interface"); + message.SetMember("member"); + message.SetErrorName("org.chromium.error"); + message.SetSender(":1.2"); + message.SetSerial(123); + message.SetReplySerial(456); + + EXPECT_EQ("org.chromium.destination", message.GetDestination()); + EXPECT_EQ("/org/chromium/path", message.GetPath()); + EXPECT_EQ("org.chromium.interface", message.GetInterface()); + EXPECT_EQ("member", message.GetMember()); + EXPECT_EQ("org.chromium.error", message.GetErrorName()); + EXPECT_EQ(":1.2", message.GetSender()); + EXPECT_EQ(123U, message.GetSerial()); + EXPECT_EQ(456U, message.GetReplySerial()); +} |