Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: webrtc/base/buffer.h

Issue 1717273002: Added functional variants of Buffer::SetData and Buffer::AppendData. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed missing include of <algorithm> in buffer.cc and bufferqueue.cc Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/base/buffer.cc » ('j') | webrtc/base/buffer_unittest.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #ifndef WEBRTC_BASE_BUFFER_H_ 11 #ifndef WEBRTC_BASE_BUFFER_H_
12 #define WEBRTC_BASE_BUFFER_H_ 12 #define WEBRTC_BASE_BUFFER_H_
13 13
14 #include <algorithm> // std::swap (pre-C++11)
15 #include <cassert> 14 #include <cassert>
16 #include <cstring> 15 #include <cstring>
17 #include <memory> 16 #include <memory>
18 #include <utility> // std::swap (C++11 and later) 17 #include <utility>
19 18
19 #include "webrtc/base/array_view.h"
20 #include "webrtc/base/checks.h"
20 #include "webrtc/base/constructormagic.h" 21 #include "webrtc/base/constructormagic.h"
21 #include "webrtc/base/deprecation.h" 22 #include "webrtc/base/deprecation.h"
22 23
23 namespace rtc { 24 namespace rtc {
24 25
25 namespace internal { 26 namespace internal {
26 27
27 // (Internal; please don't use outside this file.) ByteType<T>::t is int if T 28 // (Internal; please don't use outside this file.) ByteType<T>::t is int if T
28 // is uint8_t, int8_t, or char; otherwise, it's a compilation error. Use like 29 // is uint8_t, int8_t, or char; otherwise, it's a compilation error. Use like
29 // this: 30 // this:
(...skipping 25 matching lines...) Expand all
55 56
56 // Construct a buffer with the specified number of uninitialized bytes. 57 // Construct a buffer with the specified number of uninitialized bytes.
57 explicit Buffer(size_t size); 58 explicit Buffer(size_t size);
58 Buffer(size_t size, size_t capacity); 59 Buffer(size_t size, size_t capacity);
59 60
60 // Construct a buffer and copy the specified number of bytes into it. The 61 // Construct a buffer and copy the specified number of bytes into it. The
61 // source array may be (const) uint8_t*, int8_t*, or char*. 62 // source array may be (const) uint8_t*, int8_t*, or char*.
62 template <typename T, typename internal::ByteType<T>::t = 0> 63 template <typename T, typename internal::ByteType<T>::t = 0>
63 Buffer(const T* data, size_t size) 64 Buffer(const T* data, size_t size)
64 : Buffer(data, size, size) {} 65 : Buffer(data, size, size) {}
66
65 template <typename T, typename internal::ByteType<T>::t = 0> 67 template <typename T, typename internal::ByteType<T>::t = 0>
66 Buffer(const T* data, size_t size, size_t capacity) 68 Buffer(const T* data, size_t size, size_t capacity)
67 : Buffer(size, capacity) { 69 : Buffer(size, capacity) {
68 std::memcpy(data_.get(), data, size); 70 std::memcpy(data_.get(), data, size);
69 } 71 }
70 72
71 // Construct a buffer from the contents of an array. 73 // Construct a buffer from the contents of an array.
72 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> 74 template <typename T, size_t N, typename internal::ByteType<T>::t = 0>
73 Buffer(const T(&array)[N]) 75 Buffer(const T(&array)[N])
74 : Buffer(array, N) {} 76 : Buffer(array, N) {}
75 77
76 ~Buffer(); 78 ~Buffer();
77 79
78 // Get a pointer to the data. Just .data() will give you a (const) uint8_t*, 80 // Get a pointer to the data. Just .data() will give you a (const) uint8_t*,
79 // but you may also use .data<int8_t>() and .data<char>(). 81 // but you may also use .data<int8_t>() and .data<char>().
80 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0> 82 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0>
81 const T* data() const { 83 const T* data() const {
82 assert(IsConsistent()); 84 assert(IsConsistent());
83 return reinterpret_cast<T*>(data_.get()); 85 return reinterpret_cast<T*>(data_.get());
84 } 86 }
87
85 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0> 88 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0>
86 T* data() { 89 T* data() {
87 assert(IsConsistent()); 90 assert(IsConsistent());
88 return reinterpret_cast<T*>(data_.get()); 91 return reinterpret_cast<T*>(data_.get());
89 } 92 }
90 93
91 size_t size() const { 94 size_t size() const {
92 assert(IsConsistent()); 95 assert(IsConsistent());
93 return size_; 96 return size_;
94 } 97 }
98
95 size_t capacity() const { 99 size_t capacity() const {
96 assert(IsConsistent()); 100 assert(IsConsistent());
97 return capacity_; 101 return capacity_;
98 } 102 }
99 103
100 Buffer& operator=(const Buffer& buf) { 104 Buffer& operator=(const Buffer& buf) {
101 if (&buf != this) 105 if (&buf != this)
102 SetData(buf.data(), buf.size()); 106 SetData(buf.data(), buf.size());
103 return *this; 107 return *this;
104 } 108 }
109
105 Buffer& operator=(Buffer&& buf) { 110 Buffer& operator=(Buffer&& buf) {
106 assert(IsConsistent()); 111 assert(IsConsistent());
107 assert(buf.IsConsistent()); 112 assert(buf.IsConsistent());
108 size_ = buf.size_; 113 size_ = buf.size_;
109 capacity_ = buf.capacity_; 114 capacity_ = buf.capacity_;
110 data_ = std::move(buf.data_); 115 data_ = std::move(buf.data_);
111 buf.OnMovedFrom(); 116 buf.OnMovedFrom();
112 return *this; 117 return *this;
113 } 118 }
114 119
115 bool operator==(const Buffer& buf) const { 120 bool operator==(const Buffer& buf) const {
116 assert(IsConsistent()); 121 assert(IsConsistent());
117 return size_ == buf.size() && memcmp(data_.get(), buf.data(), size_) == 0; 122 return size_ == buf.size() && memcmp(data_.get(), buf.data(), size_) == 0;
118 } 123 }
119 124
120 bool operator!=(const Buffer& buf) const { return !(*this == buf); } 125 bool operator!=(const Buffer& buf) const { return !(*this == buf); }
121 126
122 // Replace the contents of the buffer. Accepts the same types as the 127 // The SetData functions replace the contents of the buffer. They accept the
123 // constructors. 128 // same input types as the constructors.
124 template <typename T, typename internal::ByteType<T>::t = 0> 129 template <typename T, typename internal::ByteType<T>::t = 0>
125 void SetData(const T* data, size_t size) { 130 void SetData(const T* data, size_t size) {
126 assert(IsConsistent()); 131 assert(IsConsistent());
127 size_ = 0; 132 size_ = 0;
128 AppendData(data, size); 133 AppendData(data, size);
129 } 134 }
135
130 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> 136 template <typename T, size_t N, typename internal::ByteType<T>::t = 0>
131 void SetData(const T(&array)[N]) { 137 void SetData(const T(&array)[N]) {
132 SetData(array, N); 138 SetData(array, N);
133 } 139 }
140
134 void SetData(const Buffer& buf) { SetData(buf.data(), buf.size()); } 141 void SetData(const Buffer& buf) { SetData(buf.data(), buf.size()); }
135 142
136 // Append data to the buffer. Accepts the same types as the constructors. 143 // Replace the data in the buffer with at most |max_bytes| of data, using the
144 // function |setter|, which should have the following signature:
145 // size_t setter(ArrayView<T> view)
146 // |setter| is given an appropriately typed ArrayView of the area in which to
147 // write the data (i.e. starting at the beginning of the buffer) and should
148 // return the number of bytes actually written. This number must be <=
149 // |max_bytes|.
150 template <typename T = uint8_t, typename F,
151 typename internal::ByteType<T>::t = 0>
152 size_t SetData(size_t max_bytes, F&& setter) {
153 RTC_DCHECK(IsConsistent());
154 size_ = 0;
155 return AppendData<T>(max_bytes, std::forward<F>(setter));
156 }
157
158 // The AppendData functions adds data to the end of the buffer. They accept
159 // the same input types as the constructors.
137 template <typename T, typename internal::ByteType<T>::t = 0> 160 template <typename T, typename internal::ByteType<T>::t = 0>
138 void AppendData(const T* data, size_t size) { 161 void AppendData(const T* data, size_t size) {
139 assert(IsConsistent()); 162 assert(IsConsistent());
140 const size_t new_size = size_ + size; 163 const size_t new_size = size_ + size;
141 EnsureCapacity(new_size); 164 EnsureCapacity(new_size);
142 std::memcpy(data_.get() + size_, data, size); 165 std::memcpy(data_.get() + size_, data, size);
143 size_ = new_size; 166 size_ = new_size;
144 assert(IsConsistent()); 167 assert(IsConsistent());
145 } 168 }
169
146 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> 170 template <typename T, size_t N, typename internal::ByteType<T>::t = 0>
147 void AppendData(const T(&array)[N]) { 171 void AppendData(const T(&array)[N]) {
148 AppendData(array, N); 172 AppendData(array, N);
149 } 173 }
174
150 void AppendData(const Buffer& buf) { AppendData(buf.data(), buf.size()); } 175 void AppendData(const Buffer& buf) { AppendData(buf.data(), buf.size()); }
151 176
177 // Append at most |max_bytes| of data to the end of the buffer, using the
178 // function |setter|, which should have the following signature:
179 // size_t setter(ArrayView<T> view)
180 // |setter| is given an appropriately typed ArrayView of the area in which to
181 // write the data (i.e. starting at the former end of the buffer) and should
182 // return the number of bytes actually written. This number must be <=
183 // |max_bytes|.
184 template <typename T = uint8_t, typename F,
185 typename internal::ByteType<T>::t = 0>
186 size_t AppendData(size_t max_bytes, F&& setter) {
187 RTC_DCHECK(IsConsistent());
188 const size_t old_size = size_;
189 SetSize(old_size + max_bytes);
190 T *base_ptr = data<T>() + old_size;
191 size_t written_bytes =
192 setter(rtc::ArrayView<T>(base_ptr, max_bytes));
193
194 RTC_CHECK_LE(written_bytes, max_bytes);
195 size_ = old_size + written_bytes;
196 RTC_DCHECK(IsConsistent());
197 return written_bytes;
198 }
199
152 // Sets the size of the buffer. If the new size is smaller than the old, the 200 // Sets the size of the buffer. If the new size is smaller than the old, the
153 // buffer contents will be kept but truncated; if the new size is greater, 201 // buffer contents will be kept but truncated; if the new size is greater,
154 // the existing contents will be kept and the new space will be 202 // the existing contents will be kept and the new space will be
155 // uninitialized. 203 // uninitialized.
156 void SetSize(size_t size) { 204 void SetSize(size_t size) {
157 EnsureCapacity(size); 205 EnsureCapacity(size);
158 size_ = size; 206 size_ = size;
159 } 207 }
160 208
161 // Ensure that the buffer size can be increased to at least capacity without 209 // Ensure that the buffer size can be increased to at least capacity without
162 // further reallocation. (Of course, this operation might need to reallocate 210 // further reallocation. (Of course, this operation might need to reallocate
163 // the buffer.) 211 // the buffer.)
164 void EnsureCapacity(size_t capacity) { 212 void EnsureCapacity(size_t capacity) {
165 assert(IsConsistent()); 213 assert(IsConsistent());
166 if (capacity <= capacity_) 214 if (capacity <= capacity_)
167 return; 215 return;
168 std::unique_ptr<uint8_t[]> new_data(new uint8_t[capacity]); 216 std::unique_ptr<uint8_t[]> new_data(new uint8_t[capacity]);
169 std::memcpy(new_data.get(), data_.get(), size_); 217 std::memcpy(new_data.get(), data_.get(), size_);
170 data_ = std::move(new_data); 218 data_ = std::move(new_data);
171 capacity_ = capacity; 219 capacity_ = capacity;
172 assert(IsConsistent()); 220 assert(IsConsistent());
173 } 221 }
174 222
175 // b.Pass() does the same thing as std::move(b). 223 // b.Pass() does the same thing as std::move(b).
176 // Deprecated; remove in March 2016 (bug 5373). 224 // Deprecated; remove in March 2016 (bug 5373).
177 RTC_DEPRECATED Buffer&& Pass() { return DEPRECATED_Pass(); } 225 RTC_DEPRECATED Buffer&& Pass() { return DEPRECATED_Pass(); }
226
178 Buffer&& DEPRECATED_Pass() { 227 Buffer&& DEPRECATED_Pass() {
179 assert(IsConsistent()); 228 assert(IsConsistent());
180 return std::move(*this); 229 return std::move(*this);
181 } 230 }
182 231
183 // Resets the buffer to zero size without altering capacity. Works even if the 232 // Resets the buffer to zero size without altering capacity. Works even if the
184 // buffer has been moved from. 233 // buffer has been moved from.
185 void Clear() { 234 void Clear() {
186 size_ = 0; 235 size_ = 0;
187 assert(IsConsistent()); 236 assert(IsConsistent());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 269 }
221 270
222 size_t size_; 271 size_t size_;
223 size_t capacity_; 272 size_t capacity_;
224 std::unique_ptr<uint8_t[]> data_; 273 std::unique_ptr<uint8_t[]> data_;
225 }; 274 };
226 275
227 } // namespace rtc 276 } // namespace rtc
228 277
229 #endif // WEBRTC_BASE_BUFFER_H_ 278 #endif // WEBRTC_BASE_BUFFER_H_
OLDNEW
« no previous file with comments | « no previous file | webrtc/base/buffer.cc » ('j') | webrtc/base/buffer_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698