summaryrefslogtreecommitdiffstats
path: root/components/pairing
diff options
context:
space:
mode:
authorzork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-09 06:05:14 +0000
committerzork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-09 06:06:54 +0000
commit2628798e0864a40f39ce6d3f58c13bf8d1274e21 (patch)
treec7e42a74e7c4ae6a9023a48ab55824d64a02b4fb /components/pairing
parent5fe215c80e32d8576cc590057819b8ef95fdee8b (diff)
downloadchromium_src-2628798e0864a40f39ce6d3f58c13bf8d1274e21.zip
chromium_src-2628798e0864a40f39ce6d3f58c13bf8d1274e21.tar.gz
chromium_src-2628798e0864a40f39ce6d3f58c13bf8d1274e21.tar.bz2
Add MessageBuffer class, which will manage the data received from a
bluetooth socket. BUG=380961,380962 Review URL: https://codereview.chromium.org/448753004 Cr-Commit-Position: refs/heads/master@{#288524} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/pairing')
-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
4 files changed, 206 insertions, 0 deletions
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