From e7547d55453e23134ede6f5f1bcb82bcc649eb4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Thu, 1 Nov 2018 09:33:08 +0100 Subject: [PATCH] Move MemoryStream to separate source files, and to a test target. Also delete the base class MemoryStreamBase. Bug: webrtc:6424 Change-Id: I7eec40ecff17c7c65fdf55882bccb2abaf1d5d84 Reviewed-on: https://webrtc-review.googlesource.com/c/108622 Commit-Queue: Niels Moller Reviewed-by: Karl Wiberg Cr-Commit-Position: refs/heads/master@{#25494} --- p2p/base/pseudotcp_unittest.cc | 2 +- rtc_base/BUILD.gn | 2 + rtc_base/memory_stream.cc | 143 ++++++++++++++++++++++++++ rtc_base/memory_stream.h | 59 +++++++++++ rtc_base/sslstreamadapter_unittest.cc | 1 + rtc_base/stream.cc | 137 ------------------------ rtc_base/stream.h | 57 ---------- 7 files changed, 206 insertions(+), 195 deletions(-) create mode 100644 rtc_base/memory_stream.cc create mode 100644 rtc_base/memory_stream.h diff --git a/p2p/base/pseudotcp_unittest.cc b/p2p/base/pseudotcp_unittest.cc index dd86f921d5..2fc9900cbc 100644 --- a/p2p/base/pseudotcp_unittest.cc +++ b/p2p/base/pseudotcp_unittest.cc @@ -15,8 +15,8 @@ #include "p2p/base/pseudotcp.h" #include "rtc_base/gunit.h" #include "rtc_base/helpers.h" +#include "rtc_base/memory_stream.h" #include "rtc_base/messagehandler.h" -#include "rtc_base/stream.h" #include "rtc_base/thread.h" #include "rtc_base/timeutils.h" diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 3f02fb7f0e..20ba8244bc 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -960,6 +960,8 @@ rtc_source_set("rtc_base_tests_utils") { "firewallsocketserver.h", "gunit.cc", "gunit.h", + "memory_stream.cc", + "memory_stream.h", "memory_usage.cc", "memory_usage.h", "natserver.cc", diff --git a/rtc_base/memory_stream.cc b/rtc_base/memory_stream.cc new file mode 100644 index 0000000000..541de070c7 --- /dev/null +++ b/rtc_base/memory_stream.cc @@ -0,0 +1,143 @@ +/* + * Copyright 2018 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include + +#include "rtc_base/memory_stream.h" + +namespace rtc { + +StreamState MemoryStream::GetState() const { + return SS_OPEN; +} + +StreamResult MemoryStream::Read(void* buffer, + size_t bytes, + size_t* bytes_read, + int* error) { + if (seek_position_ >= data_length_) { + return SR_EOS; + } + size_t available = data_length_ - seek_position_; + if (bytes > available) { + // Read partial buffer + bytes = available; + } + memcpy(buffer, &buffer_[seek_position_], bytes); + seek_position_ += bytes; + if (bytes_read) { + *bytes_read = bytes; + } + return SR_SUCCESS; +} + +StreamResult MemoryStream::Write(const void* buffer, + size_t bytes, + size_t* bytes_written, + int* error) { + size_t available = buffer_length_ - seek_position_; + if (0 == available) { + // Increase buffer size to the larger of: + // a) new position rounded up to next 256 bytes + // b) double the previous length + size_t new_buffer_length = + std::max(((seek_position_ + bytes) | 0xFF) + 1, buffer_length_ * 2); + StreamResult result = DoReserve(new_buffer_length, error); + if (SR_SUCCESS != result) { + return result; + } + RTC_DCHECK(buffer_length_ >= new_buffer_length); + available = buffer_length_ - seek_position_; + } + + if (bytes > available) { + bytes = available; + } + memcpy(&buffer_[seek_position_], buffer, bytes); + seek_position_ += bytes; + if (data_length_ < seek_position_) { + data_length_ = seek_position_; + } + if (bytes_written) { + *bytes_written = bytes; + } + return SR_SUCCESS; +} + +void MemoryStream::Close() { + // nothing to do +} + +bool MemoryStream::SetPosition(size_t position) { + if (position > data_length_) + return false; + seek_position_ = position; + return true; +} + +bool MemoryStream::GetPosition(size_t* position) const { + if (position) + *position = seek_position_; + return true; +} + +bool MemoryStream::GetSize(size_t* size) const { + if (size) + *size = data_length_; + return true; +} + +bool MemoryStream::ReserveSize(size_t size) { + return (SR_SUCCESS == DoReserve(size, nullptr)); +} + +/////////////////////////////////////////////////////////////////////////////// + +MemoryStream::MemoryStream() {} + +MemoryStream::MemoryStream(const char* data) { + SetData(data, strlen(data)); +} + +MemoryStream::MemoryStream(const void* data, size_t length) { + SetData(data, length); +} + +MemoryStream::~MemoryStream() { + delete[] buffer_; +} + +void MemoryStream::SetData(const void* data, size_t length) { + data_length_ = buffer_length_ = length; + delete[] buffer_; + buffer_ = new char[buffer_length_]; + memcpy(buffer_, data, data_length_); + seek_position_ = 0; +} + +StreamResult MemoryStream::DoReserve(size_t size, int* error) { + if (buffer_length_ >= size) + return SR_SUCCESS; + + if (char* new_buffer = new char[size]) { + memcpy(new_buffer, buffer_, data_length_); + delete[] buffer_; + buffer_ = new_buffer; + buffer_length_ = size; + return SR_SUCCESS; + } + + if (error) { + *error = ENOMEM; + } + return SR_ERROR; +} + +} // namespace rtc diff --git a/rtc_base/memory_stream.h b/rtc_base/memory_stream.h new file mode 100644 index 0000000000..936f71b34c --- /dev/null +++ b/rtc_base/memory_stream.h @@ -0,0 +1,59 @@ +/* + * Copyright 2018 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_MEMORY_STREAM_H_ +#define RTC_BASE_MEMORY_STREAM_H_ + +#include "rtc_base/stream.h" + +namespace rtc { + +// MemoryStream dynamically resizes to accomodate written data. + +class MemoryStream final : public StreamInterface { + public: + MemoryStream(); + explicit MemoryStream(const char* data); // Calls SetData(data, strlen(data)) + MemoryStream(const void* data, size_t length); // Calls SetData(data, length) + ~MemoryStream() override; + + StreamState GetState() const override; + StreamResult Read(void* buffer, + size_t bytes, + size_t* bytes_read, + int* error) override; + StreamResult Write(const void* buffer, + size_t bytes, + size_t* bytes_written, + int* error) override; + void Close() override; + bool SetPosition(size_t position) override; + bool GetPosition(size_t* position) const override; + bool GetSize(size_t* size) const override; + bool ReserveSize(size_t size) override; + + char* GetBuffer() { return buffer_; } + const char* GetBuffer() const { return buffer_; } + + void SetData(const void* data, size_t length); + + private: + StreamResult DoReserve(size_t size, int* error); + + // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_ + char* buffer_ = nullptr; + size_t buffer_length_ = 0; + size_t data_length_ = 0; + size_t seek_position_ = 0; +}; + +} // namespace rtc + +#endif // RTC_BASE_MEMORY_STREAM_H_ diff --git a/rtc_base/sslstreamadapter_unittest.cc b/rtc_base/sslstreamadapter_unittest.cc index ff4c7a0d92..6fbb1d7c2c 100644 --- a/rtc_base/sslstreamadapter_unittest.cc +++ b/rtc_base/sslstreamadapter_unittest.cc @@ -17,6 +17,7 @@ #include "rtc_base/checks.h" #include "rtc_base/gunit.h" #include "rtc_base/helpers.h" +#include "rtc_base/memory_stream.h" #include "rtc_base/messagedigest.h" #include "rtc_base/ssladapter.h" #include "rtc_base/sslidentity.h" diff --git a/rtc_base/stream.cc b/rtc_base/stream.cc index c1496390e2..783625c67a 100644 --- a/rtc_base/stream.cc +++ b/rtc_base/stream.cc @@ -347,143 +347,6 @@ void FileStream::DoClose() { fclose(file_); } -/////////////////////////////////////////////////////////////////////////////// -// MemoryStream -/////////////////////////////////////////////////////////////////////////////// - -MemoryStreamBase::MemoryStreamBase() - : buffer_(nullptr), buffer_length_(0), data_length_(0), seek_position_(0) {} - -StreamState MemoryStreamBase::GetState() const { - return SS_OPEN; -} - -StreamResult MemoryStreamBase::Read(void* buffer, - size_t bytes, - size_t* bytes_read, - int* error) { - if (seek_position_ >= data_length_) { - return SR_EOS; - } - size_t available = data_length_ - seek_position_; - if (bytes > available) { - // Read partial buffer - bytes = available; - } - memcpy(buffer, &buffer_[seek_position_], bytes); - seek_position_ += bytes; - if (bytes_read) { - *bytes_read = bytes; - } - return SR_SUCCESS; -} - -StreamResult MemoryStreamBase::Write(const void* buffer, - size_t bytes, - size_t* bytes_written, - int* error) { - size_t available = buffer_length_ - seek_position_; - if (0 == available) { - // Increase buffer size to the larger of: - // a) new position rounded up to next 256 bytes - // b) double the previous length - size_t new_buffer_length = - std::max(((seek_position_ + bytes) | 0xFF) + 1, buffer_length_ * 2); - StreamResult result = DoReserve(new_buffer_length, error); - if (SR_SUCCESS != result) { - return result; - } - RTC_DCHECK(buffer_length_ >= new_buffer_length); - available = buffer_length_ - seek_position_; - } - - if (bytes > available) { - bytes = available; - } - memcpy(&buffer_[seek_position_], buffer, bytes); - seek_position_ += bytes; - if (data_length_ < seek_position_) { - data_length_ = seek_position_; - } - if (bytes_written) { - *bytes_written = bytes; - } - return SR_SUCCESS; -} - -void MemoryStreamBase::Close() { - // nothing to do -} - -bool MemoryStreamBase::SetPosition(size_t position) { - if (position > data_length_) - return false; - seek_position_ = position; - return true; -} - -bool MemoryStreamBase::GetPosition(size_t* position) const { - if (position) - *position = seek_position_; - return true; -} - -bool MemoryStreamBase::GetSize(size_t* size) const { - if (size) - *size = data_length_; - return true; -} - -bool MemoryStreamBase::ReserveSize(size_t size) { - return (SR_SUCCESS == DoReserve(size, nullptr)); -} - -StreamResult MemoryStreamBase::DoReserve(size_t size, int* error) { - return (buffer_length_ >= size) ? SR_SUCCESS : SR_EOS; -} - -/////////////////////////////////////////////////////////////////////////////// - -MemoryStream::MemoryStream() {} - -MemoryStream::MemoryStream(const char* data) { - SetData(data, strlen(data)); -} - -MemoryStream::MemoryStream(const void* data, size_t length) { - SetData(data, length); -} - -MemoryStream::~MemoryStream() { - delete[] buffer_; -} - -void MemoryStream::SetData(const void* data, size_t length) { - data_length_ = buffer_length_ = length; - delete[] buffer_; - buffer_ = new char[buffer_length_]; - memcpy(buffer_, data, data_length_); - seek_position_ = 0; -} - -StreamResult MemoryStream::DoReserve(size_t size, int* error) { - if (buffer_length_ >= size) - return SR_SUCCESS; - - if (char* new_buffer = new char[size]) { - memcpy(new_buffer, buffer_, data_length_); - delete[] buffer_; - buffer_ = new_buffer; - buffer_length_ = size; - return SR_SUCCESS; - } - - if (error) { - *error = ENOMEM; - } - return SR_ERROR; -} - /////////////////////////////////////////////////////////////////////////////// // FifoBuffer /////////////////////////////////////////////////////////////////////////////// diff --git a/rtc_base/stream.h b/rtc_base/stream.h index 2e72ce3a18..43e7f58bc7 100644 --- a/rtc_base/stream.h +++ b/rtc_base/stream.h @@ -261,63 +261,6 @@ class FileStream : public StreamInterface { RTC_DISALLOW_COPY_AND_ASSIGN(FileStream); }; -/////////////////////////////////////////////////////////////////////////////// -// MemoryStream is a simple implementation of a StreamInterface over in-memory -// data. Data is read and written at the current seek position. Reads return -// end-of-stream when they reach the end of data. Writes actually extend the -// end of data mark. -/////////////////////////////////////////////////////////////////////////////// - -class MemoryStreamBase : public StreamInterface { - public: - StreamState GetState() const override; - StreamResult Read(void* buffer, - size_t bytes, - size_t* bytes_read, - int* error) override; - StreamResult Write(const void* buffer, - size_t bytes, - size_t* bytes_written, - int* error) override; - void Close() override; - bool SetPosition(size_t position) override; - bool GetPosition(size_t* position) const override; - bool GetSize(size_t* size) const override; - bool ReserveSize(size_t size) override; - - char* GetBuffer() { return buffer_; } - const char* GetBuffer() const { return buffer_; } - - protected: - MemoryStreamBase(); - - virtual StreamResult DoReserve(size_t size, int* error); - - // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_ - char* buffer_; - size_t buffer_length_; - size_t data_length_; - size_t seek_position_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(MemoryStreamBase); -}; - -// MemoryStream dynamically resizes to accomodate written data. - -class MemoryStream : public MemoryStreamBase { - public: - MemoryStream(); - explicit MemoryStream(const char* data); // Calls SetData(data, strlen(data)) - MemoryStream(const void* data, size_t length); // Calls SetData(data, length) - ~MemoryStream() override; - - void SetData(const void* data, size_t length); - - protected: - StreamResult DoReserve(size_t size, int* error) override; -}; - // FifoBuffer allows for efficient, thread-safe buffering of data between // writer and reader. As the data can wrap around the end of the buffer, // MemoryStreamBase can't help us here.