| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 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 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 CopyOnWriteBuffer(const CopyOnWriteBuffer& buf); | 29 CopyOnWriteBuffer(const CopyOnWriteBuffer& buf); |
| 30 // Move contents from an existing buffer. | 30 // Move contents from an existing buffer. |
| 31 CopyOnWriteBuffer(CopyOnWriteBuffer&& buf); | 31 CopyOnWriteBuffer(CopyOnWriteBuffer&& buf); |
| 32 | 32 |
| 33 // Construct a buffer with the specified number of uninitialized bytes. | 33 // Construct a buffer with the specified number of uninitialized bytes. |
| 34 explicit CopyOnWriteBuffer(size_t size); | 34 explicit CopyOnWriteBuffer(size_t size); |
| 35 CopyOnWriteBuffer(size_t size, size_t capacity); | 35 CopyOnWriteBuffer(size_t size, size_t capacity); |
| 36 | 36 |
| 37 // Construct a buffer and copy the specified number of bytes into it. The | 37 // Construct a buffer and copy the specified number of bytes into it. The |
| 38 // source array may be (const) uint8_t*, int8_t*, or char*. | 38 // source array may be (const) uint8_t*, int8_t*, or char*. |
| 39 template <typename T, typename internal::ByteType<T>::t = 0> | 39 template <typename T, |
| 40 typename std::enable_if< |
| 41 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 40 CopyOnWriteBuffer(const T* data, size_t size) | 42 CopyOnWriteBuffer(const T* data, size_t size) |
| 41 : CopyOnWriteBuffer(data, size, size) {} | 43 : CopyOnWriteBuffer(data, size, size) {} |
| 42 template <typename T, typename internal::ByteType<T>::t = 0> | 44 template <typename T, |
| 45 typename std::enable_if< |
| 46 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 43 CopyOnWriteBuffer(const T* data, size_t size, size_t capacity) | 47 CopyOnWriteBuffer(const T* data, size_t size, size_t capacity) |
| 44 : CopyOnWriteBuffer(size, capacity) { | 48 : CopyOnWriteBuffer(size, capacity) { |
| 45 if (buffer_) { | 49 if (buffer_) { |
| 46 std::memcpy(buffer_->data(), data, size); | 50 std::memcpy(buffer_->data(), data, size); |
| 47 } | 51 } |
| 48 } | 52 } |
| 49 | 53 |
| 50 // Construct a buffer from the contents of an array. | 54 // Construct a buffer from the contents of an array. |
| 51 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> | 55 template <typename T, |
| 52 CopyOnWriteBuffer(const T(&array)[N]) // NOLINT: runtime/explicit | 56 size_t N, |
| 57 typename std::enable_if< |
| 58 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 59 CopyOnWriteBuffer(const T (&array)[N]) // NOLINT: runtime/explicit |
| 53 : CopyOnWriteBuffer(array, N) {} | 60 : CopyOnWriteBuffer(array, N) {} |
| 54 | 61 |
| 55 ~CopyOnWriteBuffer(); | 62 ~CopyOnWriteBuffer(); |
| 56 | 63 |
| 57 // Get a pointer to the data. Just .data() will give you a (const) uint8_t*, | 64 // Get a pointer to the data. Just .data() will give you a (const) uint8_t*, |
| 58 // but you may also use .data<int8_t>() and .data<char>(). | 65 // but you may also use .data<int8_t>() and .data<char>(). |
| 59 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0> | 66 template <typename T = uint8_t, |
| 67 typename std::enable_if< |
| 68 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 60 const T* data() const { | 69 const T* data() const { |
| 61 return cdata<T>(); | 70 return cdata<T>(); |
| 62 } | 71 } |
| 63 | 72 |
| 64 // Get writable pointer to the data. This will create a copy of the underlying | 73 // Get writable pointer to the data. This will create a copy of the underlying |
| 65 // data if it is shared with other buffers. | 74 // data if it is shared with other buffers. |
| 66 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0> | 75 template <typename T = uint8_t, |
| 76 typename std::enable_if< |
| 77 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 67 T* data() { | 78 T* data() { |
| 68 RTC_DCHECK(IsConsistent()); | 79 RTC_DCHECK(IsConsistent()); |
| 69 if (!buffer_) { | 80 if (!buffer_) { |
| 70 return nullptr; | 81 return nullptr; |
| 71 } | 82 } |
| 72 CloneDataIfReferenced(buffer_->capacity()); | 83 CloneDataIfReferenced(buffer_->capacity()); |
| 73 return buffer_->data<T>(); | 84 return buffer_->data<T>(); |
| 74 } | 85 } |
| 75 | 86 |
| 76 // Get const pointer to the data. This will not create a copy of the | 87 // Get const pointer to the data. This will not create a copy of the |
| 77 // underlying data if it is shared with other buffers. | 88 // underlying data if it is shared with other buffers. |
| 78 template <typename T = uint8_t, typename internal::ByteType<T>::t = 0> | 89 template <typename T = uint8_t, |
| 90 typename std::enable_if< |
| 91 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 79 T* cdata() const { | 92 T* cdata() const { |
| 80 RTC_DCHECK(IsConsistent()); | 93 RTC_DCHECK(IsConsistent()); |
| 81 if (!buffer_) { | 94 if (!buffer_) { |
| 82 return nullptr; | 95 return nullptr; |
| 83 } | 96 } |
| 84 return buffer_->data<T>(); | 97 return buffer_->data<T>(); |
| 85 } | 98 } |
| 86 | 99 |
| 87 size_t size() const { | 100 size_t size() const { |
| 88 RTC_DCHECK(IsConsistent()); | 101 RTC_DCHECK(IsConsistent()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return data()[index]; | 143 return data()[index]; |
| 131 } | 144 } |
| 132 | 145 |
| 133 uint8_t operator[](size_t index) const { | 146 uint8_t operator[](size_t index) const { |
| 134 RTC_DCHECK_LT(index, size()); | 147 RTC_DCHECK_LT(index, size()); |
| 135 return cdata()[index]; | 148 return cdata()[index]; |
| 136 } | 149 } |
| 137 | 150 |
| 138 // Replace the contents of the buffer. Accepts the same types as the | 151 // Replace the contents of the buffer. Accepts the same types as the |
| 139 // constructors. | 152 // constructors. |
| 140 template <typename T, typename internal::ByteType<T>::t = 0> | 153 template <typename T, |
| 154 typename std::enable_if< |
| 155 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 141 void SetData(const T* data, size_t size) { | 156 void SetData(const T* data, size_t size) { |
| 142 RTC_DCHECK(IsConsistent()); | 157 RTC_DCHECK(IsConsistent()); |
| 143 if (!buffer_ || !buffer_->HasOneRef()) { | 158 if (!buffer_ || !buffer_->HasOneRef()) { |
| 144 buffer_ = size > 0 ? new RefCountedObject<Buffer>(data, size) | 159 buffer_ = size > 0 ? new RefCountedObject<Buffer>(data, size) |
| 145 : nullptr; | 160 : nullptr; |
| 146 } else { | 161 } else { |
| 147 buffer_->SetData(data, size); | 162 buffer_->SetData(data, size); |
| 148 } | 163 } |
| 149 RTC_DCHECK(IsConsistent()); | 164 RTC_DCHECK(IsConsistent()); |
| 150 } | 165 } |
| 151 | 166 |
| 152 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> | 167 template <typename T, |
| 153 void SetData(const T(&array)[N]) { | 168 size_t N, |
| 169 typename std::enable_if< |
| 170 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 171 void SetData(const T (&array)[N]) { |
| 154 SetData(array, N); | 172 SetData(array, N); |
| 155 } | 173 } |
| 156 | 174 |
| 157 void SetData(const CopyOnWriteBuffer& buf) { | 175 void SetData(const CopyOnWriteBuffer& buf) { |
| 158 RTC_DCHECK(IsConsistent()); | 176 RTC_DCHECK(IsConsistent()); |
| 159 RTC_DCHECK(buf.IsConsistent()); | 177 RTC_DCHECK(buf.IsConsistent()); |
| 160 if (&buf != this) { | 178 if (&buf != this) { |
| 161 buffer_ = buf.buffer_; | 179 buffer_ = buf.buffer_; |
| 162 } | 180 } |
| 163 } | 181 } |
| 164 | 182 |
| 165 // Append data to the buffer. Accepts the same types as the constructors. | 183 // Append data to the buffer. Accepts the same types as the constructors. |
| 166 template <typename T, typename internal::ByteType<T>::t = 0> | 184 template <typename T, |
| 185 typename std::enable_if< |
| 186 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 167 void AppendData(const T* data, size_t size) { | 187 void AppendData(const T* data, size_t size) { |
| 168 RTC_DCHECK(IsConsistent()); | 188 RTC_DCHECK(IsConsistent()); |
| 169 if (!buffer_) { | 189 if (!buffer_) { |
| 170 buffer_ = new RefCountedObject<Buffer>(data, size); | 190 buffer_ = new RefCountedObject<Buffer>(data, size); |
| 171 RTC_DCHECK(IsConsistent()); | 191 RTC_DCHECK(IsConsistent()); |
| 172 return; | 192 return; |
| 173 } | 193 } |
| 174 | 194 |
| 175 CloneDataIfReferenced(std::max(buffer_->capacity(), | 195 CloneDataIfReferenced(std::max(buffer_->capacity(), |
| 176 buffer_->size() + size)); | 196 buffer_->size() + size)); |
| 177 buffer_->AppendData(data, size); | 197 buffer_->AppendData(data, size); |
| 178 RTC_DCHECK(IsConsistent()); | 198 RTC_DCHECK(IsConsistent()); |
| 179 } | 199 } |
| 180 | 200 |
| 181 template <typename T, size_t N, typename internal::ByteType<T>::t = 0> | 201 template <typename T, |
| 182 void AppendData(const T(&array)[N]) { | 202 size_t N, |
| 203 typename std::enable_if< |
| 204 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr> |
| 205 void AppendData(const T (&array)[N]) { |
| 183 AppendData(array, N); | 206 AppendData(array, N); |
| 184 } | 207 } |
| 185 | 208 |
| 186 void AppendData(const CopyOnWriteBuffer& buf) { | 209 void AppendData(const CopyOnWriteBuffer& buf) { |
| 187 AppendData(buf.data(), buf.size()); | 210 AppendData(buf.data(), buf.size()); |
| 188 } | 211 } |
| 189 | 212 |
| 190 // Sets the size of the buffer. If the new size is smaller than the old, the | 213 // Sets the size of the buffer. If the new size is smaller than the old, the |
| 191 // buffer contents will be kept but truncated; if the new size is greater, | 214 // buffer contents will be kept but truncated; if the new size is greater, |
| 192 // the existing contents will be kept and the new space will be | 215 // the existing contents will be kept and the new space will be |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 return (!buffer_ || buffer_->capacity() > 0); | 283 return (!buffer_ || buffer_->capacity() > 0); |
| 261 } | 284 } |
| 262 | 285 |
| 263 // buffer_ is either null, or points to an rtc::Buffer with capacity > 0. | 286 // buffer_ is either null, or points to an rtc::Buffer with capacity > 0. |
| 264 scoped_refptr<RefCountedObject<Buffer>> buffer_; | 287 scoped_refptr<RefCountedObject<Buffer>> buffer_; |
| 265 }; | 288 }; |
| 266 | 289 |
| 267 } // namespace rtc | 290 } // namespace rtc |
| 268 | 291 |
| 269 #endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_ | 292 #endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_ |
| OLD | NEW |