diff options
-rw-r--r-- | dbus/DEPS | 4 | ||||
-rw-r--r-- | dbus/dbus.gyp | 14 | ||||
-rw-r--r-- | dbus/message.cc | 31 | ||||
-rw-r--r-- | dbus/message.h | 25 | ||||
-rw-r--r-- | dbus/message_unittest.cc | 17 | ||||
-rw-r--r-- | dbus/test_proto.proto | 13 |
6 files changed, 103 insertions, 1 deletions
diff --git a/dbus/DEPS b/dbus/DEPS new file mode 100644 index 0000000..736586e --- /dev/null +++ b/dbus/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+base", + "+third_party/protobuf", +]
\ No newline at end of file diff --git a/dbus/dbus.gyp b/dbus/dbus.gyp index ce2fbd4..2dc8fee 100644 --- a/dbus/dbus.gyp +++ b/dbus/dbus.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -13,6 +13,7 @@ 'dependencies': [ '../base/base.gyp:base', '../build/linux/system.gyp:dbus', + '../third_party/protobuf/protobuf.gyp:protobuf_lite', ], 'export_dependent_settings': [ '../base/base.gyp:base', @@ -30,6 +31,16 @@ ], }, { + # Protobuf compiler / generator test protocol buffer + 'target_name': 'dbus_test_proto', + 'type': 'static_library', + 'sources': [ 'test_proto.proto' ], + 'variables': { + 'proto_out_dir': 'dbus', + }, + 'includes': [ '../build/protoc.gypi' ], + }, + { # This target contains mocks that can be used to write unit tests # without issuing actual D-Bus calls. 'target_name': 'dbus_test_support', @@ -60,6 +71,7 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', 'dbus', + 'dbus_test_proto', 'dbus_test_support', ], 'sources': [ diff --git a/dbus/message.cc b/dbus/message.cc index bf2c2c3..db8184e 100644 --- a/dbus/message.cc +++ b/dbus/message.cc @@ -4,10 +4,13 @@ #include "dbus/message.h" +#include <string> + #include "base/basictypes.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/stringprintf.h" +#include "third_party/protobuf/src/google/protobuf/message_lite.h" namespace { @@ -593,6 +596,18 @@ void MessageWriter::AppendArrayOfObjectPaths( CloseContainer(&array_writer); } +bool MessageWriter::AppendProtoAsArrayOfBytes( + const google::protobuf::MessageLite& protobuf) { + std::string serialized_proto; + if (!protobuf.SerializeToString(&serialized_proto)) { + LOG(ERROR) << "Unable to serialize supplied protocol buffer"; + return false; + } + AppendArrayOfBytes(reinterpret_cast<const uint8*>(serialized_proto.data()), + serialized_proto.size()); + return true; +} + void MessageWriter::AppendVariantOfByte(uint8 value) { AppendVariantOfBasic(DBUS_TYPE_BYTE, &value); } @@ -801,6 +816,22 @@ bool MessageReader::PopArrayOfObjectPaths( return true; } +bool MessageReader::PopArrayOfBytesAsProto( + google::protobuf::MessageLite* protobuf) { + DCHECK(protobuf != NULL); + char* serialized_buf = NULL; + size_t buf_size = 0; + if (!PopArrayOfBytes(reinterpret_cast<uint8**>(&serialized_buf), &buf_size)) { + LOG(ERROR) << "Error reading array of bytes"; + return false; + } + if (!protobuf->ParseFromArray(serialized_buf, buf_size)) { + LOG(ERROR) << "Failed to parse protocol buffer from array"; + return false; + } + return true; +} + bool MessageReader::PopVariantOfByte(uint8* value) { return PopVariantOfBasic(DBUS_TYPE_BYTE, value); } diff --git a/dbus/message.h b/dbus/message.h index a4b0f9b..54227a0 100644 --- a/dbus/message.h +++ b/dbus/message.h @@ -12,6 +12,15 @@ #include "base/basictypes.h" +namespace google { +namespace protobuf { + +class MessageLite; + +} // namespace protobuf +} // namespace google + + namespace dbus { class MessageWriter; @@ -295,6 +304,14 @@ class MessageWriter { // specialized function. void AppendArrayOfObjectPaths(const std::vector<std::string>& object_paths); + // Appends the protocol buffer as an array of bytes. The buffer is serialized + // into an array of bytes before communication, since protocol buffers are not + // a native dbus type. On the receiving size the array of bytes needs to be + // read and deserialized into a protocol buffer of the correct type. There are + // methods in MessageReader to assist in this. Return true on succes and fail + // when serialization is not successful. + bool AppendProtoAsArrayOfBytes(const google::protobuf::MessageLite& protobuf); + // Appends the byte wrapped in a variant data container. Variants are // widely used in D-Bus services so it's worth having a specialized // function. For instance, The third parameter of @@ -394,6 +411,14 @@ class MessageReader { // function. bool PopArrayOfObjectPaths(std::vector<std::string>* object_paths); + // Gets the array of bytes at the current iterator position. It then parses + // this binary blob into the protocol buffer supplied. + // Returns true and advances the iterator on success. On failure returns false + // and emits an error message on the source of the failure. The two most + // common errors come from the iterator not currently being at a byte array or + // the wrong type of protocol buffer is passed in and the parse fails. + bool PopArrayOfBytesAsProto(google::protobuf::MessageLite* protobuf); + // Gets the byte from the variant data container at the current iterator // position. // Returns true and advances the iterator on success. diff --git a/dbus/message_unittest.cc b/dbus/message_unittest.cc index 7ef49fe..1e6d668 100644 --- a/dbus/message_unittest.cc +++ b/dbus/message_unittest.cc @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "dbus/test_proto.pb.h" #include "testing/gtest/include/gtest/gtest.h" // Test that a byte can be properly written and read. We only have this @@ -226,6 +227,22 @@ TEST(MessageTest, ArrayOfObjectPaths) { EXPECT_EQ("/object/path/3", output_object_paths[2]); } +TEST(MessageTest, ProtoBuf) { + scoped_ptr<dbus::Response> message(dbus::Response::CreateEmpty()); + dbus::MessageWriter writer(message.get()); + TestProto send_message; + send_message.set_text("testing"); + send_message.set_number(123); + writer.AppendProtoAsArrayOfBytes(send_message); + + dbus::MessageReader reader(message.get()); + TestProto receive_message; + ASSERT_TRUE(reader.PopArrayOfBytesAsProto(&receive_message)); + EXPECT_EQ(receive_message.text(), send_message.text()); + EXPECT_EQ(receive_message.number(), send_message.number()); +} + + // Test that an array can be properly written and read. We only have this // test for array, as repeating this for other container types is too // redundant. diff --git a/dbus/test_proto.proto b/dbus/test_proto.proto new file mode 100644 index 0000000..82279f6 --- /dev/null +++ b/dbus/test_proto.proto @@ -0,0 +1,13 @@ +// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +option optimize_for = LITE_RUNTIME; + +// This is a simple dummy protocol buffer that is used for testing handling of +// protocol buffers in MessageReader and MessageWriter. + +message TestProto { + optional string text = 1; + optional int32 number = 2; +}
\ No newline at end of file |