Commit 9cce2d32 authored by satorux@chromium.org's avatar satorux@chromium.org

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
parent db6d774d
...@@ -9,6 +9,31 @@ ...@@ -9,6 +9,31 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/stringprintf.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 { namespace dbus {
Message::Message() Message::Message()
...@@ -178,31 +203,106 @@ std::string Message::ToString() { ...@@ -178,31 +203,106 @@ std::string Message::ToString() {
// Generate headers first. // Generate headers first.
std::string headers; 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_); const char* destination = dbus_message_get_destination(raw_message_);
if (destination) return destination ? destination : "";
headers += base::StringPrintf("destination: %s\n", destination); }
std::string Message::GetPath() {
const char* path = dbus_message_get_path(raw_message_); const char* path = dbus_message_get_path(raw_message_);
if (path) return path ? path : "";
headers += base::StringPrintf("path: %s\n", path); }
std::string Message::GetInterface() {
const char* interface = dbus_message_get_interface(raw_message_); const char* interface = dbus_message_get_interface(raw_message_);
if (interface) return interface ? interface : "";
headers += base::StringPrintf("interface: %s\n", interface); }
std::string Message::GetMember() {
const char* member = dbus_message_get_member(raw_message_); const char* member = dbus_message_get_member(raw_message_);
if (member) return member ? member : "";
headers += base::StringPrintf("member: %s\n", member); }
std::string Message::GetErrorName() {
const char* error_name = dbus_message_get_error_name(raw_message_); const char* error_name = dbus_message_get_error_name(raw_message_);
if (error_name) return error_name ? error_name : "";
headers += base::StringPrintf("error_name: %s\n", error_name); }
std::string Message::GetSender() {
const char* sender = dbus_message_get_sender(raw_message_); const char* sender = dbus_message_get_sender(raw_message_);
if (sender) return sender ? sender : "";
headers += base::StringPrintf("sender: %s\n", sender); }
std::string Message::GetSignature() {
const char* signature = dbus_message_get_signature(raw_message_); const char* signature = dbus_message_get_signature(raw_message_);
if (signature) return signature ? signature : "";
headers += base::StringPrintf("signature: %s\n", signature); }
// Generate the payload. uint32 Message::GetSerial() {
MessageReader reader(this); return dbus_message_get_serial(raw_message_);
return headers + "\n" + ToStringInternal("", &reader); }
uint32 Message::GetReplySerial() {
return dbus_message_get_reply_serial(raw_message_);
} }
// //
...@@ -211,29 +311,24 @@ std::string Message::ToString() { ...@@ -211,29 +311,24 @@ std::string Message::ToString() {
MethodCall::MethodCall(const std::string& interface_name, MethodCall::MethodCall(const std::string& interface_name,
const std::string& method_name) const std::string& method_name)
: Message(), : Message() {
interface_name_(interface_name),
method_name_(method_name) {
reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL)); reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));
bool success = dbus_message_set_interface(raw_message(), SetInterface(interface_name);
interface_name.c_str()); SetMember(method_name);
CHECK(success) << "Unable to allocate memory";
success = dbus_message_set_member(raw_message(), method_name.c_str());
CHECK(success) << "Unable to allocate memory";
} }
void MethodCall::SetServiceName(const std::string& service_name) { MethodCall* MethodCall::FromRawMessage(DBusMessage* raw_message) {
const bool success = dbus_message_set_destination(raw_message(), DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));
service_name.c_str());
CHECK(success) << "Unable to allocate memory";
}
void MethodCall::SetObjectPath(const std::string& object_path) { const char* interface = dbus_message_get_interface(raw_message);
const bool success = dbus_message_set_path(raw_message(), const char* member = dbus_message_get_member(raw_message);
object_path.c_str()); std::string interface_string = interface ? interface : "";
CHECK(success) << "Unable to allocate memory"; 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) { ...@@ -243,6 +338,32 @@ void MethodCall::SetObjectPath(const std::string& object_path) {
Response::Response() : Message() { 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. // MessageWriter implementation.
// //
......
...@@ -74,6 +74,30 @@ class Message { ...@@ -74,6 +74,30 @@ class Message {
// of raw_message. raw_message_ will be unref'ed in the destructor. // of raw_message. raw_message_ will be unref'ed in the destructor.
void reset_raw_message(DBusMessage* raw_message); 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 // Returns the string representation of this message. Useful for
// debugging. // debugging.
std::string ToString(); std::string ToString();
...@@ -104,16 +128,10 @@ class MethodCall : public Message { ...@@ -104,16 +128,10 @@ class MethodCall : public Message {
MethodCall(const std::string& interface_name, MethodCall(const std::string& interface_name,
const std::string& method_name); const std::string& method_name);
const std::string& interface_name() { return interface_name_; } // Returns a newly created MethodCall from the given raw message of the
const std::string& method_name() { return method_name_; } // type DBUS_MESSAGE_TYPE_METHOD_CALL. The caller must delete the
// returned object. Takes the ownership of |raw_message|.
// Sets the service name. This will be handled by the object proxy. static MethodCall* FromRawMessage(DBusMessage* raw_message);
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_;
DISALLOW_COPY_AND_ASSIGN(MethodCall); DISALLOW_COPY_AND_ASSIGN(MethodCall);
}; };
...@@ -127,10 +145,36 @@ class Response : public Message { ...@@ -127,10 +145,36 @@ class Response : public Message {
// response is received from the server. See object_proxy.h. // response is received from the server. See object_proxy.h.
Response(); 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: private:
DISALLOW_COPY_AND_ASSIGN(Response); 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 // MessageWriter is used to write outgoing messages for calling methods
// and sending signals. // and sending signals.
// //
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
// Test that a byte can be properly written and read. We only have this // Test that a byte can be properly written and read. We only have this
...@@ -344,8 +345,8 @@ TEST(MessageTest, MethodCall) { ...@@ -344,8 +345,8 @@ TEST(MessageTest, MethodCall) {
dbus::MethodCall method_call("com.example.Interface", "SomeMethod"); dbus::MethodCall method_call("com.example.Interface", "SomeMethod");
EXPECT_TRUE(method_call.raw_message() != NULL); EXPECT_TRUE(method_call.raw_message() != NULL);
EXPECT_EQ(dbus::Message::MESSAGE_METHOD_CALL, method_call.GetMessageType()); EXPECT_EQ(dbus::Message::MESSAGE_METHOD_CALL, method_call.GetMessageType());
method_call.SetServiceName("com.example.Service"); method_call.SetDestination("com.example.Service");
method_call.SetObjectPath("/com/example/Object"); method_call.SetPath("/com/example/Object");
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
writer.AppendString("payload"); writer.AppendString("payload");
...@@ -360,6 +361,17 @@ TEST(MessageTest, MethodCall) { ...@@ -360,6 +361,17 @@ TEST(MessageTest, MethodCall) {
method_call.ToString()); 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) { TEST(MessageTest, Response) {
dbus::Response response; dbus::Response response;
EXPECT_TRUE(response.raw_message() == NULL); EXPECT_TRUE(response.raw_message() == NULL);
...@@ -368,7 +380,81 @@ TEST(MessageTest, Response) { ...@@ -368,7 +380,81 @@ TEST(MessageTest, Response) {
EXPECT_EQ(dbus::Message::MESSAGE_METHOD_RETURN, response.GetMessageType()); 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) { TEST(MessageTest, ToString_EmptyMessage) {
dbus::Message message; dbus::Message message;
EXPECT_EQ("", message.ToString()); 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());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment