diff options
author | zork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-09 06:05:14 +0000 |
---|---|---|
committer | zork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-09 06:06:54 +0000 |
commit | 2628798e0864a40f39ce6d3f58c13bf8d1274e21 (patch) | |
tree | c7e42a74e7c4ae6a9023a48ab55824d64a02b4fb /components/pairing | |
parent | 5fe215c80e32d8576cc590057819b8ef95fdee8b (diff) | |
download | chromium_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.gn | 14 | ||||
-rw-r--r-- | components/pairing/message_buffer.cc | 56 | ||||
-rw-r--r-- | components/pairing/message_buffer.h | 52 | ||||
-rw-r--r-- | components/pairing/message_buffer_unittest.cc | 84 |
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 |