| // 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. | |
| #ifndef SRC_DEVELOPER_DEBUG_SHARED_STREAM_BUFFER_H_ | |
| #define SRC_DEVELOPER_DEBUG_SHARED_STREAM_BUFFER_H_ | |
| #include <deque> | |
| #include <vector> | |
| namespace debug { | |
| // This class is a buffer that sits between an asynchronous OS read/write source and producers and | |
| // consumer of stream data. | |
| // | |
| // It is used by the BufferedStream and its implementations to do the actual buffering. | |
| 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 | |
| #endif // SRC_DEVELOPER_DEBUG_SHARED_STREAM_BUFFER_H_ |