Bug 1431449 - Move nsTString::ToInteger* methods to nsTSubstring; r?bz draft
authorAnthony Ramine <n.oxyde@gmail.com>
Thu, 18 Jan 2018 15:32:35 +0100
changeset 722190 02ed4fbb2629b31cd0b571e4a8b75c21fa2ae647
parent 722189 3f49d37dcdb1e08f9ec08ff52a31e26ff1c12c44
child 722191 97e48fa65cbe3176a11d01951adcab332aab6f30
child 722332 a6cc15ad1aa6386b7875382bec577c24e0085ea4
push id96080
push userbmo:nox@mozilla.com
push dateThu, 18 Jan 2018 16:12:25 +0000
reviewersbz
bugs1431449
milestone59.0a1
Bug 1431449 - Move nsTString::ToInteger* methods to nsTSubstring; r?bz MozReview-Commit-ID: 8hCDfF8rLRC
xpcom/string/nsTString.h
xpcom/string/nsTStringObsolete.cpp
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
--- a/xpcom/string/nsTString.h
+++ b/xpcom/string/nsTString.h
@@ -372,33 +372,16 @@ public:
    * Perform string to single-precision float conversion.
    *
    * @param   aErrorCode will contain error if one occurs
    * @return  single-precision float rep of string value
    */
   float ToFloat(nsresult* aErrorCode) const;
 
   /**
-   * Perform string to int conversion.
-   * @param   aErrorCode will contain error if one occurs
-   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
-   * @return  int rep of string value, and possible (out) error code
-   */
-  int32_t ToInteger(nsresult* aErrorCode, uint32_t aRadix = 10) const;
-
-  /**
-   * Perform string to 64-bit int conversion.
-   * @param   aErrorCode will contain error if one occurs
-   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
-   * @return  64-bit int rep of string value, and possible (out) error code
-   */
-  int64_t ToInteger64(nsresult* aErrorCode, uint32_t aRadix = 10) const;
-
-
-  /**
    * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
    * any _other_ way than they are now.  Consider these alternatives
    *
    * aWritable = aReadable.Left(17);   // ...a member function that returns a |Substring|
    * aWritable = Left(aReadable, 17);  // ...a global function that returns a |Substring|
    * Left(aReadable, 17, aWritable);   // ...a global function that does the assignment
    *
    * as opposed to the current signature
--- a/xpcom/string/nsTStringObsolete.cpp
+++ b/xpcom/string/nsTStringObsolete.cpp
@@ -106,135 +106,16 @@ nsTString<T>::RFindCharInSet(const char_
     aOffset = this->mLength;
   else
     ++aOffset;
 
   return ::RFindCharInSet(this->mData, aOffset, aSet);
 }
 
 
-// Common logic for nsTString<T>::ToInteger and nsTString<T>::ToInteger64.
-template<typename T, typename int_type>
-int_type
-ToIntegerCommon(const nsTString<T>& aSrc, nsresult* aErrorCode, uint32_t aRadix)
-{
-  MOZ_ASSERT(aRadix == 10 || aRadix == 16);
-
-  // Initial value, override if we find an integer.
-  *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
-
-  // Begin by skipping over leading chars that shouldn't be part of the number.
-  auto cp = aSrc.BeginReading();
-  auto endcp = aSrc.EndReading();
-  bool negate = false;
-  bool done = false;
-
-  // NB: For backwards compatibility I'm not going to change this logic but
-  //     it seems really odd. Previously there was logic to auto-detect the
-  //     radix if kAutoDetect was passed in. In practice this value was never
-  //     used, so it pretended to auto detect and skipped some preceding
-  //     letters (excluding valid hex digits) but never used the result.
-  //
-  //     For example if you pass in "Get the number: 10", aRadix = 10 we'd
-  //     skip the 'G', and then fail to parse "et the number: 10". If aRadix =
-  //     16 we'd skip the 'G', and parse just 'e' returning 14.
-  while ((cp < endcp) && (!done)) {
-    switch (*cp++) {
-      // clang-format off
-      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-      case '0': case '1': case '2': case '3': case '4':
-      case '5': case '6': case '7': case '8': case '9':
-        done = true;
-        break;
-      // clang-format on
-      case '-':
-        negate = true;
-        break;
-      default:
-        break;
-    }
-  }
-
-  if (!done) {
-    // No base 16 or base 10 digits were found.
-    return 0;
-  }
-
-  // Step back.
-  cp--;
-
-  mozilla::CheckedInt<int_type> result;
-
-  // Now iterate the numeric chars and build our result.
-  while (cp < endcp) {
-    auto theChar = *cp++;
-    if (('0' <= theChar) && (theChar <= '9')) {
-      result = (aRadix * result) + (theChar - '0');
-    } else if ((theChar >= 'A') && (theChar <= 'F')) {
-      if (10 == aRadix) {
-        // Invalid base 10 digit, error out.
-        return 0;
-      } else {
-        result = (aRadix * result) + ((theChar - 'A') + 10);
-      }
-    } else if ((theChar >= 'a') && (theChar <= 'f')) {
-      if (10 == aRadix) {
-        // Invalid base 10 digit, error out.
-        return 0;
-      } else {
-        result = (aRadix * result) + ((theChar - 'a') + 10);
-      }
-    } else if ((('X' == theChar) || ('x' == theChar)) && result == 0) {
-      // For some reason we support a leading 'x' regardless of radix. For
-      // example: "000000x500", aRadix = 10 would be parsed as 500 rather
-      // than 0.
-      continue;
-    } else {
-      // We've encountered a char that's not a legal number or sign and we can
-      // terminate processing.
-      break;
-    }
-
-    if (!result.isValid()) {
-      // Overflow!
-      return 0;
-    }
-  }
-
-  // Integer found.
-  *aErrorCode = NS_OK;
-
-  if (negate) {
-    result = -result;
-  }
-
-  return result.value();
-}
-
-
-template <typename T>
-int32_t
-nsTString<T>::ToInteger(nsresult* aErrorCode, uint32_t aRadix) const
-{
-  return ToIntegerCommon<T, int32_t>(*this, aErrorCode, aRadix);
-}
-
-
-/**
- * nsTString::ToInteger64
- */
-template <typename T>
-int64_t
-nsTString<T>::ToInteger64(nsresult* aErrorCode, uint32_t aRadix) const
-{
-  return ToIntegerCommon<T, int64_t>(*this, aErrorCode, aRadix);
-}
-
-
 /**
    * nsTString::Mid
    */
 
 template <typename T>
 typename nsTString<T>::size_type
 nsTString<T>::Mid(self_type& aResult, index_type aStartPos, size_type aLengthToCopy) const
 {
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -1315,8 +1315,126 @@ nsTSubstring<T>::Split(const char_type a
 }
 
 template <typename T>
 const nsTDependentSubstring<T>&
 nsTSubstringSplitter<T>::nsTSubstringSplit_Iter::operator* () const
 {
    return mObj.Get(mPos);
 }
+
+// Common logic for nsTSubstring<T>::ToInteger and nsTSubstring<T>::ToInteger64.
+template<typename T, typename int_type>
+int_type
+ToIntegerCommon(const nsTSubstring<T>& aSrc, nsresult* aErrorCode, uint32_t aRadix)
+{
+  MOZ_ASSERT(aRadix == 10 || aRadix == 16);
+
+  // Initial value, override if we find an integer.
+  *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
+
+  // Begin by skipping over leading chars that shouldn't be part of the number.
+  auto cp = aSrc.BeginReading();
+  auto endcp = aSrc.EndReading();
+  bool negate = false;
+  bool done = false;
+
+  // NB: For backwards compatibility I'm not going to change this logic but
+  //     it seems really odd. Previously there was logic to auto-detect the
+  //     radix if kAutoDetect was passed in. In practice this value was never
+  //     used, so it pretended to auto detect and skipped some preceding
+  //     letters (excluding valid hex digits) but never used the result.
+  //
+  //     For example if you pass in "Get the number: 10", aRadix = 10 we'd
+  //     skip the 'G', and then fail to parse "et the number: 10". If aRadix =
+  //     16 we'd skip the 'G', and parse just 'e' returning 14.
+  while ((cp < endcp) && (!done)) {
+    switch (*cp++) {
+      // clang-format off
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+        done = true;
+        break;
+      // clang-format on
+      case '-':
+        negate = true;
+        break;
+      default:
+        break;
+    }
+  }
+
+  if (!done) {
+    // No base 16 or base 10 digits were found.
+    return 0;
+  }
+
+  // Step back.
+  cp--;
+
+  mozilla::CheckedInt<int_type> result;
+
+  // Now iterate the numeric chars and build our result.
+  while (cp < endcp) {
+    auto theChar = *cp++;
+    if (('0' <= theChar) && (theChar <= '9')) {
+      result = (aRadix * result) + (theChar - '0');
+    } else if ((theChar >= 'A') && (theChar <= 'F')) {
+      if (10 == aRadix) {
+        // Invalid base 10 digit, error out.
+        return 0;
+      } else {
+        result = (aRadix * result) + ((theChar - 'A') + 10);
+      }
+    } else if ((theChar >= 'a') && (theChar <= 'f')) {
+      if (10 == aRadix) {
+        // Invalid base 10 digit, error out.
+        return 0;
+      } else {
+        result = (aRadix * result) + ((theChar - 'a') + 10);
+      }
+    } else if ((('X' == theChar) || ('x' == theChar)) && result == 0) {
+      // For some reason we support a leading 'x' regardless of radix. For
+      // example: "000000x500", aRadix = 10 would be parsed as 500 rather
+      // than 0.
+      continue;
+    } else {
+      // We've encountered a char that's not a legal number or sign and we can
+      // terminate processing.
+      break;
+    }
+
+    if (!result.isValid()) {
+      // Overflow!
+      return 0;
+    }
+  }
+
+  // Integer found.
+  *aErrorCode = NS_OK;
+
+  if (negate) {
+    result = -result;
+  }
+
+  return result.value();
+}
+
+
+template <typename T>
+int32_t
+nsTSubstring<T>::ToInteger(nsresult* aErrorCode, uint32_t aRadix) const
+{
+  return ToIntegerCommon<T, int32_t>(*this, aErrorCode, aRadix);
+}
+
+
+/**
+ * nsTSubstring::ToInteger64
+ */
+template <typename T>
+int64_t
+nsTSubstring<T>::ToInteger64(nsresult* aErrorCode, uint32_t aRadix) const
+{
+  return ToIntegerCommon<T, int64_t>(*this, aErrorCode, aRadix);
+}
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -125,16 +125,32 @@ public:
   }
 
   char_iterator& EndWriting(char_iterator& aIter, const fallible_t& aFallible)
   {
     return aIter = EndWriting(aFallible);
   }
 
   /**
+   * Perform string to int conversion.
+   * @param   aErrorCode will contain error if one occurs
+   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
+   * @return  int rep of string value, and possible (out) error code
+   */
+  int32_t ToInteger(nsresult* aErrorCode, uint32_t aRadix = 10) const;
+
+  /**
+   * Perform string to 64-bit int conversion.
+   * @param   aErrorCode will contain error if one occurs
+   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
+   * @return  64-bit int rep of string value, and possible (out) error code
+   */
+  int64_t ToInteger64(nsresult* aErrorCode, uint32_t aRadix = 10) const;
+
+  /**
    * deprecated writing iterators
    */
 
   iterator& BeginWriting(iterator& aIter)
   {
     char_type* data = BeginWriting();
     aIter.mStart = data;
     aIter.mEnd = data + base_string_type::mLength;