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