Switch to using a flags argument instead of a boolean argument, per review comment.
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 03 May 2010 16:24:59 -0700
changeset 1553 a90c9f5a484093563543bc21cc9a3bad9e5dbdfb
parent 1552 c0f64cbcc93e673678dec0c6b0c5a1c1d58861cb
child 1554 7a792acb48c78defe41fb9f47813a3cd30344b7a
push id1251
push userdholbert@mozilla.com
push dateMon, 03 May 2010 23:25:04 +0000
Switch to using a flags argument instead of a boolean argument, per review comment.
tokenizer_allowSeparatorToBeOptional
tokenizer_fixOldUses
tokenizer_useInSVGAndSMIL
--- a/tokenizer_allowSeparatorToBeOptional
+++ b/tokenizer_allowSeparatorToBeOptional
@@ -1,38 +1,46 @@
 From: Daniel Holbert <dholbert@cs.stanford.edu>
 Bug 562310 Part 3: Extend nsCharSeparatedTokenizer to allow separator to be optional. r=NOT_REVIEWED_YET
 
 diff --git a/xpcom/ds/nsCharSeparatedTokenizer.h b/xpcom/ds/nsCharSeparatedTokenizer.h
 --- a/xpcom/ds/nsCharSeparatedTokenizer.h
 +++ b/xpcom/ds/nsCharSeparatedTokenizer.h
-@@ -55,18 +55,20 @@
+@@ -54,20 +54,28 @@
+  * "foo , bar hi , baz" -> "foo" "bar hi" "baz"
   * "foo, ,bar,baz" ->      "foo" "" "bar" "baz"
   * "foo,,bar,baz" ->       "foo" "" "bar" "baz"
   * "foo,bar,baz," ->       "foo" "bar" "baz"
   */
  class nsCharSeparatedTokenizer
  {
  public:
++    // Flags -- only one for now. If we need more, they should be defined to
++    // be 1<<1, 1<<2, etc. (They're masks, and aFlags/mFlags are bitfields.)
++    enum {
++        SEPARATOR_OPTIONAL = 1
++    };
++
      nsCharSeparatedTokenizer(const nsSubstring& aSource,
 -                             PRUnichar aSeparatorChar)
--        : mLastTokenEndedWithSeparator(PR_FALSE),
 +                             PRUnichar aSeparatorChar,
-+                             PRBool aIsSeparatorRequired)
-+        : mIsSeparatorRequired(aIsSeparatorRequired),
-+          mLastTokenEndedWithSeparator(PR_FALSE),
-           mSeparatorChar(aSeparatorChar)
++                             PRUint32  aFlags = 0)
+         : mLastTokenEndedWithSeparator(PR_FALSE),
+-          mSeparatorChar(aSeparatorChar)
++          mSeparatorChar(aSeparatorChar),
++          mFlags(aFlags)
      {
          aSource.BeginReading(mIter);
          aSource.EndReading(mEnd);
  
          // Skip initial whitespace
          while (mIter != mEnd && isWhitespace(*mIter)) {
              ++mIter;
-@@ -94,63 +96,76 @@ public:
+         }
+@@ -94,49 +102,62 @@ public:
       */
      const nsDependentSubstring nextToken()
      {
          nsSubstring::const_char_iterator end = mIter, begin = mIter;
  
          NS_ASSERTION(mIter == mEnd || !isWhitespace(*mIter),
                       "Should be at beginning of token if there is one");
  
@@ -46,28 +54,28 @@ diff --git a/xpcom/ds/nsCharSeparatedTok
                ++mIter;
            }
            end = mIter;
  
            // Skip whitespace after current word.
            while (mIter != mEnd && isWhitespace(*mIter)) {
                ++mIter;
            }
-+          if (!mIsSeparatorRequired) {
++          if (mFlags & SEPARATOR_OPTIONAL) {
 +            // We've hit (and skipped) whitespace, and that's sufficient to end
 +            // our token, regardless of whether we've reached a SeparatorChar.
 +            break;
 +          } // (else, we'll keep looping until we hit mEnd or SeparatorChar)
          }
 -        mLastTokenEndedWithSeparator = mIter != mEnd;
  
 -        // Skip separator (and any whitespace after it).
 +        mLastTokenEndedWithSeparator = (mIter != mEnd &&
 +                                        *mIter == mSeparatorChar);
-+        NS_ASSERTION(!mIsSeparatorRequired ||
++        NS_ASSERTION((mFlags & SEPARATOR_OPTIONAL) ||
 +                     (mLastTokenEndedWithSeparator == (mIter != mEnd)),
 +                     "If we require a separator and haven't hit the end of "
 +                     "our string, then we shouldn't have left the loop "
 +                     "unless we hit a separator");
 +
 +        // Skip separator (and any whitespace after it), if we're at one.
          if (mLastTokenEndedWithSeparator) {
 -            NS_ASSERTION(*mIter == mSeparatorChar, "Ended loop too soon");
@@ -78,34 +86,19 @@ diff --git a/xpcom/ds/nsCharSeparatedTok
              }
          }
          
          return Substring(begin, end);
      }
  
  private:
      nsSubstring::const_char_iterator mIter, mEnd;
-+    PRPackedBool mIsSeparatorRequired;
      PRPackedBool mLastTokenEndedWithSeparator;
      PRUnichar mSeparatorChar;
++    PRUint32  mFlags;
  
      PRBool isWhitespace(PRUnichar aChar)
      {
          return aChar <= ' ' &&
                 (aChar == ' ' || aChar == '\n' ||
                  aChar == '\r'|| aChar == '\t');
      }
  };
- 
- class nsCommaSeparatedTokenizer : public nsCharSeparatedTokenizer
- {
- public:
-     nsCommaSeparatedTokenizer(const nsSubstring& aSource)
--        : nsCharSeparatedTokenizer(aSource, ',') {}
-+        : nsCharSeparatedTokenizer(aSource, ',', PR_TRUE) {}
- };
- 
- 
- class nsCCommaSeparatedTokenizer
- {
- public:
-     nsCCommaSeparatedTokenizer(const nsCSubstring& aSource)
-     {
--- a/tokenizer_fixOldUses
+++ b/tokenizer_fixOldUses
@@ -9,17 +9,17 @@ diff --git a/content/html/content/src/ns
    if (NS_FAILED(rv))
      // Parameter not found or whatever
      return CANPLAY_MAYBE;
  
    CanPlayStatus result = CANPLAY_YES;
    // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
    // of the 'codecs' parameter
 -  nsCommaSeparatedTokenizer tokenizer(codecs);
-+  nsCharSeparatedTokenizer tokenizer(codecs, ',', PR_TRUE);
++  nsCharSeparatedTokenizer tokenizer(codecs, ',');
    PRBool expectMoreTokens = PR_FALSE;
    while (tokenizer.hasMoreTokens()) {
      const nsSubstring& token = tokenizer.nextToken();
  
      if (!CodecListContains(supportedCodecs, token)) {
        // Totally unsupported codec
        return CANPLAY_NO;
      }
@@ -31,22 +31,22 @@ diff --git a/content/svg/content/src/nsS
  
  /*static*/ PRBool
  nsSVGFeatures::MatchesLanguagePreferences(const nsSubstring& aAttribute,
                                            const nsSubstring& aAcceptLangs) 
  {
    const nsDefaultStringComparator defaultComparator;
  
 -  nsCommaSeparatedTokenizer attributeTokenizer(aAttribute);
-+  nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',', PR_TRUE);
++  nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',');
  
    while (attributeTokenizer.hasMoreTokens()) {
      const nsSubstring &attributeToken = attributeTokenizer.nextToken();
 -    nsCommaSeparatedTokenizer languageTokenizer(aAcceptLangs);
-+    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',', PR_TRUE);
++    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
      while (languageTokenizer.hasMoreTokens()) {
        if (nsStyleUtil::DashMatchCompare(attributeToken,
                                          languageTokenizer.nextToken(),
                                          defaultComparator)) {
          return PR_TRUE;
        }
      }
    }
@@ -55,48 +55,48 @@ diff --git a/content/svg/content/src/nsS
  
  /*static*/ PRInt32
  nsSVGFeatures::GetBestLanguagePreferenceRank(const nsSubstring& aAttribute,
                                               const nsSubstring& aAcceptLangs) 
  {
    const nsDefaultStringComparator defaultComparator;
  
 -  nsCommaSeparatedTokenizer attributeTokenizer(aAttribute);
-+  nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',', PR_TRUE);
++  nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',');
    PRInt32 lowestRank = -1;
  
    while (attributeTokenizer.hasMoreTokens()) {
      const nsSubstring &attributeToken = attributeTokenizer.nextToken();
 -    nsCommaSeparatedTokenizer languageTokenizer(aAcceptLangs);
-+    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',', PR_TRUE);
++    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
      PRInt32 index = 0;
      while (languageTokenizer.hasMoreTokens()) {
        const nsSubstring &languageToken = languageTokenizer.nextToken();
        PRBool exactMatch = (languageToken == attributeToken);
        PRBool prefixOnlyMatch =
          !exactMatch &&
          nsStyleUtil::DashMatchCompare(attributeToken,
                                        languageTokenizer.nextToken(),
 diff --git a/xpcom/ds/nsCharSeparatedTokenizer.h b/xpcom/ds/nsCharSeparatedTokenizer.h
 --- a/xpcom/ds/nsCharSeparatedTokenizer.h
 +++ b/xpcom/ds/nsCharSeparatedTokenizer.h
-@@ -151,24 +151,16 @@ private:
+@@ -157,24 +157,16 @@ private:
      PRBool isWhitespace(PRUnichar aChar)
      {
          return aChar <= ' ' &&
                 (aChar == ' ' || aChar == '\n' ||
                  aChar == '\r'|| aChar == '\t');
      }
  };
  
 -class nsCommaSeparatedTokenizer : public nsCharSeparatedTokenizer
 -{
 -public:
 -    nsCommaSeparatedTokenizer(const nsSubstring& aSource)
--        : nsCharSeparatedTokenizer(aSource, ',', PR_TRUE) {}
+-        : nsCharSeparatedTokenizer(aSource, ',') {}
 -};
 -
 -
  class nsCCommaSeparatedTokenizer
  {
  public:
      nsCCommaSeparatedTokenizer(const nsCSubstring& aSource)
      {
--- a/tokenizer_useInSVGAndSMIL
+++ b/tokenizer_useInSVGAndSMIL
@@ -62,17 +62,17 @@ diff --git a/content/smil/nsSMILParserUt
 -    while (substrEnd != start && NS_IS_SPACE(*(substrEnd-1)))
 -      --substrEnd;
 -
 -    rv = aParser.Parse(Substring(start, substrEnd));
 -    if (NS_FAILED(rv))
 -      break;
 -
 -    start = next;
-+  nsCharSeparatedTokenizer tokenizer(aSpec, ';', PR_TRUE);
++  nsCharSeparatedTokenizer tokenizer(aSpec, ';');
 +  if (!tokenizer.hasMoreTokens()) { // Empty list
 +    return NS_ERROR_FAILURE;
    }
  
 -  return rv;
 +  while (tokenizer.hasMoreTokens()) {
 +    nsresult rv = aParser.Parse(tokenizer.nextToken());
 +    if (NS_FAILED(rv)) {
@@ -220,17 +220,17 @@ diff --git a/content/svg/content/src/SVG
  
  namespace mozilla {
  
  //----------------------------------------------------------------------
  // PathGenerator methods
  
  // For the dummy 'from' value used in pure by-animation & to-animation
  void
-@@ -112,71 +112,48 @@ already_AddRefed<gfxFlattenedPath>
+@@ -112,71 +112,51 @@ already_AddRefed<gfxFlattenedPath>
  SVGMotionSMILPathUtils::PathGenerator::GetResultingPath()
  {
    return mGfxContext.GetFlattenedPath();
  }
  
  //----------------------------------------------------------------------
  // Helper / protected methods
  
@@ -261,59 +261,61 @@ diff --git a/content/svg/content/src/SVG
    ParseCoordinatePair(const nsAString& aCoordPairStr,
                        float& aXVal, float& aYVal)
  {
 -  nsSVGLength2 xLength, yLength;
 -  
 -  char* str = ToNewCString(aCoordPairStr);
 -  char* rest = str;
 -  PRBool success = PR_FALSE;
-+  nsCharSeparatedTokenizer tokenizer(aCoordPairStr, ',', PR_FALSE);
-+  nsSVGLength2 x, y;
-+  nsresult rv;
++  nsCharSeparatedTokenizer
++    tokenizer(aCoordPairStr, ',',
++              nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
  
 -  if (ParseOneCoordinate(&rest, xLength) &&
 -      ParseOneCoordinate(&rest, yLength)) {
-+  if (!tokenizer.hasMoreTokens()) { // No 1st token
-+    return PR_FALSE;
-+  }
-+  // Parse X value
-+  x.Init();
-+  rv = x.SetBaseValueString(tokenizer.nextToken(), nsnull, PR_FALSE);
-+  if (NS_FAILED(rv) ||                // 1st token failed to parse.
-+      !tokenizer.hasMoreTokens()) {   // No 2nd token.
-+    return PR_FALSE;
-+  }
++  nsSVGLength2 x, y;
++  nsresult rv;
  
 -    // Check for any non-whitespace characters remaining at the end.
 -    PRBool foundTrailingNonWhitespace = PR_FALSE;
 -    while (*rest != '\0') {
 -      if (!IsSVGWhitespace(*rest)) {
 -        foundTrailingNonWhitespace = PR_TRUE;
 -        break;
 -      }
 -    }
 -    if (!foundTrailingNonWhitespace) {
 -      success = PR_TRUE;
 -    }
++  if (!tokenizer.hasMoreTokens()) { // No 1st token
++    return PR_FALSE;
+   }
+-  nsMemory::Free(str);
++  // Parse X value
++  x.Init();
++  rv = x.SetBaseValueString(tokenizer.nextToken(), nsnull, PR_FALSE);
++  if (NS_FAILED(rv) ||                // 1st token failed to parse.
++      !tokenizer.hasMoreTokens()) {   // No 2nd token.
++    return PR_FALSE;
++  }
+ 
+-  if (success) {
+-    aXVal = xLength.GetBaseValue(mSVGElement);
+-    aYVal = yLength.GetBaseValue(mSVGElement);
 +  // Parse Y value
 +  y.Init();
 +  rv = y.SetBaseValueString(tokenizer.nextToken(), nsnull, PR_FALSE);
 +  if (NS_FAILED(rv) ||                           // 2nd token failed to parse.
 +      tokenizer.lastTokenEndedWithSeparator() || // Trailing comma.
 +      tokenizer.hasMoreTokens()) {               // More text remains
 +    return PR_FALSE;
    }
--  nsMemory::Free(str);
- 
--  if (success) {
--    aXVal = xLength.GetBaseValue(mSVGElement);
--    aYVal = yLength.GetBaseValue(mSVGElement);
--  }
 -  return success;
++
 +  aXVal = x.GetBaseValue(mSVGElement);
 +  aYVal = y.GetBaseValue(mSVGElement);
 +  return PR_TRUE;
  }
  
  //----------------------------------------------------------------------
  // MotionValueParser methods
  nsresult
@@ -359,27 +361,29 @@ diff --git a/content/svg/content/src/nsS
  #include "nsDOMError.h"
  #include "prdtoa.h"
  #include "nsReadableUtils.h"
  #include "nsTextFormatter.h"
  #include "nsCRT.h"
  #include "nsCOMArray.h"
  #include "nsContentUtils.h"
  
-@@ -158,66 +159,63 @@ NS_INTERFACE_MAP_END
+@@ -158,66 +159,65 @@ NS_INTERFACE_MAP_END
  
  
  //----------------------------------------------------------------------
  // nsISVGValue methods:
  
  NS_IMETHODIMP
  nsSVGPointList::SetValueString(const nsAString& aValue)
  {
 -  nsresult rv = NS_OK;
-+  nsCharSeparatedTokenizer tokenizer(aValue, ',', PR_FALSE);
++  nsCharSeparatedTokenizer
++    tokenizer(aValue, ',',
++              nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 +  nsCOMArray<nsIDOMSVGPoint> points;
  
 -  char* str = ToNewCString(aValue);
 -  
 -  char* rest = str;
 -  char* token1;
 -  char* token2;
 -  nsCOMArray<nsIDOMSVGPoint> points;
@@ -485,34 +489,36 @@ diff --git a/content/svg/content/src/nsS
  using namespace mozilla;
  
  /* Implementation of nsSVGViewBoxRect methods */
  
  PRBool
  nsSVGViewBoxRect::operator==(const nsSVGViewBoxRect& aOther) const
  {
    if (&aOther == this)
-@@ -135,47 +137,45 @@ nsSVGViewBox::SetBaseValue(float aX, flo
+@@ -135,47 +137,47 @@ nsSVGViewBox::SetBaseValue(float aX, flo
      aSVGElement->AnimationNeedsResample();
    }
  #endif
  }
  
  static nsresult
  ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
  {
 -  nsresult rv = NS_OK;
 -
 -  char *str = ToNewUTF8String(aStr);
 -
 -  char *rest = str;
 -  char *token;
 -
 -  float vals[4];
-+  nsCharSeparatedTokenizer tokenizer(aStr, ',', PR_FALSE);
++  nsCharSeparatedTokenizer
++    tokenizer(aStr, ',',
++              nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 +  float vals[NUM_VIEWBOX_COMPONENTS];
    PRUint32 i;
 -  for (i = 0; i < 4; ++i) {
 -    if (!(token = nsCRT::strtok(rest, SVG_COMMA_WSP_DELIM, &rest)))
 -      break; // parse error
 +  for (i = 0; i < NUM_VIEWBOX_COMPONENTS && tokenizer.hasMoreTokens(); ++i) {
 +    NS_ConvertUTF16toUTF8 utf8Token(tokenizer.nextToken());
 +    const char *token = utf8Token.get();