• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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