LCOV - code coverage report
Current view: top level - xpcom/string - nsStringBuffer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 8 8 100.0 %
Date: 2017-07-14 16:53:18 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsStringBuffer_h__
       8             : #define nsStringBuffer_h__
       9             : 
      10             : #include <atomic>
      11             : #include "mozilla/MemoryReporting.h"
      12             : 
      13             : template<class T> struct already_AddRefed;
      14             : 
      15             : /**
      16             :  * This structure precedes the string buffers "we" allocate.  It may be the
      17             :  * case that nsTAString::mData does not point to one of these special
      18             :  * buffers.  The mDataFlags member variable distinguishes the buffer type.
      19             :  *
      20             :  * When this header is in use, it enables reference counting, and capacity
      21             :  * tracking.  NOTE: A string buffer can be modified only if its reference
      22             :  * count is 1.
      23             :  */
      24             : class nsStringBuffer
      25             : {
      26             : private:
      27             :   friend class CheckStaticAtomSizes;
      28             : 
      29             :   std::atomic<uint32_t> mRefCount;
      30             :   uint32_t mStorageSize;
      31             : 
      32             : public:
      33             : 
      34             :   /**
      35             :    * Allocates a new string buffer, with given size in bytes and a
      36             :    * reference count of one.  When the string buffer is no longer needed,
      37             :    * it should be released via Release.
      38             :    *
      39             :    * It is up to the caller to set the bytes corresponding to the string
      40             :    * buffer by calling the Data method to fetch the raw data pointer.  Care
      41             :    * must be taken to properly null terminate the character array.  The
      42             :    * storage size can be greater than the length of the actual string
      43             :    * (i.e., it is not required that the null terminator appear in the last
      44             :    * storage unit of the string buffer's data).
      45             :    *
      46             :    * @return new string buffer or null if out of memory.
      47             :    */
      48             :   static already_AddRefed<nsStringBuffer> Alloc(size_t aStorageSize);
      49             : 
      50             :   /**
      51             :    * Resizes the given string buffer to the specified storage size.  This
      52             :    * method must not be called on a readonly string buffer.  Use this API
      53             :    * carefully!!
      54             :    *
      55             :    * This method behaves like the ANSI-C realloc function.  (i.e., If the
      56             :    * allocation fails, null will be returned and the given string buffer
      57             :    * will remain unmodified.)
      58             :    *
      59             :    * @see IsReadonly
      60             :    */
      61             :   static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize);
      62             : 
      63             :   /**
      64             :    * Increment the reference count on this string buffer.
      65             :    */
      66             :   void NS_FASTCALL AddRef();
      67             : 
      68             :   /**
      69             :    * Decrement the reference count on this string buffer.  The string
      70             :    * buffer will be destroyed when its reference count reaches zero.
      71             :    */
      72             :   void NS_FASTCALL Release();
      73             : 
      74             :   /**
      75             :    * This method returns the string buffer corresponding to the given data
      76             :    * pointer.  The data pointer must have been returned previously by a
      77             :    * call to the nsStringBuffer::Data method.
      78             :    */
      79      272679 :   static nsStringBuffer* FromData(void* aData)
      80             :   {
      81      272679 :     return reinterpret_cast<nsStringBuffer*>(aData) - 1;
      82             :   }
      83             : 
      84             :   /**
      85             :    * This method returns the data pointer for this string buffer.
      86             :    */
      87      131098 :   void* Data() const
      88             :   {
      89      131098 :     return const_cast<char*>(reinterpret_cast<const char*>(this + 1));
      90             :   }
      91             : 
      92             :   /**
      93             :    * This function returns the storage size of a string buffer in bytes.
      94             :    * This value is the same value that was originally passed to Alloc (or
      95             :    * Realloc).
      96             :    */
      97       59210 :   uint32_t StorageSize() const
      98             :   {
      99       59210 :     return mStorageSize;
     100             :   }
     101             : 
     102             :   /**
     103             :    * If this method returns false, then the caller can be sure that their
     104             :    * reference to the string buffer is the only reference to the string
     105             :    * buffer, and therefore it has exclusive access to the string buffer and
     106             :    * associated data.  However, if this function returns true, then other
     107             :    * consumers may rely on the data in this buffer being immutable and
     108             :    * other threads may access this buffer simultaneously.
     109             :    */
     110       95417 :   bool IsReadonly() const
     111             :   {
     112             :     // This doesn't lead to the destruction of the buffer, so we don't
     113             :     // need to perform acquire memory synchronization for the normal
     114             :     // reason that a reference count needs acquire synchronization
     115             :     // (ensuring that all writes to the object made on other threads are
     116             :     // visible to the thread destroying the object).
     117             :     //
     118             :     // We then need to consider the possibility that there were prior
     119             :     // writes to the buffer on a different thread:  one that has either
     120             :     // since released its reference count, or one that also has access
     121             :     // to this buffer through the same reference.  There are two ways
     122             :     // for that to happen: either the buffer pointer or a data structure
     123             :     // (e.g., string object) pointing to the buffer was transferred from
     124             :     // one thread to another, or the data structure pointing to the
     125             :     // buffer was already visible on both threads.  In the first case
     126             :     // (transfer), the transfer of data from one thread to another would
     127             :     // have handled the memory synchronization.  In the latter case
     128             :     // (data structure visible on both threads), the caller needed some
     129             :     // sort of higher level memory synchronization to protect against
     130             :     // the string object being mutated at the same time on multiple
     131             :     // threads.
     132      190834 :     return mRefCount.load(std::memory_order_relaxed) > 1;
     133             :   }
     134             : 
     135             :   /**
     136             :    * The FromString methods return a string buffer for the given string
     137             :    * object or null if the string object does not have a string buffer.
     138             :    * The reference count of the string buffer is NOT incremented by these
     139             :    * methods.  If the caller wishes to hold onto the returned value, then
     140             :    * the returned string buffer must have its reference count incremented
     141             :    * via a call to the AddRef method.
     142             :    */
     143             :   static nsStringBuffer* FromString(const nsAString& aStr);
     144             :   static nsStringBuffer* FromString(const nsACString& aStr);
     145             : 
     146             :   /**
     147             :    * The ToString methods assign this string buffer to a given string
     148             :    * object.  If the string object does not support sharable string
     149             :    * buffers, then its value will be set to a copy of the given string
     150             :    * buffer.  Otherwise, these methods increment the reference count of the
     151             :    * given string buffer.  It is important to specify the length (in
     152             :    * storage units) of the string contained in the string buffer since the
     153             :    * length of the string may be less than its storage size.  The string
     154             :    * must have a null terminator at the offset specified by |len|.
     155             :    *
     156             :    * NOTE: storage size is measured in bytes even for wide strings;
     157             :    *       however, string length is always measured in storage units
     158             :    *       (2-byte units for wide strings).
     159             :    */
     160             :   void ToString(uint32_t aLen, nsAString& aStr, bool aMoveOwnership = false);
     161             :   void ToString(uint32_t aLen, nsACString& aStr, bool aMoveOwnership = false);
     162             : 
     163             :   /**
     164             :    * This measures the size only if the StringBuffer is unshared.
     165             :    */
     166             :   size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf) const;
     167             : 
     168             :   /**
     169             :    * This measures the size regardless of whether the StringBuffer is
     170             :    * unshared.
     171             :    *
     172             :    * WARNING: Only use this if you really know what you are doing, because
     173             :    * it can easily lead to double-counting strings.  If you do use them,
     174             :    * please explain clearly in a comment why it's safe and won't lead to
     175             :    * double-counting.
     176             :    */
     177             :   size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf) const;
     178             : };
     179             : 
     180             : #endif /* !defined(nsStringBuffer_h__ */

Generated by: LCOV version 1.13