Bug 1303273 part.8 UniCharsAndModifiers should use nsAutoString and AutoTArray to store characters and modifiers r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 07 Oct 2016 14:32:45 +0900
changeset 423632 aa6bebb9a677f147bad918cbb2d1ca1d51f65e83
parent 423631 2a9fdce27b77cbd4bed75cdd73275c2ec2bbfd7f
child 423633 af1de7480b4e8a344f9a585e05a0dfbce4c43423
push id31948
push usermasayuki@d-toybox.com
push dateTue, 11 Oct 2016 12:46:29 +0000
reviewersm_kato
bugs1303273
milestone52.0a1
Bug 1303273 part.8 UniCharsAndModifiers should use nsAutoString and AutoTArray to store characters and modifiers r?m_kato Fortunately, UniCharsAndModifiers instances are only in stack. Therefore, we can make it a stack class and use nsAutoString and AutoTArray for not using heap at handling inputs from usual keyboard layouts. MozReview-Commit-ID: 9ZPbdjGst64
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -911,81 +911,65 @@ ModifierKeyState::EnsureAltGr()
 
 /*****************************************************************************
  * mozilla::widget::UniCharsAndModifiers
  *****************************************************************************/
 
 void
 UniCharsAndModifiers::Append(char16_t aUniChar, Modifiers aModifiers)
 {
-  MOZ_ASSERT(mLength < 5);
-  mChars[mLength] = aUniChar;
-  mModifiers[mLength] = aModifiers;
-  mLength++;
+  mChars.Append(aUniChar);
+  mModifiers.AppendElement(aModifiers);
 }
 
 void
 UniCharsAndModifiers::FillModifiers(Modifiers aModifiers)
 {
-  for (size_t i = 0; i < mLength; i++) {
+  for (size_t i = 0; i < Length(); i++) {
     mModifiers[i] = aModifiers;
   }
 }
 
 void
 UniCharsAndModifiers::OverwriteModifiersIfBeginsWith(
                         const UniCharsAndModifiers& aOther)
 {
   if (!BeginsWith(aOther)) {
     return;
   }
-  for (size_t i = 0; i < aOther.mLength; ++i) {
+  for (size_t i = 0; i < aOther.Length(); ++i) {
     mModifiers[i] = aOther.mModifiers[i];
   }
 }
 
 bool
 UniCharsAndModifiers::UniCharsEqual(const UniCharsAndModifiers& aOther) const
 {
-  if (mLength != aOther.mLength) {
-    return false;
-  }
-  return !memcmp(mChars, aOther.mChars, mLength * sizeof(char16_t));
+  return mChars.Equals(aOther.mChars);
 }
 
 bool
 UniCharsAndModifiers::UniCharsCaseInsensitiveEqual(
                         const UniCharsAndModifiers& aOther) const
 {
-  if (mLength != aOther.mLength) {
-    return false;
-  }
-
   nsCaseInsensitiveStringComparator comp;
-  return !comp(mChars, aOther.mChars, mLength, aOther.mLength);
+  return mChars.Equals(aOther.mChars, comp);
 }
 
 bool
 UniCharsAndModifiers::BeginsWith(const UniCharsAndModifiers& aOther) const
 {
-  if (mLength < aOther.mLength) {
-    return false;
-  }
-  return !memcmp(mChars, aOther.mChars, aOther.mLength * sizeof(char16_t));
+  return StringBeginsWith(mChars, aOther.mChars);
 }
 
 UniCharsAndModifiers&
 UniCharsAndModifiers::operator+=(const UniCharsAndModifiers& aOther)
 {
-  uint32_t copyCount = std::min(aOther.mLength, 5 - mLength);
-  NS_ENSURE_TRUE(copyCount > 0, *this);
-  memcpy(&mChars[mLength], aOther.mChars, copyCount * sizeof(char16_t));
-  memcpy(&mModifiers[mLength], aOther.mModifiers,
-         copyCount * sizeof(Modifiers));
-  mLength += copyCount;
+  mChars.Append(aOther.mChars);
+  mModifiers.AppendElements(aOther.mModifiers);
   return *this;
 }
 
 UniCharsAndModifiers
 UniCharsAndModifiers::operator+(const UniCharsAndModifiers& aOther) const
 {
   UniCharsAndModifiers result(*this);
   result += aOther;
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -52,60 +52,72 @@ static const uint32_t sModifierKeyMap[][
   { nsIWidget::CTRL_L,    VK_CONTROL, VK_LCONTROL },
   { nsIWidget::CTRL_R,    VK_CONTROL, VK_RCONTROL },
   { nsIWidget::ALT_L,     VK_MENU,    VK_LMENU },
   { nsIWidget::ALT_R,     VK_MENU,    VK_RMENU }
 };
 
 class KeyboardLayout;
 
-class UniCharsAndModifiers final
+class MOZ_STACK_CLASS UniCharsAndModifiers final
 {
 public:
-  UniCharsAndModifiers() : mLength(0) {}
+  UniCharsAndModifiers() {}
   UniCharsAndModifiers operator+(const UniCharsAndModifiers& aOther) const;
   UniCharsAndModifiers& operator+=(const UniCharsAndModifiers& aOther);
 
   /**
    * Append a pair of unicode character and the final modifier.
    */
   void Append(char16_t aUniChar, Modifiers aModifiers);
-  void Clear() { mLength = 0; }
-  bool IsEmpty() const { return !mLength; }
+  void Clear()
+  {
+    mChars.Truncate();
+    mModifiers.Clear();
+  }
+  bool IsEmpty() const
+  {
+    MOZ_ASSERT(mChars.Length() == mModifiers.Length());
+    return mChars.IsEmpty();
+  }
 
   char16_t CharAt(size_t aIndex) const
   {
-    MOZ_ASSERT(aIndex < mLength);
+    MOZ_ASSERT(aIndex < Length());
     return mChars[aIndex];
   }
   Modifiers ModifiersAt(size_t aIndex) const
   {
-    MOZ_ASSERT(aIndex < mLength);
+    MOZ_ASSERT(aIndex < Length());
     return mModifiers[aIndex];
   }
-  size_t Length() const { return mLength; }
+  size_t Length() const
+  {
+    MOZ_ASSERT(mChars.Length() == mModifiers.Length());
+    return mChars.Length();
+  }
 
   void FillModifiers(Modifiers aModifiers);
   /**
    * OverwriteModifiersIfBeginsWith() assigns mModifiers with aOther between
    * [0] and [aOther.mLength - 1] only when mChars begins with aOther.mChars.
    */
   void OverwriteModifiersIfBeginsWith(const UniCharsAndModifiers& aOther);
 
   bool UniCharsEqual(const UniCharsAndModifiers& aOther) const;
   bool UniCharsCaseInsensitiveEqual(const UniCharsAndModifiers& aOther) const;
   bool BeginsWith(const UniCharsAndModifiers& aOther) const;
 
-  nsString ToString() const { return nsString(mChars, mLength); }
+  const nsString& ToString() const { return mChars; }
 
 private:
-  // Dead-key + up to 4 characters
-  char16_t mChars[5];
-  Modifiers mModifiers[5];
-  size_t mLength;
+  nsAutoString mChars;
+  // 5 is enough number for normal keyboard layout handling.  On Windows,
+  // a dead key sequence may cause inputting up to 5 characters per key press.
+  AutoTArray<Modifiers, 5> mModifiers;
 };
 
 struct DeadKeyEntry;
 class DeadKeyTable;
 
 
 class VirtualKey
 {