1 /* 2 * Copyright 2019 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef RTC_BASE_MEMORY_FIFO_BUFFER_H_ 12 #define RTC_BASE_MEMORY_FIFO_BUFFER_H_ 13 14 #include <memory> 15 16 #include "rtc_base/stream.h" 17 18 namespace rtc { 19 20 // FifoBuffer allows for efficient, thread-safe buffering of data between 21 // writer and reader. 22 class FifoBuffer final : public StreamInterface { 23 public: 24 // Creates a FIFO buffer with the specified capacity. 25 explicit FifoBuffer(size_t length); 26 // Creates a FIFO buffer with the specified capacity and owner 27 FifoBuffer(size_t length, Thread* owner); 28 ~FifoBuffer() override; 29 // Gets the amount of data currently readable from the buffer. 30 bool GetBuffered(size_t* data_len) const; 31 // Resizes the buffer to the specified capacity. Fails if data_length_ > size 32 bool SetCapacity(size_t length); 33 34 // Read into |buffer| with an offset from the current read position, offset 35 // is specified in number of bytes. 36 // This method doesn't adjust read position nor the number of available 37 // bytes, user has to call ConsumeReadData() to do this. 38 StreamResult ReadOffset(void* buffer, 39 size_t bytes, 40 size_t offset, 41 size_t* bytes_read); 42 43 // Write |buffer| with an offset from the current write position, offset is 44 // specified in number of bytes. 45 // This method doesn't adjust the number of buffered bytes, user has to call 46 // ConsumeWriteBuffer() to do this. 47 StreamResult WriteOffset(const void* buffer, 48 size_t bytes, 49 size_t offset, 50 size_t* bytes_written); 51 52 // StreamInterface methods 53 StreamState GetState() const override; 54 StreamResult Read(void* buffer, 55 size_t bytes, 56 size_t* bytes_read, 57 int* error) override; 58 StreamResult Write(const void* buffer, 59 size_t bytes, 60 size_t* bytes_written, 61 int* error) override; 62 void Close() override; 63 64 // Seek to a byte offset from the beginning of the stream. Returns false if 65 // the stream does not support seeking, or cannot seek to the specified 66 // position. 67 bool SetPosition(size_t position); 68 69 // Get the byte offset of the current position from the start of the stream. 70 // Returns false if the position is not known. 71 bool GetPosition(size_t* position) const; 72 73 // Seek to the start of the stream. Rewind()74 bool Rewind() { return SetPosition(0); } 75 76 // GetReadData returns a pointer to a buffer which is owned by the stream. 77 // The buffer contains data_len bytes. null is returned if no data is 78 // available, or if the method fails. If the caller processes the data, it 79 // must call ConsumeReadData with the number of processed bytes. GetReadData 80 // does not require a matching call to ConsumeReadData if the data is not 81 // processed. Read and ConsumeReadData invalidate the buffer returned by 82 // GetReadData. 83 const void* GetReadData(size_t* data_len); 84 void ConsumeReadData(size_t used); 85 // GetWriteBuffer returns a pointer to a buffer which is owned by the stream. 86 // The buffer has a capacity of buf_len bytes. null is returned if there is 87 // no buffer available, or if the method fails. The call may write data to 88 // the buffer, and then call ConsumeWriteBuffer with the number of bytes 89 // written. GetWriteBuffer does not require a matching call to 90 // ConsumeWriteData if no data is written. Write and 91 // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer. 92 void* GetWriteBuffer(size_t* buf_len); 93 void ConsumeWriteBuffer(size_t used); 94 95 // Return the number of Write()-able bytes remaining before end-of-stream. 96 // Returns false if not known. 97 bool GetWriteRemaining(size_t* size) const; 98 99 private: 100 // Helper method that implements ReadOffset. Caller must acquire a lock 101 // when calling this method. 102 StreamResult ReadOffsetLocked(void* buffer, 103 size_t bytes, 104 size_t offset, 105 size_t* bytes_read) 106 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); 107 108 // Helper method that implements WriteOffset. Caller must acquire a lock 109 // when calling this method. 110 StreamResult WriteOffsetLocked(const void* buffer, 111 size_t bytes, 112 size_t offset, 113 size_t* bytes_written) 114 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); 115 116 // keeps the opened/closed state of the stream 117 StreamState state_ RTC_GUARDED_BY(crit_); 118 // the allocated buffer 119 std::unique_ptr<char[]> buffer_ RTC_GUARDED_BY(crit_); 120 // size of the allocated buffer 121 size_t buffer_length_ RTC_GUARDED_BY(crit_); 122 // amount of readable data in the buffer 123 size_t data_length_ RTC_GUARDED_BY(crit_); 124 // offset to the readable data 125 size_t read_position_ RTC_GUARDED_BY(crit_); 126 // stream callbacks are dispatched on this thread 127 Thread* owner_; 128 // object lock 129 CriticalSection crit_; 130 RTC_DISALLOW_COPY_AND_ASSIGN(FifoBuffer); 131 }; 132 133 } // namespace rtc 134 135 #endif // RTC_BASE_MEMORY_FIFO_BUFFER_H_ 136