content/base/src/nsTextFragment.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * A class which represents a fragment of text (eg inside a text
     7  * node); if only codepoints below 256 are used, the text is stored as
     8  * a char*; otherwise the text is stored as a char16_t*
     9  */
    11 #ifndef nsTextFragment_h___
    12 #define nsTextFragment_h___
    14 #include "mozilla/Attributes.h"
    15 #include "mozilla/MemoryReporting.h"
    17 #include "nsString.h"
    18 #include "nsReadableUtils.h"
    19 #include "nsISupportsImpl.h"
    21 class nsString;
    22 class nsCString;
    24 // XXX should this normalize the code to keep a \u0000 at the end?
    26 // XXX nsTextFragmentPool?
    28 /**
    29  * A fragment of text. If mIs2b is 1 then the m2b pointer is valid
    30  * otherwise the m1b pointer is valid. If m1b is used then each byte
    31  * of data represents a single ucs2 character with the high byte being
    32  * zero.
    33  *
    34  * This class does not have a virtual destructor therefore it is not
    35  * meant to be subclassed.
    36  */
    37 class nsTextFragment MOZ_FINAL {
    38 public:
    39   static nsresult Init();
    40   static void Shutdown();
    42   /**
    43    * Default constructor. Initialize the fragment to be empty.
    44    */
    45   nsTextFragment()
    46     : m1b(nullptr), mAllBits(0)
    47   {
    48     MOZ_COUNT_CTOR(nsTextFragment);
    49     NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!");
    50   }
    52   ~nsTextFragment();
    54   /**
    55    * Change the contents of this fragment to be a copy of the
    56    * the argument fragment, or to "" if unable to allocate enough memory.
    57    */
    58   nsTextFragment& operator=(const nsTextFragment& aOther);
    60   /**
    61    * Return true if this fragment is represented by char16_t data
    62    */
    63   bool Is2b() const
    64   {
    65     return mState.mIs2b;
    66   }
    68   /**
    69    * Return true if this fragment contains Bidi text
    70    * For performance reasons this flag is only set if explicitely requested (by
    71    * setting the aUpdateBidi argument on SetTo or Append to true).
    72    */
    73   bool IsBidi() const
    74   {
    75     return mState.mIsBidi;
    76   }
    78   /**
    79    * Get a pointer to constant char16_t data.
    80    */
    81   const char16_t *Get2b() const
    82   {
    83     NS_ASSERTION(Is2b(), "not 2b text"); 
    84     return m2b;
    85   }
    87   /**
    88    * Get a pointer to constant char data.
    89    */
    90   const char *Get1b() const
    91   {
    92     NS_ASSERTION(!Is2b(), "not 1b text"); 
    93     return (const char *)m1b;
    94   }
    96   /**
    97    * Get the length of the fragment. The length is the number of logical
    98    * characters, not the number of bytes to store the characters.
    99    */
   100   uint32_t GetLength() const
   101   {
   102     return mState.mLength;
   103   }
   105   bool CanGrowBy(size_t n) const
   106   {
   107     return n < (1 << 29) && mState.mLength + n < (1 << 29);
   108   }
   110   /**
   111    * Change the contents of this fragment to be a copy of the given
   112    * buffer. If aUpdateBidi is true, contents of the fragment will be scanned,
   113    * and mState.mIsBidi will be turned on if it includes any Bidi characters.
   114    */
   115   bool SetTo(const char16_t* aBuffer, int32_t aLength, bool aUpdateBidi);
   117   /**
   118    * Append aData to the end of this fragment. If aUpdateBidi is true, contents
   119    * of the fragment will be scanned, and mState.mIsBidi will be turned on if
   120    * it includes any Bidi characters.
   121    */
   122   bool Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBidi);
   124   /**
   125    * Append the contents of this string fragment to aString
   126    */
   127   void AppendTo(nsAString& aString) const {
   128     if (!AppendTo(aString, mozilla::fallible_t())) {
   129       NS_ABORT_OOM(GetLength());
   130     }
   131   }
   133   /**
   134    * Append the contents of this string fragment to aString
   135    * @return false if an out of memory condition is detected, true otherwise
   136    */
   137   bool AppendTo(nsAString& aString,
   138                 const mozilla::fallible_t&) const NS_WARN_UNUSED_RESULT {
   139     if (mState.mIs2b) {
   140       bool ok = aString.Append(m2b, mState.mLength, mozilla::fallible_t());
   141       if (!ok) {
   142         return false;
   143       }
   145       return true;
   146     } else {
   147       return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString,
   148                                 mozilla::fallible_t());
   149     }
   150   }
   152   /**
   153    * Append a substring of the contents of this string fragment to aString.
   154    * @param aOffset where to start the substring in this text fragment
   155    * @param aLength the length of the substring
   156    */
   157   void AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength) const {
   158     if (!AppendTo(aString, aOffset, aLength, mozilla::fallible_t())) {
   159       NS_ABORT_OOM(aLength);
   160     }
   161   }
   163   /**
   164    * Append a substring of the contents of this string fragment to aString.
   165    * @param aString the string in which to append
   166    * @param aOffset where to start the substring in this text fragment
   167    * @param aLength the length of the substring
   168    * @return false if an out of memory condition is detected, true otherwise
   169    */
   170   bool AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength,
   171                 const mozilla::fallible_t&) const NS_WARN_UNUSED_RESULT
   172   {
   173     if (mState.mIs2b) {
   174       bool ok = aString.Append(m2b + aOffset, aLength, mozilla::fallible_t());
   175       if (!ok) {
   176         return false;
   177       }
   179       return true;
   180     } else {
   181       return AppendASCIItoUTF16(Substring(m1b + aOffset, aLength), aString,
   182                                 mozilla::fallible_t());
   183     }
   184   }
   186   /**
   187    * Make a copy of the fragments contents starting at offset for
   188    * count characters. The offset and count will be adjusted to
   189    * lie within the fragments data. The fragments data is converted if
   190    * necessary.
   191    */
   192   void CopyTo(char16_t *aDest, int32_t aOffset, int32_t aCount);
   194   /**
   195    * Return the character in the text-fragment at the given
   196    * index. This always returns a char16_t.
   197    */
   198   char16_t CharAt(int32_t aIndex) const
   199   {
   200     NS_ASSERTION(uint32_t(aIndex) < mState.mLength, "bad index");
   201     return mState.mIs2b ? m2b[aIndex] : static_cast<unsigned char>(m1b[aIndex]);
   202   }
   204   struct FragmentBits {
   205     // uint32_t to ensure that the values are unsigned, because we
   206     // want 0/1, not 0/-1!
   207     // Making these bool causes Windows to not actually pack them,
   208     // which causes crashes because we assume this structure is no more than
   209     // 32 bits!
   210     uint32_t mInHeap : 1;
   211     uint32_t mIs2b : 1;
   212     uint32_t mIsBidi : 1;
   213     uint32_t mLength : 29;
   214   };
   216   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   218 private:
   219   void ReleaseText();
   221   /**
   222    * Scan the contents of the fragment and turn on mState.mIsBidi if it
   223    * includes any Bidi characters.
   224    */
   225   void UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength);
   227   union {
   228     char16_t *m2b;
   229     const char *m1b; // This is const since it can point to shared data
   230   };
   232   union {
   233     uint32_t mAllBits;
   234     FragmentBits mState;
   235   };
   236 };
   238 #endif /* nsTextFragment_h___ */

mercurial