summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/components_tests.gyp4
-rw-r--r--components/pairing.gypi7
-rw-r--r--components/pairing/BUILD.gn14
-rw-r--r--components/pairing/message_buffer.cc56
-rw-r--r--components/pairing/message_buffer.h52
-rw-r--r--components/pairing/message_buffer_unittest.cc84
6 files changed, 215 insertions, 2 deletions
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 6074c87..c6f9a8f 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -601,10 +601,14 @@
],
}],
['chromeos==1', {
+ 'sources': [
+ 'pairing/message_buffer_unittest.cc',
+ ],
'sources!': [
'storage_monitor/storage_monitor_linux_unittest.cc',
],
'dependencies': [
+ 'components.gyp:pairing',
'../chromeos/chromeos.gyp:chromeos_test_support',
],
}],
diff --git a/components/pairing.gypi b/components/pairing.gypi
index b6c00ff..35f13c9 100644
--- a/components/pairing.gypi
+++ b/components/pairing.gypi
@@ -14,16 +14,19 @@
'pairing_api_proto',
'../base/base.gyp:base',
'../device/bluetooth/bluetooth.gyp:device_bluetooth',
+ '../net/net.gyp:net',
],
'sources': [
+ 'pairing/controller_pairing_controller.cc',
+ 'pairing/controller_pairing_controller.h',
'pairing/fake_controller_pairing_controller.cc',
'pairing/fake_controller_pairing_controller.h',
'pairing/fake_host_pairing_controller.cc',
'pairing/fake_host_pairing_controller.h',
- 'pairing/controller_pairing_controller.cc',
- 'pairing/controller_pairing_controller.h',
'pairing/host_pairing_controller.cc',
'pairing/host_pairing_controller.h',
+ 'pairing/message_buffer.cc',
+ 'pairing/message_buffer.h',
],
},
{
diff --git a/components/pairing/BUILD.gn b/components/pairing/BUILD.gn
index af7b979..55f29ed 100644
--- a/components/pairing/BUILD.gn
+++ b/components/pairing/BUILD.gn
@@ -14,11 +14,25 @@ source_set("pairing") {
"pairing/controller_pairing_controller.h",
"pairing/host_pairing_controller.cc",
"pairing/host_pairing_controller.h",
+ "pairing/message_buffer.cc",
+ "pairing/message_buffer.h",
]
deps = [
"//base",
"//device/bluetooth",
+ "//net",
+ ]
+}
+
+source_set("unit_tests") {
+ sources = [
+ "message_buffer_unittest.cc",
+ ]
+
+ deps = [
+ ":pairing",
+ "//testing/gtest",
]
}
diff --git a/components/pairing/message_buffer.cc b/components/pairing/message_buffer.cc
new file mode 100644
index 0000000..3cfe95d
--- /dev/null
+++ b/components/pairing/message_buffer.cc
@@ -0,0 +1,56 @@
+// Copyright 2014 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.
+
+#include "components/pairing/message_buffer.h"
+
+#include "net/base/io_buffer.h"
+
+namespace pairing_chromeos {
+
+MessageBuffer::MessageBuffer()
+ : buffer_offset_(0),
+ total_buffer_size_(0) {
+}
+
+MessageBuffer::~MessageBuffer() {}
+
+int MessageBuffer::AvailableBytes() {
+ return total_buffer_size_ - buffer_offset_;
+}
+
+void MessageBuffer::ReadBytes(char* buffer, int size) {
+ CHECK_LE(size, AvailableBytes());
+
+ int offset = 0;
+ while (offset < size) {
+ scoped_refptr<net::IOBuffer> io_buffer = pending_data_.front().first;
+ int io_buffer_size = pending_data_.front().second;
+
+ CHECK_GT(io_buffer_size, buffer_offset_);
+ int copy_size = std::min(size - offset, io_buffer_size - buffer_offset_);
+ memcpy(&buffer[offset], &io_buffer->data()[buffer_offset_], copy_size);
+
+ offset += copy_size;
+ buffer_offset_ += copy_size;
+
+ CHECK_LE(buffer_offset_, io_buffer_size);
+ if (buffer_offset_ == io_buffer_size) {
+ CHECK_GE(total_buffer_size_, io_buffer_size);
+ total_buffer_size_ -= io_buffer_size;
+ pending_data_.pop_front();
+ buffer_offset_ = 0;
+ }
+ }
+ CHECK_EQ(offset, size);
+}
+
+void MessageBuffer::AddIOBuffer(scoped_refptr<net::IOBuffer> io_buffer,
+ int size) {
+ if (size == 0)
+ return;
+ pending_data_.push_back(std::make_pair(io_buffer, size));
+ total_buffer_size_ += size;
+}
+
+} // namespace pairing_chromeos
diff --git a/components/pairing/message_buffer.h b/components/pairing/message_buffer.h
new file mode 100644
index 0000000..8b2fcc0
--- /dev/null
+++ b/components/pairing/message_buffer.h
@@ -0,0 +1,52 @@
+// Copyright 2014 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.
+
+#ifndef COMPONENTS_PAIRING_MESSAGE_BUFFER_H_
+#define COMPONENTS_PAIRING_MESSAGE_BUFFER_H_
+
+#include <deque>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+
+namespace net {
+class IOBuffer;
+}
+
+namespace pairing_chromeos {
+
+// A MessageBuffer is a simple wrapper around an ordered set of buffers received
+// from a socket. It keeps track of the amount of unread data, and allows data
+// to be retreived that was split across buffers in a single chunk.
+class MessageBuffer {
+ public:
+ MessageBuffer();
+ ~MessageBuffer();
+
+ // Returns the number of bytes currently received, but not yet read.
+ int AvailableBytes();
+
+ // Read |size| bytes into |buffer|. |size| must be smaller than or equal to
+ // the current number of available bytes.
+ void ReadBytes(char* buffer, int size);
+
+ // Add the data from an IOBuffer. A reference to the IOBuffer will be
+ // maintained until it is drained.
+ void AddIOBuffer(scoped_refptr<net::IOBuffer> io_buffer, int size);
+
+ private:
+ // Offset of the next byte to be read from the current IOBuffer.
+ int buffer_offset_;
+ // Total number of bytes in IOBuffers in |pending_data_|, including bytes that
+ // have already been read.
+ int total_buffer_size_;
+ std::deque<std::pair<scoped_refptr<net::IOBuffer>, int> > pending_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageBuffer);
+};
+
+} // namespace pairing_chromeos
+
+#endif // COMPONENTS_PAIRING_MESSAGE_BUFFER_H_
diff --git a/components/pairing/message_buffer_unittest.cc b/components/pairing/message_buffer_unittest.cc
new file mode 100644
index 0000000..2f9fe40
--- /dev/null
+++ b/components/pairing/message_buffer_unittest.cc
@@ -0,0 +1,84 @@
+// Copyright 2014 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.
+
+#include "components/pairing/message_buffer.h"
+
+#include "net/base/io_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace pairing_chromeos {
+
+typedef testing::Test MessageBufferTest;
+
+TEST_F(MessageBufferTest, BasicReadWrite) {
+ MessageBuffer message_buffer;
+ scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(3));
+ io_buffer->data()[0] = 3;
+ io_buffer->data()[1] = 1;
+ io_buffer->data()[2] = 4;
+
+ message_buffer.AddIOBuffer(io_buffer, 3);
+
+ EXPECT_EQ(message_buffer.AvailableBytes(), 3);
+ char data = 0;
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 3);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 2);
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 1);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 1);
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 4);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 0);
+}
+
+TEST_F(MessageBufferTest, SplitBuffer) {
+ MessageBuffer message_buffer;
+ scoped_refptr<net::IOBuffer> io_buffer0(new net::IOBuffer(1));
+ io_buffer0->data()[0] = 3;
+
+ scoped_refptr<net::IOBuffer> io_buffer1(new net::IOBuffer(2));
+ io_buffer1->data()[0] = 1;
+ io_buffer1->data()[1] = 4;
+
+ message_buffer.AddIOBuffer(io_buffer0, 1);
+ message_buffer.AddIOBuffer(io_buffer1, 2);
+
+ EXPECT_EQ(message_buffer.AvailableBytes(), 3);
+ char data[3];
+ message_buffer.ReadBytes(data, 3);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 0);
+ EXPECT_EQ(data[0], 3);
+ EXPECT_EQ(data[1], 1);
+ EXPECT_EQ(data[2], 4);
+}
+
+TEST_F(MessageBufferTest, EmptyBuffer) {
+ MessageBuffer message_buffer;
+ scoped_refptr<net::IOBuffer> io_buffer0(new net::IOBuffer(1));
+ io_buffer0->data()[0] = 3;
+
+ scoped_refptr<net::IOBuffer> io_buffer1(new net::IOBuffer(0));
+ scoped_refptr<net::IOBuffer> io_buffer2(new net::IOBuffer(2));
+ io_buffer2->data()[0] = 1;
+ io_buffer2->data()[1] = 4;
+
+ message_buffer.AddIOBuffer(io_buffer0, 1);
+ message_buffer.AddIOBuffer(io_buffer1, 0);
+ message_buffer.AddIOBuffer(io_buffer2, 2);
+
+ EXPECT_EQ(message_buffer.AvailableBytes(), 3);
+ char data = 0;
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 3);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 2);
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 1);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 1);
+ message_buffer.ReadBytes(&data, 1);
+ EXPECT_EQ(data, 4);
+ EXPECT_EQ(message_buffer.AvailableBytes(), 0);
+}
+
+} // namespace pairing_chromeos