blob: 7280b6a73b503a08d1acddc2feb48479aa097531 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <deque>
#include <vector>
namespace debug_ipc {
// This class is a buffer that sits between an asynchronous OS read/write
// source and producers and consumer of stream data.
class StreamBuffer {
public:
class Writer {
public:
// Consumes as much of the given data as possible, returning how many bytes
// were consumed. If less than "len" bytes are written, the system will
// notify the stream buffer when more data can be written via
// SetWriteable().
virtual size_t ConsumeStreamBufferData(const char* data, size_t len) = 0;
};
// You must call set_writer before using.
StreamBuffer();
~StreamBuffer();
// System API ----------------------------------------------------------------
// Sets the writer which flushes write data to the OS.
void set_writer(Writer* writer) { writer_ = writer; }
// Provides data from the OS source for reading.
void AddReadData(std::vector<char> data);
// Notification from the OS that data can be written.
void SetWritable();
// Public API ----------------------------------------------------------------
// Returns true if the given number of bytes are available for reading.
bool IsAvailable(size_t count) const;
// Copies up to |buffer_len| bytes to the given |buffer|. If there is not
// enough data available it will do a partial read (check IsAvailable() if
// you need to know in advance). Returns the number of bytes actually read.
size_t Read(char* buffer, size_t buffer_len);
// Like Read() but does not actually consume the data. The same data will be
// supplied for a subsequent Peek() or Read() call.
size_t Peek(char* buffer, size_t buffer_len) const;
// Writes the data to the OS sink.
void Write(std::vector<char> data);
private:
size_t ReadOrPeek(char* buffer, size_t buffer_len, bool erase_consumed);
void FlushWriteBuffer();
Writer* writer_ = nullptr;
// Read buffer in a sequence of ordered buffers. Read at the
// front, add data at the back.
std::deque<const std::vector<char>> read_buffer_;
size_t first_read_buffer_offset_ = 0; // Position of read_buffer_[0].
// Write buffer.
std::deque<const std::vector<char>> write_buffer_;
bool can_write_ = true;
size_t first_write_buffer_offset_ = 0; // Position of write_buffer_[0].
};
} // namespace debug_ipc