| Index: webrtc/base/stream.cc
|
| diff --git a/webrtc/base/stream.cc b/webrtc/base/stream.cc
|
| deleted file mode 100644
|
| index 67ef104044e3158ebe7cf37bc88b29e296ab36c7..0000000000000000000000000000000000000000
|
| --- a/webrtc/base/stream.cc
|
| +++ /dev/null
|
| @@ -1,1123 +0,0 @@
|
| -/*
|
| - * Copyright 2004 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.
|
| - */
|
| -
|
| -#if defined(WEBRTC_POSIX)
|
| -#include <sys/file.h>
|
| -#endif // WEBRTC_POSIX
|
| -#include <sys/types.h>
|
| -#include <sys/stat.h>
|
| -#include <errno.h>
|
| -
|
| -#include <algorithm>
|
| -#include <string>
|
| -
|
| -#include "webrtc/base/basictypes.h"
|
| -#include "webrtc/base/checks.h"
|
| -#include "webrtc/base/logging.h"
|
| -#include "webrtc/base/messagequeue.h"
|
| -#include "webrtc/base/stream.h"
|
| -#include "webrtc/base/stringencode.h"
|
| -#include "webrtc/base/stringutils.h"
|
| -#include "webrtc/base/thread.h"
|
| -#include "webrtc/base/timeutils.h"
|
| -
|
| -#if defined(WEBRTC_WIN)
|
| -#include "webrtc/base/win32.h"
|
| -#define fileno _fileno
|
| -#endif
|
| -
|
| -namespace rtc {
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// StreamInterface
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -StreamInterface::~StreamInterface() {
|
| -}
|
| -
|
| -StreamResult StreamInterface::WriteAll(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - StreamResult result = SR_SUCCESS;
|
| - size_t total_written = 0, current_written;
|
| - while (total_written < data_len) {
|
| - result = Write(static_cast<const char*>(data) + total_written,
|
| - data_len - total_written, ¤t_written, error);
|
| - if (result != SR_SUCCESS)
|
| - break;
|
| - total_written += current_written;
|
| - }
|
| - if (written)
|
| - *written = total_written;
|
| - return result;
|
| -}
|
| -
|
| -StreamResult StreamInterface::ReadAll(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - StreamResult result = SR_SUCCESS;
|
| - size_t total_read = 0, current_read;
|
| - while (total_read < buffer_len) {
|
| - result = Read(static_cast<char*>(buffer) + total_read,
|
| - buffer_len - total_read, ¤t_read, error);
|
| - if (result != SR_SUCCESS)
|
| - break;
|
| - total_read += current_read;
|
| - }
|
| - if (read)
|
| - *read = total_read;
|
| - return result;
|
| -}
|
| -
|
| -StreamResult StreamInterface::ReadLine(std::string* line) {
|
| - line->clear();
|
| - StreamResult result = SR_SUCCESS;
|
| - while (true) {
|
| - char ch;
|
| - result = Read(&ch, sizeof(ch), nullptr, nullptr);
|
| - if (result != SR_SUCCESS) {
|
| - break;
|
| - }
|
| - if (ch == '\n') {
|
| - break;
|
| - }
|
| - line->push_back(ch);
|
| - }
|
| - if (!line->empty()) { // give back the line we've collected so far with
|
| - result = SR_SUCCESS; // a success code. Otherwise return the last code
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -void StreamInterface::PostEvent(Thread* t, int events, int err) {
|
| - t->Post(RTC_FROM_HERE, this, MSG_POST_EVENT,
|
| - new StreamEventData(events, err));
|
| -}
|
| -
|
| -void StreamInterface::PostEvent(int events, int err) {
|
| - PostEvent(Thread::Current(), events, err);
|
| -}
|
| -
|
| -const void* StreamInterface::GetReadData(size_t* data_len) {
|
| - return nullptr;
|
| -}
|
| -
|
| -void* StreamInterface::GetWriteBuffer(size_t* buf_len) {
|
| - return nullptr;
|
| -}
|
| -
|
| -bool StreamInterface::SetPosition(size_t position) {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::GetPosition(size_t* position) const {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::GetSize(size_t* size) const {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::GetAvailable(size_t* size) const {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::GetWriteRemaining(size_t* size) const {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::Flush() {
|
| - return false;
|
| -}
|
| -
|
| -bool StreamInterface::ReserveSize(size_t size) {
|
| - return true;
|
| -}
|
| -
|
| -StreamInterface::StreamInterface() {
|
| -}
|
| -
|
| -void StreamInterface::OnMessage(Message* msg) {
|
| - if (MSG_POST_EVENT == msg->message_id) {
|
| - StreamEventData* pe = static_cast<StreamEventData*>(msg->pdata);
|
| - SignalEvent(this, pe->events, pe->error);
|
| - delete msg->pdata;
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// StreamAdapterInterface
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -StreamAdapterInterface::StreamAdapterInterface(StreamInterface* stream,
|
| - bool owned)
|
| - : stream_(stream), owned_(owned) {
|
| - if (nullptr != stream_)
|
| - stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
|
| -}
|
| -
|
| -StreamState StreamAdapterInterface::GetState() const {
|
| - return stream_->GetState();
|
| -}
|
| -StreamResult StreamAdapterInterface::Read(void* buffer,
|
| - size_t buffer_len,
|
| - size_t* read,
|
| - int* error) {
|
| - return stream_->Read(buffer, buffer_len, read, error);
|
| -}
|
| -StreamResult StreamAdapterInterface::Write(const void* data,
|
| - size_t data_len,
|
| - size_t* written,
|
| - int* error) {
|
| - return stream_->Write(data, data_len, written, error);
|
| -}
|
| -void StreamAdapterInterface::Close() {
|
| - stream_->Close();
|
| -}
|
| -
|
| -bool StreamAdapterInterface::SetPosition(size_t position) {
|
| - return stream_->SetPosition(position);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::GetPosition(size_t* position) const {
|
| - return stream_->GetPosition(position);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::GetSize(size_t* size) const {
|
| - return stream_->GetSize(size);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::GetAvailable(size_t* size) const {
|
| - return stream_->GetAvailable(size);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::GetWriteRemaining(size_t* size) const {
|
| - return stream_->GetWriteRemaining(size);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::ReserveSize(size_t size) {
|
| - return stream_->ReserveSize(size);
|
| -}
|
| -
|
| -bool StreamAdapterInterface::Flush() {
|
| - return stream_->Flush();
|
| -}
|
| -
|
| -void StreamAdapterInterface::Attach(StreamInterface* stream, bool owned) {
|
| - if (nullptr != stream_)
|
| - stream_->SignalEvent.disconnect(this);
|
| - if (owned_)
|
| - delete stream_;
|
| - stream_ = stream;
|
| - owned_ = owned;
|
| - if (nullptr != stream_)
|
| - stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
|
| -}
|
| -
|
| -StreamInterface* StreamAdapterInterface::Detach() {
|
| - if (nullptr != stream_)
|
| - stream_->SignalEvent.disconnect(this);
|
| - StreamInterface* stream = stream_;
|
| - stream_ = nullptr;
|
| - return stream;
|
| -}
|
| -
|
| -StreamAdapterInterface::~StreamAdapterInterface() {
|
| - if (owned_)
|
| - delete stream_;
|
| -}
|
| -
|
| -void StreamAdapterInterface::OnEvent(StreamInterface* stream,
|
| - int events,
|
| - int err) {
|
| - SignalEvent(this, events, err);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// StreamTap
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -StreamTap::StreamTap(StreamInterface* stream, StreamInterface* tap)
|
| - : StreamAdapterInterface(stream), tap_(), tap_result_(SR_SUCCESS),
|
| - tap_error_(0) {
|
| - AttachTap(tap);
|
| -}
|
| -
|
| -StreamTap::~StreamTap() = default;
|
| -
|
| -void StreamTap::AttachTap(StreamInterface* tap) {
|
| - tap_.reset(tap);
|
| -}
|
| -
|
| -StreamInterface* StreamTap::DetachTap() {
|
| - return tap_.release();
|
| -}
|
| -
|
| -StreamResult StreamTap::GetTapResult(int* error) {
|
| - if (error) {
|
| - *error = tap_error_;
|
| - }
|
| - return tap_result_;
|
| -}
|
| -
|
| -StreamResult StreamTap::Read(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - size_t backup_read;
|
| - if (!read) {
|
| - read = &backup_read;
|
| - }
|
| - StreamResult res = StreamAdapterInterface::Read(buffer, buffer_len,
|
| - read, error);
|
| - if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
|
| - tap_result_ = tap_->WriteAll(buffer, *read, nullptr, &tap_error_);
|
| - }
|
| - return res;
|
| -}
|
| -
|
| -StreamResult StreamTap::Write(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - size_t backup_written;
|
| - if (!written) {
|
| - written = &backup_written;
|
| - }
|
| - StreamResult res = StreamAdapterInterface::Write(data, data_len,
|
| - written, error);
|
| - if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
|
| - tap_result_ = tap_->WriteAll(data, *written, nullptr, &tap_error_);
|
| - }
|
| - return res;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// NullStream
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -NullStream::NullStream() {
|
| -}
|
| -
|
| -NullStream::~NullStream() {
|
| -}
|
| -
|
| -StreamState NullStream::GetState() const {
|
| - return SS_OPEN;
|
| -}
|
| -
|
| -StreamResult NullStream::Read(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - if (error) *error = -1;
|
| - return SR_ERROR;
|
| -}
|
| -
|
| -StreamResult NullStream::Write(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - if (written) *written = data_len;
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -void NullStream::Close() {
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// FileStream
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -FileStream::FileStream() : file_(nullptr) {}
|
| -
|
| -FileStream::~FileStream() {
|
| - FileStream::Close();
|
| -}
|
| -
|
| -bool FileStream::Open(const std::string& filename, const char* mode,
|
| - int* error) {
|
| - Close();
|
| -#if defined(WEBRTC_WIN)
|
| - std::wstring wfilename;
|
| - if (Utf8ToWindowsFilename(filename, &wfilename)) {
|
| - file_ = _wfopen(wfilename.c_str(), ToUtf16(mode).c_str());
|
| - } else {
|
| - if (error) {
|
| - *error = -1;
|
| - return false;
|
| - }
|
| - }
|
| -#else
|
| - file_ = fopen(filename.c_str(), mode);
|
| -#endif
|
| - if (!file_ && error) {
|
| - *error = errno;
|
| - }
|
| - return (file_ != nullptr);
|
| -}
|
| -
|
| -bool FileStream::OpenShare(const std::string& filename, const char* mode,
|
| - int shflag, int* error) {
|
| - Close();
|
| -#if defined(WEBRTC_WIN)
|
| - std::wstring wfilename;
|
| - if (Utf8ToWindowsFilename(filename, &wfilename)) {
|
| - file_ = _wfsopen(wfilename.c_str(), ToUtf16(mode).c_str(), shflag);
|
| - if (!file_ && error) {
|
| - *error = errno;
|
| - return false;
|
| - }
|
| - return file_ != nullptr;
|
| - } else {
|
| - if (error) {
|
| - *error = -1;
|
| - }
|
| - return false;
|
| - }
|
| -#else
|
| - return Open(filename, mode, error);
|
| -#endif
|
| -}
|
| -
|
| -bool FileStream::DisableBuffering() {
|
| - if (!file_)
|
| - return false;
|
| - return (setvbuf(file_, nullptr, _IONBF, 0) == 0);
|
| -}
|
| -
|
| -StreamState FileStream::GetState() const {
|
| - return (file_ == nullptr) ? SS_CLOSED : SS_OPEN;
|
| -}
|
| -
|
| -StreamResult FileStream::Read(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - if (!file_)
|
| - return SR_EOS;
|
| - size_t result = fread(buffer, 1, buffer_len, file_);
|
| - if ((result == 0) && (buffer_len > 0)) {
|
| - if (feof(file_))
|
| - return SR_EOS;
|
| - if (error)
|
| - *error = errno;
|
| - return SR_ERROR;
|
| - }
|
| - if (read)
|
| - *read = result;
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -StreamResult FileStream::Write(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - if (!file_)
|
| - return SR_EOS;
|
| - size_t result = fwrite(data, 1, data_len, file_);
|
| - if ((result == 0) && (data_len > 0)) {
|
| - if (error)
|
| - *error = errno;
|
| - return SR_ERROR;
|
| - }
|
| - if (written)
|
| - *written = result;
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -void FileStream::Close() {
|
| - if (file_) {
|
| - DoClose();
|
| - file_ = nullptr;
|
| - }
|
| -}
|
| -
|
| -bool FileStream::SetPosition(size_t position) {
|
| - if (!file_)
|
| - return false;
|
| - return (fseek(file_, static_cast<int>(position), SEEK_SET) == 0);
|
| -}
|
| -
|
| -bool FileStream::GetPosition(size_t* position) const {
|
| - RTC_DCHECK(nullptr != position);
|
| - if (!file_)
|
| - return false;
|
| - long result = ftell(file_);
|
| - if (result < 0)
|
| - return false;
|
| - if (position)
|
| - *position = result;
|
| - return true;
|
| -}
|
| -
|
| -bool FileStream::GetSize(size_t* size) const {
|
| - RTC_DCHECK(nullptr != size);
|
| - if (!file_)
|
| - return false;
|
| - struct stat file_stats;
|
| - if (fstat(fileno(file_), &file_stats) != 0)
|
| - return false;
|
| - if (size)
|
| - *size = file_stats.st_size;
|
| - return true;
|
| -}
|
| -
|
| -bool FileStream::GetAvailable(size_t* size) const {
|
| - RTC_DCHECK(nullptr != size);
|
| - if (!GetSize(size))
|
| - return false;
|
| - long result = ftell(file_);
|
| - if (result < 0)
|
| - return false;
|
| - if (size)
|
| - *size -= result;
|
| - return true;
|
| -}
|
| -
|
| -bool FileStream::ReserveSize(size_t size) {
|
| - // TODO: extend the file to the proper length
|
| - return true;
|
| -}
|
| -
|
| -bool FileStream::GetSize(const std::string& filename, size_t* size) {
|
| - struct stat file_stats;
|
| - if (stat(filename.c_str(), &file_stats) != 0)
|
| - return false;
|
| - *size = file_stats.st_size;
|
| - return true;
|
| -}
|
| -
|
| -bool FileStream::Flush() {
|
| - if (file_) {
|
| - return (0 == fflush(file_));
|
| - }
|
| - // try to flush empty file?
|
| - RTC_NOTREACHED();
|
| - return false;
|
| -}
|
| -
|
| -#if defined(WEBRTC_POSIX) && !defined(__native_client__)
|
| -
|
| -bool FileStream::TryLock() {
|
| - if (file_ == nullptr) {
|
| - // Stream not open.
|
| - RTC_NOTREACHED();
|
| - return false;
|
| - }
|
| -
|
| - return flock(fileno(file_), LOCK_EX|LOCK_NB) == 0;
|
| -}
|
| -
|
| -bool FileStream::Unlock() {
|
| - if (file_ == nullptr) {
|
| - // Stream not open.
|
| - RTC_NOTREACHED();
|
| - return false;
|
| - }
|
| -
|
| - return flock(fileno(file_), LOCK_UN) == 0;
|
| -}
|
| -
|
| -#endif
|
| -
|
| -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::GetAvailable(size_t* size) const {
|
| - if (size)
|
| - *size = data_length_ - seek_position_;
|
| - 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() : buffer_alloc_(nullptr) {}
|
| -
|
| -MemoryStream::MemoryStream(const char* data) : buffer_alloc_(nullptr) {
|
| - SetData(data, strlen(data));
|
| -}
|
| -
|
| -MemoryStream::MemoryStream(const void* data, size_t length)
|
| - : buffer_alloc_(nullptr) {
|
| - SetData(data, length);
|
| -}
|
| -
|
| -MemoryStream::~MemoryStream() {
|
| - delete [] buffer_alloc_;
|
| -}
|
| -
|
| -void MemoryStream::SetData(const void* data, size_t length) {
|
| - data_length_ = buffer_length_ = length;
|
| - delete [] buffer_alloc_;
|
| - buffer_alloc_ = new char[buffer_length_ + kAlignment];
|
| - buffer_ = reinterpret_cast<char*>(ALIGNP(buffer_alloc_, kAlignment));
|
| - 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_alloc = new char[size + kAlignment]) {
|
| - char* new_buffer = reinterpret_cast<char*>(
|
| - ALIGNP(new_buffer_alloc, kAlignment));
|
| - memcpy(new_buffer, buffer_, data_length_);
|
| - delete [] buffer_alloc_;
|
| - buffer_alloc_ = new_buffer_alloc;
|
| - buffer_ = new_buffer;
|
| - buffer_length_ = size;
|
| - return SR_SUCCESS;
|
| - }
|
| -
|
| - if (error) {
|
| - *error = ENOMEM;
|
| - }
|
| - return SR_ERROR;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -ExternalMemoryStream::ExternalMemoryStream() {
|
| -}
|
| -
|
| -ExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) {
|
| - SetData(data, length);
|
| -}
|
| -
|
| -ExternalMemoryStream::~ExternalMemoryStream() {
|
| -}
|
| -
|
| -void ExternalMemoryStream::SetData(void* data, size_t length) {
|
| - data_length_ = buffer_length_ = length;
|
| - buffer_ = static_cast<char*>(data);
|
| - seek_position_ = 0;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// FifoBuffer
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -FifoBuffer::FifoBuffer(size_t size)
|
| - : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size),
|
| - data_length_(0), read_position_(0), owner_(Thread::Current()) {
|
| - // all events are done on the owner_ thread
|
| -}
|
| -
|
| -FifoBuffer::FifoBuffer(size_t size, Thread* owner)
|
| - : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size),
|
| - data_length_(0), read_position_(0), owner_(owner) {
|
| - // all events are done on the owner_ thread
|
| -}
|
| -
|
| -FifoBuffer::~FifoBuffer() {
|
| -}
|
| -
|
| -bool FifoBuffer::GetBuffered(size_t* size) const {
|
| - CritScope cs(&crit_);
|
| - *size = data_length_;
|
| - return true;
|
| -}
|
| -
|
| -bool FifoBuffer::SetCapacity(size_t size) {
|
| - CritScope cs(&crit_);
|
| - if (data_length_ > size) {
|
| - return false;
|
| - }
|
| -
|
| - if (size != buffer_length_) {
|
| - char* buffer = new char[size];
|
| - const size_t copy = data_length_;
|
| - const size_t tail_copy = std::min(copy, buffer_length_ - read_position_);
|
| - memcpy(buffer, &buffer_[read_position_], tail_copy);
|
| - memcpy(buffer + tail_copy, &buffer_[0], copy - tail_copy);
|
| - buffer_.reset(buffer);
|
| - read_position_ = 0;
|
| - buffer_length_ = size;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -StreamResult FifoBuffer::ReadOffset(void* buffer, size_t bytes,
|
| - size_t offset, size_t* bytes_read) {
|
| - CritScope cs(&crit_);
|
| - return ReadOffsetLocked(buffer, bytes, offset, bytes_read);
|
| -}
|
| -
|
| -StreamResult FifoBuffer::WriteOffset(const void* buffer, size_t bytes,
|
| - size_t offset, size_t* bytes_written) {
|
| - CritScope cs(&crit_);
|
| - return WriteOffsetLocked(buffer, bytes, offset, bytes_written);
|
| -}
|
| -
|
| -StreamState FifoBuffer::GetState() const {
|
| - CritScope cs(&crit_);
|
| - return state_;
|
| -}
|
| -
|
| -StreamResult FifoBuffer::Read(void* buffer, size_t bytes,
|
| - size_t* bytes_read, int* error) {
|
| - CritScope cs(&crit_);
|
| - const bool was_writable = data_length_ < buffer_length_;
|
| - size_t copy = 0;
|
| - StreamResult result = ReadOffsetLocked(buffer, bytes, 0, ©);
|
| -
|
| - if (result == SR_SUCCESS) {
|
| - // If read was successful then adjust the read position and number of
|
| - // bytes buffered.
|
| - read_position_ = (read_position_ + copy) % buffer_length_;
|
| - data_length_ -= copy;
|
| - if (bytes_read) {
|
| - *bytes_read = copy;
|
| - }
|
| -
|
| - // if we were full before, and now we're not, post an event
|
| - if (!was_writable && copy > 0) {
|
| - PostEvent(owner_, SE_WRITE, 0);
|
| - }
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -StreamResult FifoBuffer::Write(const void* buffer, size_t bytes,
|
| - size_t* bytes_written, int* error) {
|
| - CritScope cs(&crit_);
|
| -
|
| - const bool was_readable = (data_length_ > 0);
|
| - size_t copy = 0;
|
| - StreamResult result = WriteOffsetLocked(buffer, bytes, 0, ©);
|
| -
|
| - if (result == SR_SUCCESS) {
|
| - // If write was successful then adjust the number of readable bytes.
|
| - data_length_ += copy;
|
| - if (bytes_written) {
|
| - *bytes_written = copy;
|
| - }
|
| -
|
| - // if we didn't have any data to read before, and now we do, post an event
|
| - if (!was_readable && copy > 0) {
|
| - PostEvent(owner_, SE_READ, 0);
|
| - }
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -void FifoBuffer::Close() {
|
| - CritScope cs(&crit_);
|
| - state_ = SS_CLOSED;
|
| -}
|
| -
|
| -const void* FifoBuffer::GetReadData(size_t* size) {
|
| - CritScope cs(&crit_);
|
| - *size = (read_position_ + data_length_ <= buffer_length_) ?
|
| - data_length_ : buffer_length_ - read_position_;
|
| - return &buffer_[read_position_];
|
| -}
|
| -
|
| -void FifoBuffer::ConsumeReadData(size_t size) {
|
| - CritScope cs(&crit_);
|
| - RTC_DCHECK(size <= data_length_);
|
| - const bool was_writable = data_length_ < buffer_length_;
|
| - read_position_ = (read_position_ + size) % buffer_length_;
|
| - data_length_ -= size;
|
| - if (!was_writable && size > 0) {
|
| - PostEvent(owner_, SE_WRITE, 0);
|
| - }
|
| -}
|
| -
|
| -void* FifoBuffer::GetWriteBuffer(size_t* size) {
|
| - CritScope cs(&crit_);
|
| - if (state_ == SS_CLOSED) {
|
| - return nullptr;
|
| - }
|
| -
|
| - // if empty, reset the write position to the beginning, so we can get
|
| - // the biggest possible block
|
| - if (data_length_ == 0) {
|
| - read_position_ = 0;
|
| - }
|
| -
|
| - const size_t write_position = (read_position_ + data_length_)
|
| - % buffer_length_;
|
| - *size = (write_position > read_position_ || data_length_ == 0) ?
|
| - buffer_length_ - write_position : read_position_ - write_position;
|
| - return &buffer_[write_position];
|
| -}
|
| -
|
| -void FifoBuffer::ConsumeWriteBuffer(size_t size) {
|
| - CritScope cs(&crit_);
|
| - RTC_DCHECK(size <= buffer_length_ - data_length_);
|
| - const bool was_readable = (data_length_ > 0);
|
| - data_length_ += size;
|
| - if (!was_readable && size > 0) {
|
| - PostEvent(owner_, SE_READ, 0);
|
| - }
|
| -}
|
| -
|
| -bool FifoBuffer::GetWriteRemaining(size_t* size) const {
|
| - CritScope cs(&crit_);
|
| - *size = buffer_length_ - data_length_;
|
| - return true;
|
| -}
|
| -
|
| -StreamResult FifoBuffer::ReadOffsetLocked(void* buffer,
|
| - size_t bytes,
|
| - size_t offset,
|
| - size_t* bytes_read) {
|
| - if (offset >= data_length_) {
|
| - return (state_ != SS_CLOSED) ? SR_BLOCK : SR_EOS;
|
| - }
|
| -
|
| - const size_t available = data_length_ - offset;
|
| - const size_t read_position = (read_position_ + offset) % buffer_length_;
|
| - const size_t copy = std::min(bytes, available);
|
| - const size_t tail_copy = std::min(copy, buffer_length_ - read_position);
|
| - char* const p = static_cast<char*>(buffer);
|
| - memcpy(p, &buffer_[read_position], tail_copy);
|
| - memcpy(p + tail_copy, &buffer_[0], copy - tail_copy);
|
| -
|
| - if (bytes_read) {
|
| - *bytes_read = copy;
|
| - }
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -StreamResult FifoBuffer::WriteOffsetLocked(const void* buffer,
|
| - size_t bytes,
|
| - size_t offset,
|
| - size_t* bytes_written) {
|
| - if (state_ == SS_CLOSED) {
|
| - return SR_EOS;
|
| - }
|
| -
|
| - if (data_length_ + offset >= buffer_length_) {
|
| - return SR_BLOCK;
|
| - }
|
| -
|
| - const size_t available = buffer_length_ - data_length_ - offset;
|
| - const size_t write_position = (read_position_ + data_length_ + offset)
|
| - % buffer_length_;
|
| - const size_t copy = std::min(bytes, available);
|
| - const size_t tail_copy = std::min(copy, buffer_length_ - write_position);
|
| - const char* const p = static_cast<const char*>(buffer);
|
| - memcpy(&buffer_[write_position], p, tail_copy);
|
| - memcpy(&buffer_[0], p + tail_copy, copy - tail_copy);
|
| -
|
| - if (bytes_written) {
|
| - *bytes_written = copy;
|
| - }
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// LoggingAdapter
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -LoggingAdapter::LoggingAdapter(StreamInterface* stream, LoggingSeverity level,
|
| - const std::string& label, bool hex_mode)
|
| - : StreamAdapterInterface(stream), level_(level), hex_mode_(hex_mode) {
|
| - set_label(label);
|
| -}
|
| -
|
| -void LoggingAdapter::set_label(const std::string& label) {
|
| - label_.assign("[");
|
| - label_.append(label);
|
| - label_.append("]");
|
| -}
|
| -
|
| -StreamResult LoggingAdapter::Read(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - size_t local_read; if (!read) read = &local_read;
|
| - StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len, read,
|
| - error);
|
| - if (result == SR_SUCCESS) {
|
| - LogMultiline(level_, label_.c_str(), true, buffer, *read, hex_mode_, &lms_);
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -StreamResult LoggingAdapter::Write(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - size_t local_written;
|
| - if (!written) written = &local_written;
|
| - StreamResult result = StreamAdapterInterface::Write(data, data_len, written,
|
| - error);
|
| - if (result == SR_SUCCESS) {
|
| - LogMultiline(level_, label_.c_str(), false, data, *written, hex_mode_,
|
| - &lms_);
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -void LoggingAdapter::Close() {
|
| - LogMultiline(level_, label_.c_str(), false, nullptr, 0, hex_mode_, &lms_);
|
| - LogMultiline(level_, label_.c_str(), true, nullptr, 0, hex_mode_, &lms_);
|
| - LOG_V(level_) << label_ << " Closed locally";
|
| - StreamAdapterInterface::Close();
|
| -}
|
| -
|
| -void LoggingAdapter::OnEvent(StreamInterface* stream, int events, int err) {
|
| - if (events & SE_OPEN) {
|
| - LOG_V(level_) << label_ << " Open";
|
| - } else if (events & SE_CLOSE) {
|
| - LogMultiline(level_, label_.c_str(), false, nullptr, 0, hex_mode_, &lms_);
|
| - LogMultiline(level_, label_.c_str(), true, nullptr, 0, hex_mode_, &lms_);
|
| - LOG_V(level_) << label_ << " Closed with error: " << err;
|
| - }
|
| - StreamAdapterInterface::OnEvent(stream, events, err);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// StringStream - Reads/Writes to an external std::string
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -StringStream::StringStream(std::string* str)
|
| - : str_(*str), read_pos_(0), read_only_(false) {
|
| -}
|
| -
|
| -StringStream::StringStream(const std::string& str)
|
| - : str_(const_cast<std::string&>(str)), read_pos_(0), read_only_(true) {
|
| -}
|
| -
|
| -StreamState StringStream::GetState() const {
|
| - return SS_OPEN;
|
| -}
|
| -
|
| -StreamResult StringStream::Read(void* buffer, size_t buffer_len,
|
| - size_t* read, int* error) {
|
| - size_t available = std::min(buffer_len, str_.size() - read_pos_);
|
| - if (!available)
|
| - return SR_EOS;
|
| - memcpy(buffer, str_.data() + read_pos_, available);
|
| - read_pos_ += available;
|
| - if (read)
|
| - *read = available;
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -StreamResult StringStream::Write(const void* data, size_t data_len,
|
| - size_t* written, int* error) {
|
| - if (read_only_) {
|
| - if (error) {
|
| - *error = -1;
|
| - }
|
| - return SR_ERROR;
|
| - }
|
| - str_.append(static_cast<const char*>(data),
|
| - static_cast<const char*>(data) + data_len);
|
| - if (written)
|
| - *written = data_len;
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -void StringStream::Close() {
|
| -}
|
| -
|
| -bool StringStream::SetPosition(size_t position) {
|
| - if (position > str_.size())
|
| - return false;
|
| - read_pos_ = position;
|
| - return true;
|
| -}
|
| -
|
| -bool StringStream::GetPosition(size_t* position) const {
|
| - if (position)
|
| - *position = read_pos_;
|
| - return true;
|
| -}
|
| -
|
| -bool StringStream::GetSize(size_t* size) const {
|
| - if (size)
|
| - *size = str_.size();
|
| - return true;
|
| -}
|
| -
|
| -bool StringStream::GetAvailable(size_t* size) const {
|
| - if (size)
|
| - *size = str_.size() - read_pos_;
|
| - return true;
|
| -}
|
| -
|
| -bool StringStream::ReserveSize(size_t size) {
|
| - if (read_only_)
|
| - return false;
|
| - str_.reserve(size);
|
| - return true;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -// StreamReference
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -StreamReference::StreamReference(StreamInterface* stream)
|
| - : StreamAdapterInterface(stream, false) {
|
| - // owner set to false so the destructor does not free the stream.
|
| - stream_ref_count_ = new StreamRefCount(stream);
|
| -}
|
| -
|
| -StreamInterface* StreamReference::NewReference() {
|
| - stream_ref_count_->AddReference();
|
| - return new StreamReference(stream_ref_count_, stream());
|
| -}
|
| -
|
| -StreamReference::~StreamReference() {
|
| - stream_ref_count_->Release();
|
| -}
|
| -
|
| -StreamReference::StreamReference(StreamRefCount* stream_ref_count,
|
| - StreamInterface* stream)
|
| - : StreamAdapterInterface(stream, false),
|
| - stream_ref_count_(stream_ref_count) {
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -StreamResult Flow(StreamInterface* source,
|
| - char* buffer,
|
| - size_t buffer_len,
|
| - StreamInterface* sink,
|
| - size_t* data_len /* = nullptr */) {
|
| - RTC_DCHECK(buffer_len > 0);
|
| -
|
| - StreamResult result;
|
| - size_t count, read_pos, write_pos;
|
| - if (data_len) {
|
| - read_pos = *data_len;
|
| - } else {
|
| - read_pos = 0;
|
| - }
|
| -
|
| - bool end_of_stream = false;
|
| - do {
|
| - // Read until buffer is full, end of stream, or error
|
| - while (!end_of_stream && (read_pos < buffer_len)) {
|
| - result = source->Read(buffer + read_pos, buffer_len - read_pos, &count,
|
| - nullptr);
|
| - if (result == SR_EOS) {
|
| - end_of_stream = true;
|
| - } else if (result != SR_SUCCESS) {
|
| - if (data_len) {
|
| - *data_len = read_pos;
|
| - }
|
| - return result;
|
| - } else {
|
| - read_pos += count;
|
| - }
|
| - }
|
| -
|
| - // Write until buffer is empty, or error (including end of stream)
|
| - write_pos = 0;
|
| - while (write_pos < read_pos) {
|
| - result = sink->Write(buffer + write_pos, read_pos - write_pos, &count,
|
| - nullptr);
|
| - if (result != SR_SUCCESS) {
|
| - if (data_len) {
|
| - *data_len = read_pos - write_pos;
|
| - if (write_pos > 0) {
|
| - memmove(buffer, buffer + write_pos, *data_len);
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| - write_pos += count;
|
| - }
|
| -
|
| - read_pos = 0;
|
| - } while (!end_of_stream);
|
| -
|
| - if (data_len) {
|
| - *data_len = 0;
|
| - }
|
| - return SR_SUCCESS;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -} // namespace rtc
|
|
|