| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 return *this; | 116 return *this; |
| 117 } | 117 } |
| 118 | 118 |
| 119 CopyOnWriteBuffer& operator=(CopyOnWriteBuffer&& buf) { | 119 CopyOnWriteBuffer& operator=(CopyOnWriteBuffer&& buf) { |
| 120 RTC_DCHECK(IsConsistent()); | 120 RTC_DCHECK(IsConsistent()); |
| 121 RTC_DCHECK(buf.IsConsistent()); | 121 RTC_DCHECK(buf.IsConsistent()); |
| 122 buffer_ = std::move(buf.buffer_); | 122 buffer_ = std::move(buf.buffer_); |
| 123 return *this; | 123 return *this; |
| 124 } | 124 } |
| 125 | 125 |
| 126 bool operator==(const CopyOnWriteBuffer& buf) const { | 126 bool operator==(const CopyOnWriteBuffer& buf) const; |
| 127 // Must either use the same buffer internally or have the same contents. | |
| 128 RTC_DCHECK(IsConsistent()); | |
| 129 RTC_DCHECK(buf.IsConsistent()); | |
| 130 return buffer_.get() == buf.buffer_.get() || | |
| 131 (buffer_.get() && buf.buffer_.get() && | |
| 132 *buffer_.get() == *buf.buffer_.get()); | |
| 133 } | |
| 134 | 127 |
| 135 bool operator!=(const CopyOnWriteBuffer& buf) const { | 128 bool operator!=(const CopyOnWriteBuffer& buf) const { |
| 136 return !(*this == buf); | 129 return !(*this == buf); |
| 137 } | 130 } |
| 138 | 131 |
| 139 uint8_t& operator[](size_t index) { | 132 uint8_t& operator[](size_t index) { |
| 140 RTC_DCHECK_LT(index, size()); | 133 RTC_DCHECK_LT(index, size()); |
| 141 return data()[index]; | 134 return data()[index]; |
| 142 } | 135 } |
| 143 | 136 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 199 } |
| 207 | 200 |
| 208 void AppendData(const CopyOnWriteBuffer& buf) { | 201 void AppendData(const CopyOnWriteBuffer& buf) { |
| 209 AppendData(buf.data(), buf.size()); | 202 AppendData(buf.data(), buf.size()); |
| 210 } | 203 } |
| 211 | 204 |
| 212 // Sets the size of the buffer. If the new size is smaller than the old, the | 205 // Sets the size of the buffer. If the new size is smaller than the old, the |
| 213 // buffer contents will be kept but truncated; if the new size is greater, | 206 // buffer contents will be kept but truncated; if the new size is greater, |
| 214 // the existing contents will be kept and the new space will be | 207 // the existing contents will be kept and the new space will be |
| 215 // uninitialized. | 208 // uninitialized. |
| 216 void SetSize(size_t size) { | 209 void SetSize(size_t size); |
| 217 RTC_DCHECK(IsConsistent()); | |
| 218 if (!buffer_) { | |
| 219 if (size > 0) { | |
| 220 buffer_ = new RefCountedObject<Buffer>(size); | |
| 221 } | |
| 222 RTC_DCHECK(IsConsistent()); | |
| 223 return; | |
| 224 } | |
| 225 | |
| 226 // Clone data if referenced. | |
| 227 if (!buffer_->HasOneRef()) { | |
| 228 buffer_ = new RefCountedObject<Buffer>( | |
| 229 buffer_->data(), | |
| 230 std::min(buffer_->size(), size), | |
| 231 std::max(buffer_->capacity(), size)); | |
| 232 } | |
| 233 buffer_->SetSize(size); | |
| 234 RTC_DCHECK(IsConsistent()); | |
| 235 } | |
| 236 | 210 |
| 237 // Ensure that the buffer size can be increased to at least capacity without | 211 // Ensure that the buffer size can be increased to at least capacity without |
| 238 // further reallocation. (Of course, this operation might need to reallocate | 212 // further reallocation. (Of course, this operation might need to reallocate |
| 239 // the buffer.) | 213 // the buffer.) |
| 240 void EnsureCapacity(size_t capacity) { | 214 void EnsureCapacity(size_t capacity); |
| 241 RTC_DCHECK(IsConsistent()); | |
| 242 if (!buffer_) { | |
| 243 if (capacity > 0) { | |
| 244 buffer_ = new RefCountedObject<Buffer>(0, capacity); | |
| 245 } | |
| 246 RTC_DCHECK(IsConsistent()); | |
| 247 return; | |
| 248 } else if (capacity <= buffer_->capacity()) { | |
| 249 return; | |
| 250 } | |
| 251 | |
| 252 CloneDataIfReferenced(std::max(buffer_->capacity(), capacity)); | |
| 253 buffer_->EnsureCapacity(capacity); | |
| 254 RTC_DCHECK(IsConsistent()); | |
| 255 } | |
| 256 | 215 |
| 257 // Resets the buffer to zero size without altering capacity. Works even if the | 216 // Resets the buffer to zero size without altering capacity. Works even if the |
| 258 // buffer has been moved from. | 217 // buffer has been moved from. |
| 259 void Clear() { | 218 void Clear(); |
| 260 if (!buffer_) | |
| 261 return; | |
| 262 | |
| 263 if (buffer_->HasOneRef()) { | |
| 264 buffer_->Clear(); | |
| 265 } else { | |
| 266 buffer_ = new RefCountedObject<Buffer>(0, buffer_->capacity()); | |
| 267 } | |
| 268 RTC_DCHECK(IsConsistent()); | |
| 269 } | |
| 270 | 219 |
| 271 // Swaps two buffers. | 220 // Swaps two buffers. |
| 272 friend void swap(CopyOnWriteBuffer& a, CopyOnWriteBuffer& b) { | 221 friend void swap(CopyOnWriteBuffer& a, CopyOnWriteBuffer& b) { |
| 273 std::swap(a.buffer_, b.buffer_); | 222 std::swap(a.buffer_, b.buffer_); |
| 274 } | 223 } |
| 275 | 224 |
| 276 private: | 225 private: |
| 277 // Create a copy of the underlying data if it is referenced from other Buffer | 226 // Create a copy of the underlying data if it is referenced from other Buffer |
| 278 // objects. | 227 // objects. |
| 279 void CloneDataIfReferenced(size_t new_capacity) { | 228 void CloneDataIfReferenced(size_t new_capacity); |
| 280 if (buffer_->HasOneRef()) { | |
| 281 return; | |
| 282 } | |
| 283 | |
| 284 buffer_ = new RefCountedObject<Buffer>(buffer_->data(), buffer_->size(), | |
| 285 new_capacity); | |
| 286 RTC_DCHECK(IsConsistent()); | |
| 287 } | |
| 288 | 229 |
| 289 // Pre- and postcondition of all methods. | 230 // Pre- and postcondition of all methods. |
| 290 bool IsConsistent() const { | 231 bool IsConsistent() const { |
| 291 return (!buffer_ || buffer_->capacity() > 0); | 232 return (!buffer_ || buffer_->capacity() > 0); |
| 292 } | 233 } |
| 293 | 234 |
| 294 // buffer_ is either null, or points to an rtc::Buffer with capacity > 0. | 235 // buffer_ is either null, or points to an rtc::Buffer with capacity > 0. |
| 295 scoped_refptr<RefCountedObject<Buffer>> buffer_; | 236 scoped_refptr<RefCountedObject<Buffer>> buffer_; |
| 296 }; | 237 }; |
| 297 | 238 |
| 298 } // namespace rtc | 239 } // namespace rtc |
| 299 | 240 |
| 300 #endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_ | 241 #endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_ |
| OLD | NEW |