blob: f859815c705c4094ee44323c782b0f8fbf84b977 [file] [log] [blame]
Niels Möller13339482019-03-28 13:30:15 +01001/*
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
18namespace rtc {
19
20// FifoBuffer allows for efficient, thread-safe buffering of data between
21// writer and reader.
22class 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.
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_