summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorsatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-10 22:34:02 +0000
committersatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-10 22:34:02 +0000
commit9cce2d32f708024bb24d0036e98a2ded583a9552 (patch)
treefb80fe7896ce20361a777ae429bc74475f039f11 /dbus
parentdb6d774d0055bc4d1f79ced2b93dd2ea2a56fe9b (diff)
downloadchromium_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
Diffstat (limited to 'dbus')
-rw-r--r--dbus/message.cc191
-rw-r--r--dbus/message.h64
-rw-r--r--dbus/message_unittest.cc90
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());
+}