LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - copyonwritebuffer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 34 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright 2016 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 WEBRTC_BASE_COPYONWRITEBUFFER_H_
      12             : #define WEBRTC_BASE_COPYONWRITEBUFFER_H_
      13             : 
      14             : #include <algorithm>
      15             : #include <utility>
      16             : 
      17             : #include "webrtc/base/buffer.h"
      18             : #include "webrtc/base/checks.h"
      19             : #include "webrtc/base/refcount.h"
      20             : #include "webrtc/base/scoped_ref_ptr.h"
      21             : 
      22             : namespace rtc {
      23             : 
      24           0 : class CopyOnWriteBuffer {
      25             :  public:
      26             :   // An empty buffer.
      27             :   CopyOnWriteBuffer();
      28             :   // Copy size and contents of an existing buffer.
      29             :   CopyOnWriteBuffer(const CopyOnWriteBuffer& buf);
      30             :   // Move contents from an existing buffer.
      31             :   CopyOnWriteBuffer(CopyOnWriteBuffer&& buf);
      32             : 
      33             :   // Construct a buffer with the specified number of uninitialized bytes.
      34             :   explicit CopyOnWriteBuffer(size_t size);
      35             :   CopyOnWriteBuffer(size_t size, size_t capacity);
      36             : 
      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*.
      39             :   template <typename T,
      40             :             typename std::enable_if<
      41             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
      42             :   CopyOnWriteBuffer(const T* data, size_t size)
      43             :       : CopyOnWriteBuffer(data, size, size) {}
      44             :   template <typename T,
      45             :             typename std::enable_if<
      46             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
      47             :   CopyOnWriteBuffer(const T* data, size_t size, size_t capacity)
      48             :       : CopyOnWriteBuffer(size, capacity) {
      49             :     if (buffer_) {
      50             :       std::memcpy(buffer_->data(), data, size);
      51             :     }
      52             :   }
      53             : 
      54             :   // Construct a buffer from the contents of an array.
      55             :   template <typename T,
      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
      60             :       : CopyOnWriteBuffer(array, N) {}
      61             : 
      62             :   ~CopyOnWriteBuffer();
      63             : 
      64             :   // Get a pointer to the data. Just .data() will give you a (const) uint8_t*,
      65             :   // but you may also use .data<int8_t>() and .data<char>().
      66             :   template <typename T = uint8_t,
      67             :             typename std::enable_if<
      68             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
      69             :   const T* data() const {
      70             :     return cdata<T>();
      71             :   }
      72             : 
      73             :   // Get writable pointer to the data. This will create a copy of the underlying
      74             :   // data if it is shared with other buffers.
      75             :   template <typename T = uint8_t,
      76             :             typename std::enable_if<
      77             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
      78           0 :   T* data() {
      79           0 :     RTC_DCHECK(IsConsistent());
      80           0 :     if (!buffer_) {
      81           0 :       return nullptr;
      82             :     }
      83           0 :     CloneDataIfReferenced(buffer_->capacity());
      84           0 :     return buffer_->data<T>();
      85             :   }
      86             : 
      87             :   // Get const pointer to the data. This will not create a copy of the
      88             :   // underlying data if it is shared with other buffers.
      89             :   template <typename T = uint8_t,
      90             :             typename std::enable_if<
      91             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
      92           0 :   const T* cdata() const {
      93           0 :     RTC_DCHECK(IsConsistent());
      94           0 :     if (!buffer_) {
      95           0 :       return nullptr;
      96             :     }
      97           0 :     return buffer_->data<T>();
      98             :   }
      99             : 
     100           0 :   size_t size() const {
     101           0 :     RTC_DCHECK(IsConsistent());
     102           0 :     return buffer_ ? buffer_->size() : 0;
     103             :   }
     104             : 
     105           0 :   size_t capacity() const {
     106           0 :     RTC_DCHECK(IsConsistent());
     107           0 :     return buffer_ ? buffer_->capacity() : 0;
     108             :   }
     109             : 
     110             :   CopyOnWriteBuffer& operator=(const CopyOnWriteBuffer& buf) {
     111             :     RTC_DCHECK(IsConsistent());
     112             :     RTC_DCHECK(buf.IsConsistent());
     113             :     if (&buf != this) {
     114             :       buffer_ = buf.buffer_;
     115             :     }
     116             :     return *this;
     117             :   }
     118             : 
     119           0 :   CopyOnWriteBuffer& operator=(CopyOnWriteBuffer&& buf) {
     120           0 :     RTC_DCHECK(IsConsistent());
     121           0 :     RTC_DCHECK(buf.IsConsistent());
     122           0 :     buffer_ = std::move(buf.buffer_);
     123           0 :     return *this;
     124             :   }
     125             : 
     126             :   bool operator==(const CopyOnWriteBuffer& buf) const;
     127             : 
     128             :   bool operator!=(const CopyOnWriteBuffer& buf) const {
     129             :     return !(*this == buf);
     130             :   }
     131             : 
     132             :   uint8_t& operator[](size_t index) {
     133             :     RTC_DCHECK_LT(index, size());
     134             :     return data()[index];
     135             :   }
     136             : 
     137             :   uint8_t operator[](size_t index) const {
     138             :     RTC_DCHECK_LT(index, size());
     139             :     return cdata()[index];
     140             :   }
     141             : 
     142             :   // Replace the contents of the buffer. Accepts the same types as the
     143             :   // constructors.
     144             :   template <typename T,
     145             :             typename std::enable_if<
     146             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
     147           0 :   void SetData(const T* data, size_t size) {
     148           0 :     RTC_DCHECK(IsConsistent());
     149           0 :     if (!buffer_) {
     150           0 :       buffer_ = size > 0 ? new RefCountedObject<Buffer>(data, size) : nullptr;
     151           0 :     } else if (!buffer_->HasOneRef()) {
     152           0 :       buffer_ = new RefCountedObject<Buffer>(data, size, buffer_->capacity());
     153             :     } else {
     154           0 :       buffer_->SetData(data, size);
     155             :     }
     156           0 :     RTC_DCHECK(IsConsistent());
     157           0 :   }
     158             : 
     159             :   template <typename T,
     160             :             size_t N,
     161             :             typename std::enable_if<
     162             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
     163             :   void SetData(const T (&array)[N]) {
     164             :     SetData(array, N);
     165             :   }
     166             : 
     167             :   void SetData(const CopyOnWriteBuffer& buf) {
     168             :     RTC_DCHECK(IsConsistent());
     169             :     RTC_DCHECK(buf.IsConsistent());
     170             :     if (&buf != this) {
     171             :       buffer_ = buf.buffer_;
     172             :     }
     173             :   }
     174             : 
     175             :   // Append data to the buffer. Accepts the same types as the constructors.
     176             :   template <typename T,
     177             :             typename std::enable_if<
     178             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
     179             :   void AppendData(const T* data, size_t size) {
     180             :     RTC_DCHECK(IsConsistent());
     181             :     if (!buffer_) {
     182             :       buffer_ = new RefCountedObject<Buffer>(data, size);
     183             :       RTC_DCHECK(IsConsistent());
     184             :       return;
     185             :     }
     186             : 
     187             :     CloneDataIfReferenced(std::max(buffer_->capacity(),
     188             :         buffer_->size() + size));
     189             :     buffer_->AppendData(data, size);
     190             :     RTC_DCHECK(IsConsistent());
     191             :   }
     192             : 
     193             :   template <typename T,
     194             :             size_t N,
     195             :             typename std::enable_if<
     196             :                 internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
     197             :   void AppendData(const T (&array)[N]) {
     198             :     AppendData(array, N);
     199             :   }
     200             : 
     201             :   void AppendData(const CopyOnWriteBuffer& buf) {
     202             :     AppendData(buf.data(), buf.size());
     203             :   }
     204             : 
     205             :   // Sets the size of the buffer. If the new size is smaller than the old, the
     206             :   // buffer contents will be kept but truncated; if the new size is greater,
     207             :   // the existing contents will be kept and the new space will be
     208             :   // uninitialized.
     209             :   void SetSize(size_t size);
     210             : 
     211             :   // Ensure that the buffer size can be increased to at least capacity without
     212             :   // further reallocation. (Of course, this operation might need to reallocate
     213             :   // the buffer.)
     214             :   void EnsureCapacity(size_t capacity);
     215             : 
     216             :   // Resets the buffer to zero size without altering capacity. Works even if the
     217             :   // buffer has been moved from.
     218             :   void Clear();
     219             : 
     220             :   // Swaps two buffers.
     221             :   friend void swap(CopyOnWriteBuffer& a, CopyOnWriteBuffer& b) {
     222             :     std::swap(a.buffer_, b.buffer_);
     223             :   }
     224             : 
     225             :  private:
     226             :   // Create a copy of the underlying data if it is referenced from other Buffer
     227             :   // objects.
     228             :   void CloneDataIfReferenced(size_t new_capacity);
     229             : 
     230             :   // Pre- and postcondition of all methods.
     231           0 :   bool IsConsistent() const {
     232           0 :     return (!buffer_ || buffer_->capacity() > 0);
     233             :   }
     234             : 
     235             :   // buffer_ is either null, or points to an rtc::Buffer with capacity > 0.
     236             :   scoped_refptr<RefCountedObject<Buffer>> buffer_;
     237             : };
     238             : 
     239             : }  // namespace rtc
     240             : 
     241             : #endif  // WEBRTC_BASE_COPYONWRITEBUFFER_H_

Generated by: LCOV version 1.13