update copy_string() to the single-fragment string world, and optimize write() to not return a value. b=282083, r+sr=jst, a=schrep
authordwitte@stanford.edu
Thu, 03 Jan 2008 16:07:06 -0800
changeset 9792 54b0419450006f5beda6102c6a6796bdc3bd4db5
parent 9791 c58f24fa4cea721c52b52df2bc453d7a2594a4e7
child 9793 1a1565c6124cc34d6b9ec479bb217bfc738d831c
push idunknown
push userunknown
push dateunknown
reviewersschrep
bugs282083
milestone1.9b3pre
update copy_string() to the single-fragment string world, and optimize write() to not return a value. b=282083, r+sr=jst, a=schrep
content/base/src/nsContentUtils.cpp
content/xslt/src/base/txDouble.cpp
content/xslt/src/base/txStringUtils.cpp
parser/htmlparser/src/nsScannerString.cpp
toolkit/xre/nsWindowsRestart.cpp
toolkit/xre/nsWindowsWMain.cpp
xpcom/string/public/nsAlgorithm.h
xpcom/string/public/nsCharTraits.h
xpcom/string/public/nsStringIterator.h
xpcom/string/public/nsUTF8Utils.h
xpcom/string/src/nsReadableUtils.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -574,17 +574,17 @@ class CopyNormalizeNewlines
     PRUint32 GetCharsWritten() {
       return mWritten;
     }
 
     PRBool IsLastCharCR() {
       return mLastCharCR;
     }
 
-    PRUint32 write(const typename OutputIterator::value_type* aSource, PRUint32 aSourceLength) {
+    void write(const typename OutputIterator::value_type* aSource, PRUint32 aSourceLength) {
 
       const typename OutputIterator::value_type* done_writing = aSource + aSourceLength;
 
       // If the last source buffer ended with a CR...
       if (mLastCharCR) {
         // ..and if the next one is a LF, then skip it since
         // we've already written out a newline
         if (aSourceLength && (*aSource == value_type('\n'))) {
@@ -610,17 +610,16 @@ class CopyNormalizeNewlines
         }
         else {
           mDestination->writechar(*aSource++);
         }
         ++num_written;
       }
 
       mWritten += num_written;
-      return aSourceLength;
     }
 
   private:
     PRBool mLastCharCR;
     OutputIterator* mDestination;
     PRUint32 mWritten;
 };
 
--- a/content/xslt/src/base/txDouble.cpp
+++ b/content/xslt/src/base/txDouble.cpp
@@ -95,21 +95,21 @@ MBool Double::isNeg(double aDbl)
  */
 class txStringToDouble
 {
 public:
     typedef PRUnichar input_type;
     typedef PRUnichar value_type;
     txStringToDouble(): mState(eWhitestart), mSign(ePositive) {}
 
-    PRUint32
+    void
     write(const input_type* aSource, PRUint32 aSourceLength)
     {
         if (mState == eIllegal) {
-            return aSourceLength;
+            return;
         }
         PRUint32 i = 0;
         PRUnichar c;
         for ( ; i < aSourceLength; ++i) {
             c = aSource[i];
             switch (mState) {
                 case eWhitestart:
                     if (c == '-') {
@@ -121,33 +121,33 @@ public:
                         mBuffer.Append((char)c);
                     }
                     else if (c == '.') {
                         mState = eMantissa;
                         mBuffer.Append((char)c);
                     }
                     else if (!XMLUtils::isWhitespace(c)) {
                         mState = eIllegal;
-                        return aSourceLength;
+                        return;
                     }
                     break;
                 case eDecimal:
                     if (c >= '0' && c <= '9') {
                         mBuffer.Append((char)c);
                     }
                     else if (c == '.') {
                         mState = eMantissa;
                         mBuffer.Append((char)c);
                     }
                     else if (XMLUtils::isWhitespace(c)) {
                         mState = eWhiteend;
                     }
                     else {
                         mState = eIllegal;
-                        return aSourceLength;
+                        return;
                     }
                     break;
                 case eMantissa:
                     if (c >= '0' && c <= '9') {
                         mBuffer.Append((char)c);
                     }
                     else if (XMLUtils::isWhitespace(c)) {
                         mState = eWhiteend;
@@ -155,24 +155,23 @@ public:
                     else {
                         mState = eIllegal;
                         return aSourceLength;
                     }
                     break;
                 case eWhiteend:
                     if (!XMLUtils::isWhitespace(c)) {
                         mState = eIllegal;
-                        return aSourceLength;
+                        return;
                     }
                     break;
                 default:
                     break;
             }
         }
-        return aSourceLength;
     }
 
     double
     getDouble()
     {
         if (mState == eIllegal || mBuffer.IsEmpty() ||
             (mBuffer.Length() == 1 && mBuffer[0] == '.')) {
             return Double::NaN;
--- a/content/xslt/src/base/txStringUtils.cpp
+++ b/content/xslt/src/base/txStringUtils.cpp
@@ -81,27 +81,26 @@ txCaseInsensitiveStringComparator::opera
 /**
  * A character sink for case conversion.
  */
 class ConvertToLowerCase
 {
 public:
   typedef PRUnichar value_type;
 
-  PRUint32 write( const PRUnichar* aSource, PRUint32 aSourceLength)
+  void write( const PRUnichar* aSource, PRUint32 aSourceLength)
   {
     PRUnichar* cp = const_cast<PRUnichar*>(aSource);
     const PRUnichar* end = aSource + aSourceLength;
     while (cp != end) {
       PRUnichar ch = *cp;
       if ((ch >= 'A') && (ch <= 'Z'))
         *cp = ch + ('a' - 'A');
       ++cp;
     }
-    return aSourceLength;
   }
 };
 
 void TX_ToLowerCase(nsAString& aString)
 {
   nsAString::iterator fromBegin, fromEnd;
   ConvertToLowerCase converter;
   copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd),
@@ -115,32 +114,31 @@ class CopyToLowerCase
 {
 public:
   typedef PRUnichar value_type;
 
   CopyToLowerCase(nsAString::iterator& aDestIter) : mIter(aDestIter)
   {
   }
 
-  PRUint32 write(const PRUnichar* aSource, PRUint32 aSourceLength)
+  void write(const PRUnichar* aSource, PRUint32 aSourceLength)
   {
     PRUint32 len = PR_MIN(PRUint32(mIter.size_forward()), aSourceLength);
     PRUnichar* cp = mIter.get();
     const PRUnichar* end = aSource + len;
     while (aSource != end) {
       PRUnichar ch = *aSource;
       if ((ch >= 'A') && (ch <= 'Z'))
         *cp = ch + ('a' - 'A');
       else
         *cp = ch;
       ++aSource;
       ++cp;
     }
     mIter.advance(len);
-    return len;
   }
 
 protected:
   nsAString::iterator& mIter;
 };
 
 void TX_ToLowerCase(const nsAString& aSource, nsAString& aDest)
 {
--- a/parser/htmlparser/src/nsScannerString.cpp
+++ b/parser/htmlparser/src/nsScannerString.cpp
@@ -478,30 +478,49 @@ nsScannerSharedSubstring::MakeMutable()
   mBuffer = nsnull;
   mBufferList = nsnull;
 }
 
   /**
    * utils -- based on code from nsReadableUtils.cpp
    */
 
+// private helper function
+static inline
+nsAString::iterator&
+copy_multifragment_string( nsScannerIterator& first, const nsScannerIterator& last, nsAString::iterator& result )
+  {
+    typedef nsCharSourceTraits<nsScannerIterator> source_traits;
+    typedef nsCharSinkTraits<nsAString::iterator> sink_traits;
+
+    while ( first != last )
+      {
+        PRUint32 distance = source_traits::readable_distance(first, last);
+        sink_traits::write(result, source_traits::read(first), distance);
+        NS_ASSERTION(distance > 0, "|copy_multifragment_string| will never terminate");
+        source_traits::advance(first, distance);
+      }
+
+    return result;
+  }
+
 void
 CopyUnicodeTo( const nsScannerIterator& aSrcStart,
                const nsScannerIterator& aSrcEnd,
                nsAString& aDest )
   {
     nsAString::iterator writer;
     if (!EnsureStringLength(aDest, Distance(aSrcStart, aSrcEnd))) {
       aDest.Truncate();
       return; // out of memory
     }
     aDest.BeginWriting(writer);
     nsScannerIterator fromBegin(aSrcStart);
     
-    copy_string(fromBegin, aSrcEnd, writer);
+    copy_multifragment_string(fromBegin, aSrcEnd, writer);
   }
 
 void
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsScannerSharedSubstring& aDest )
   {
     // Check whether we can just create a dependent string.
@@ -522,17 +541,17 @@ AppendUnicodeTo( const nsScannerIterator
   {
     nsAString::iterator writer;
     PRUint32 oldLength = aDest.Length();
     if (!EnsureStringLength(aDest, oldLength + Distance(aSrcStart, aSrcEnd)))
       return; // out of memory
     aDest.BeginWriting(writer).advance(oldLength);
     nsScannerIterator fromBegin(aSrcStart);
     
-    copy_string(fromBegin, aSrcEnd, writer);
+    copy_multifragment_string(fromBegin, aSrcEnd, writer);
   }
 
 PRBool
 FindCharInReadable( PRUnichar aChar,
                     nsScannerIterator& aSearchStart,
                     const nsScannerIterator& aSearchEnd )
   {
     while ( aSearchStart != aSearchEnd )
--- a/toolkit/xre/nsWindowsRestart.cpp
+++ b/toolkit/xre/nsWindowsRestart.cpp
@@ -229,17 +229,17 @@ AllocConvertUTF8toUTF16(const char *arg)
 {
   // UTF16 can't be longer in units than UTF8
   int len = strlen(arg);
   PRUnichar *s = new PRUnichar[(len + 1) * sizeof(PRUnichar)];
   if (!s)
     return NULL;
 
   ConvertUTF8toUTF16 convert(s);
-  len = convert.write(arg, len);
+  convert.write(arg, len);
   s[len] = '\0';
   return s;
 }
 
 static void
 FreeAllocStrings(int argc, PRUnichar **argv)
 {
   while (argc) {
--- a/toolkit/xre/nsWindowsWMain.cpp
+++ b/toolkit/xre/nsWindowsWMain.cpp
@@ -17,17 +17,17 @@ AllocConvertUTF16toUTF8(const WCHAR *arg
 {
   // be generous... UTF16 units can expand up to 3 UTF8 units
   int len = wcslen(arg);
   char *s = new char[len * 3 + 1];
   if (!s)
     return NULL;
 
   ConvertUTF16toUTF8 convert(s);
-  len = convert.write(arg, len);
+  convert.write(arg, len);
   s[len] = '\0';
   return s;
 }
 
 static void
 FreeAllocStrings(int argc, char **argv)
 {
   while (argc) {
--- a/xpcom/string/public/nsAlgorithm.h
+++ b/xpcom/string/public/nsAlgorithm.h
@@ -80,52 +80,18 @@ NS_COUNT( InputIterator& first, const In
       if ( *first == value )
         ++result;
     return result;
   }
 
 template <class InputIterator, class OutputIterator>
 inline
 OutputIterator&
-copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result )
+copy_string( const InputIterator& first, const InputIterator& last, OutputIterator& result )
   {
     typedef nsCharSourceTraits<InputIterator> source_traits;
     typedef nsCharSinkTraits<OutputIterator>  sink_traits;
 
-    while ( first != last )
-      {
-        PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last)));
-        NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate");
-        source_traits::advance(first, count_copied);
-      }
-
-    return result;
-  }
-
-template <class InputIterator, class OutputIterator>
-OutputIterator&
-copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result )
-  {
-    while ( first != last )
-      {
-        last.normalize_backward();
-        result.normalize_backward();
-        PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
-        if ( first.fragment().mStart == last.fragment().mStart )
-          lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.get() - first.get()));
-
-        NS_ASSERTION(lengthToCopy, "|copy_string_backward| will never terminate");
-
-#ifdef _MSC_VER
-        // XXX Visual C++ can't stomach 'typename' where it rightfully should
-        nsCharTraits<OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
-#else
-        nsCharTraits<typename OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
-#endif
-
-        last.advance( -PRInt32(lengthToCopy) );
-        result.advance( -PRInt32(lengthToCopy) );
-      }
-
+    sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last));
     return result;
   }
 
 #endif // !defined(nsAlgorithm_h___)
--- a/xpcom/string/public/nsCharTraits.h
+++ b/xpcom/string/public/nsCharTraits.h
@@ -793,61 +793,58 @@ struct nsCharSourceTraits<const PRUnicha
 
 #endif
 
 
 template <class OutputIterator>
 struct nsCharSinkTraits
   {
     static
-    PRUint32
+    void
     write( OutputIterator& iter, const typename OutputIterator::value_type* s, PRUint32 n )
       {
-        return iter.write(s, n);
+        iter.write(s, n);
       }
   };
 
 #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
 
 template <class CharT>
 struct nsCharSinkTraits<CharT*>
   {
     static
-    PRUint32
+    void
     write( CharT*& iter, const CharT* s, PRUint32 n )
       {
         nsCharTraits<CharT>::move(iter, s, n);
         iter += n;
-        return n;
       }
   };
 
 #else
 
 NS_SPECIALIZE_TEMPLATE
 struct nsCharSinkTraits<char*>
   {
     static
-    PRUint32
+    void
     write( char*& iter, const char* s, PRUint32 n )
       {
         nsCharTraits<char>::move(iter, s, n);
         iter += n;
-        return n;
       }
   };
 
 NS_SPECIALIZE_TEMPLATE
 struct nsCharSinkTraits<PRUnichar*>
   {
     static
-    PRUint32
+    void
     write( PRUnichar*& iter, const PRUnichar* s, PRUint32 n )
       {
         nsCharTraits<PRUnichar>::move(iter, s, n);
         iter += n;
-        return n;
       }
   };
 
 #endif
 
 #endif // !defined(nsCharTraits_h___)
--- a/xpcom/string/public/nsStringIterator.h
+++ b/xpcom/string/public/nsStringIterator.h
@@ -321,24 +321,23 @@ class nsWritingIterator
 
               NS_ASSERTION(step<0, "can't advance (backward) a writing iterator beyond the end of a string");
 
               mPosition += step;
             }
           return *this;
         }
 
-      PRUint32
+      void
       write( const value_type* s, PRUint32 n )
         {
           NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!");
 
           nsCharTraits<value_type>::move(mPosition, s, n);
           advance( difference_type(n) );
-          return n;
         }
   };
 
 template <class CharT>
 inline
 PRBool
 operator==( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs )
   {
--- a/xpcom/string/public/nsUTF8Utils.h
+++ b/xpcom/string/public/nsUTF8Utils.h
@@ -462,37 +462,37 @@ class ConvertUTF8toUTF16
       typedef char      value_type;
       typedef PRUnichar buffer_type;
 
     ConvertUTF8toUTF16( buffer_type* aBuffer )
         : mStart(aBuffer), mBuffer(aBuffer), mErrorEncountered(PR_FALSE) {}
 
     size_t Length() const { return mBuffer - mStart; }
 
-    PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+    void NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
       {
         if ( mErrorEncountered )
-          return N;
+          return;
 
         // algorithm assumes utf8 units won't
         // be spread across fragments
         const value_type* p = start;
         const value_type* end = start + N;
         buffer_type* out = mBuffer;
         for ( ; p != end /* && *p */; )
           {
             PRBool overlong, err;
             PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&p, end, &err,
                                                          &overlong);
 
             if ( err )
               {
                 mErrorEncountered = PR_TRUE;
                 mBuffer = out;
-                return N;
+                return;
               }
 
             if ( overlong )
               {
                 // Overlong sequence
                 *out++ = UCS2_REPLACEMENT_CHAR;
               }
             else if ( ucs4 <= 0xD7FF )
@@ -519,17 +519,16 @@ class ConvertUTF8toUTF16
                 }
               }
             else
               {
                 *out++ = ucs4;
               }
           }
         mBuffer = out;
-        return p - start;
       }
 
     void write_terminator()
       {
         *mBuffer = buffer_type(0);
       }
 
     private:
@@ -546,21 +545,21 @@ class CalculateUTF8Length
   {
     public:
       typedef char value_type;
 
     CalculateUTF8Length() : mLength(0), mErrorEncountered(PR_FALSE) { }
 
     size_t Length() const { return mLength; }
 
-    PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+    void NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
       {
           // ignore any further requests
         if ( mErrorEncountered )
-            return N;
+            return;
 
         // algorithm assumes utf8 units won't
         // be spread across fragments
         const value_type* p = start;
         const value_type* end = start + N;
         for ( ; p < end /* && *p */; ++mLength )
           {
             if ( UTF8traits::isASCII(*p) )
@@ -591,19 +590,17 @@ class CalculateUTF8Length
               {
                 break;
               }
           }
         if ( p != end )
           {
             NS_ERROR("Not a UTF-8 string. This code should only be used for converting from known UTF-8 strings.");
             mErrorEncountered = PR_TRUE;
-            return N;
           }
-        return p - start;
       }
 
     private:
       size_t mLength;
       PRBool mErrorEncountered;
   };
 
 /**
@@ -621,17 +618,17 @@ class ConvertUTF16toUTF8
     // |ConvertUTF8toUTF16|, but it's that way for backwards
     // compatibility.
 
     ConvertUTF16toUTF8( buffer_type* aBuffer )
         : mStart(aBuffer), mBuffer(aBuffer) {}
 
     size_t Size() const { return mBuffer - mStart; }
 
-    PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+    void NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
       {
         buffer_type *out = mBuffer; // gcc isn't smart enough to do this!
 
         for (const value_type *p = start, *end = start + N; p < end; ++p )
           {
             value_type c = *p;
             if (! (c & 0xFF80)) // U+0000 - U+007F
               {
@@ -702,17 +699,16 @@ class ConvertUTF16toUTF8
                 *out++ = 0xBD;
 
                 // DC00- DFFF - Low Surrogate
                 NS_WARNING("got a low Surrogate but no high surrogate");
               }
           }
 
         mBuffer = out;
-        return N;
       }
 
     void write_terminator()
       {
         *mBuffer = buffer_type(0);
       }
 
     private:
@@ -730,17 +726,17 @@ class CalculateUTF8Size
     public:
       typedef PRUnichar value_type;
 
     CalculateUTF8Size()
       : mSize(0) { }
 
     size_t Size() const { return mSize; }
 
-    PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+    void NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
       {
         // Assume UCS2 surrogate pairs won't be spread across fragments.
         for (const value_type *p = start, *end = start + N; p < end; ++p )
           {
             value_type c = *p;
             if (! (c & 0xFF80)) // U+0000 - U+007F
               mSize += 1;
             else if (! (c & 0xF800)) // U+0100 - U+07FF
@@ -779,18 +775,16 @@ class CalculateUTF8Size
               {
                 // Treat broken characters as the Unicode replacement
                 // character 0xFFFD (0xEFBFBD in UTF-8)
                 mSize += 3;
 
                 NS_WARNING("got a low Surrogate but no high surrogate");
               }
           }
-
-        return N;
       }
 
     private:
       size_t mSize;
   };
 
 #ifdef MOZILLA_INTERNAL_API
 /**
@@ -806,23 +800,22 @@ class LossyConvertEncoding
       typedef FromCharT input_type;
       typedef ToCharT   output_type;
 
       typedef typename nsCharTraits<FromCharT>::unsigned_char_type unsigned_input_type;
 
     public:
       LossyConvertEncoding( output_type* aDestination ) : mDestination(aDestination) { }
 
-      PRUint32
+      void
       write( const input_type* aSource, PRUint32 aSourceLength )
         {
           const input_type* done_writing = aSource + aSourceLength;
           while ( aSource < done_writing )
             *mDestination++ = (output_type)(unsigned_input_type)(*aSource++);  // use old-style cast to mimic old |ns[C]String| behavior
-          return aSourceLength;
         }
 
       void
       write_terminator()
         {
           *mDestination = output_type(0);
         }
 
--- a/xpcom/string/src/nsReadableUtils.cpp
+++ b/xpcom/string/src/nsReadableUtils.cpp
@@ -493,62 +493,52 @@ NS_COM
 PRBool
 IsASCII( const nsAString& aString )
   {
     static const PRUnichar NOT_ASCII = PRUnichar(~0x007F);
 
 
     // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character
 
-    nsAString::const_iterator done_reading;
+    nsAString::const_iterator iter, done_reading;
+    aString.BeginReading(iter);
     aString.EndReading(done_reading);
 
-      // for each chunk of |aString|...
-    PRUint32 fragmentLength = 0;
-    nsAString::const_iterator iter;
-    for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+    const PRUnichar* c = iter.get();
+    const PRUnichar* end = done_reading.get();
+    
+    while ( c < end )
       {
-        fragmentLength = PRUint32(iter.size_forward());
-        const PRUnichar* c = iter.get();
-        const PRUnichar* fragmentEnd = c + fragmentLength;
-
-          // for each character in this chunk...
-        while ( c < fragmentEnd )
-          if ( *c++ & NOT_ASCII )
-            return PR_FALSE;
+        if ( *c++ & NOT_ASCII )
+          return PR_FALSE;
       }
 
     return PR_TRUE;
   }
 
 NS_COM
 PRBool
 IsASCII( const nsACString& aString )
   {
     static const char NOT_ASCII = char(~0x7F);
 
 
     // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character
 
-    nsACString::const_iterator done_reading;
+    nsACString::const_iterator iter, done_reading;
+    aString.BeginReading(iter);
     aString.EndReading(done_reading);
 
-      // for each chunk of |aString|...
-    PRUint32 fragmentLength = 0;
-    nsACString::const_iterator iter;
-    for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+    const char* c = iter.get();
+    const char* end = done_reading.get();
+    
+    while ( c < end )
       {
-        fragmentLength = PRUint32(iter.size_forward());
-        const char* c = iter.get();
-        const char* fragmentEnd = c + fragmentLength;
-
-          // for each character in this chunk...
-        while ( c < fragmentEnd )
-          if ( *c++ & NOT_ASCII )
-            return PR_FALSE;
+        if ( *c++ & NOT_ASCII )
+          return PR_FALSE;
       }
 
     return PR_TRUE;
   }
 
 NS_COM
 PRBool
 IsUTF8( const nsACString& aString )
@@ -558,95 +548,88 @@ IsUTF8( const nsACString& aString )
 
     PRInt32 state = 0;
     PRBool overlong = PR_FALSE;
     PRBool surrogate = PR_FALSE;
     PRBool nonchar = PR_FALSE;
     PRUint16 olupper = 0; // overlong byte upper bound.
     PRUint16 slower = 0;  // surrogate byte lower bound.
 
-      // for each chunk of |aString|...
-    PRUint32 fragmentLength = 0;
     nsReadingIterator<char> iter;
+    aString.BeginReading(iter);
 
-    for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+    const char* ptr = iter.get();
+    const char* end = done_reading.get();
+    while ( ptr < end )
       {
-        fragmentLength = PRUint32(iter.size_forward());
-        const char* ptr = iter.get();
-        const char* fragmentEnd = ptr + fragmentLength;
-
-          // for each character in this chunk...
-        while ( ptr < fragmentEnd )
+        PRUint8 c;
+        
+        if (0 == state)
           {
-            PRUint8 c;
-            
-            if (0 == state)
-              {
-                c = *ptr++;
+            c = *ptr++;
+
+            if ( UTF8traits::isASCII(c) ) 
+              continue;
 
-                if ( UTF8traits::isASCII(c) ) 
-                  continue;
-
-                if ( c <= 0xC1 ) // [80-BF] where not expected, [C0-C1] for overlong.
-                  return PR_FALSE;
-                else if ( UTF8traits::is2byte(c) ) 
-                    state = 1;
-                else if ( UTF8traits::is3byte(c) ) 
+            if ( c <= 0xC1 ) // [80-BF] where not expected, [C0-C1] for overlong.
+              return PR_FALSE;
+            else if ( UTF8traits::is2byte(c) ) 
+                state = 1;
+            else if ( UTF8traits::is3byte(c) ) 
+              {
+                state = 2;
+                if ( c == 0xE0 ) // to exclude E0[80-9F][80-BF] 
+                  {
+                    overlong = PR_TRUE;
+                    olupper = 0x9F;
+                  }
+                else if ( c == 0xED ) // ED[A0-BF][80-BF] : surrogate codepoint
                   {
-                    state = 2;
-                    if ( c == 0xE0 ) // to exclude E0[80-9F][80-BF] 
-                      {
-                        overlong = PR_TRUE;
-                        olupper = 0x9F;
-                      }
-                    else if ( c == 0xED ) // ED[A0-BF][80-BF] : surrogate codepoint
-                      {
-                        surrogate = PR_TRUE;
-                        slower = 0xA0;
-                      }
-                    else if ( c == 0xEF ) // EF BF [BE-BF] : non-character
-                      nonchar = PR_TRUE;
+                    surrogate = PR_TRUE;
+                    slower = 0xA0;
                   }
-                else if ( c <= 0xF4 ) // XXX replace /w UTF8traits::is4byte when it's updated to exclude [F5-F7].(bug 199090)
+                else if ( c == 0xEF ) // EF BF [BE-BF] : non-character
+                  nonchar = PR_TRUE;
+              }
+            else if ( c <= 0xF4 ) // XXX replace /w UTF8traits::is4byte when it's updated to exclude [F5-F7].(bug 199090)
+              {
+                state = 3;
+                nonchar = PR_TRUE;
+                if ( c == 0xF0 ) // to exclude F0[80-8F][80-BF]{2}
+                  {
+                    overlong = PR_TRUE;
+                    olupper = 0x8F;
+                  }
+                else if ( c == 0xF4 ) // to exclude F4[90-BF][80-BF] 
                   {
-                    state = 3;
-                    nonchar = PR_TRUE;
-                    if ( c == 0xF0 ) // to exclude F0[80-8F][80-BF]{2}
-                      {
-                        overlong = PR_TRUE;
-                        olupper = 0x8F;
-                      }
-                    else if ( c == 0xF4 ) // to exclude F4[90-BF][80-BF] 
-                      {
-                        // actually not surrogates but codepoints beyond 0x10FFFF
-                        surrogate = PR_TRUE;
-                        slower = 0x90;
-                      }
+                    // actually not surrogates but codepoints beyond 0x10FFFF
+                    surrogate = PR_TRUE;
+                    slower = 0x90;
                   }
-                else
-                  return PR_FALSE; // Not UTF-8 string
               }
-              
-              while (ptr < fragmentEnd && state)
-                {
-                  c = *ptr++;
-                  --state;
+            else
+              return PR_FALSE; // Not UTF-8 string
+          }
+          
+        while ( ptr < end && state )
+          {
+            c = *ptr++;
+            --state;
 
-                  // non-character : EF BF [BE-BF] or F[0-7] [89AB]F BF [BE-BF]
-                  if ( nonchar &&  ( !state &&  c < 0xBE ||
-                       state == 1 && c != 0xBF  ||
-                       state == 2 && 0x0F != (0x0F & c) ))
-                     nonchar = PR_FALSE;
+            // non-character : EF BF [BE-BF] or F[0-7] [89AB]F BF [BE-BF]
+            if ( nonchar &&  ( !state &&  c < 0xBE ||
+                  state == 1 && c != 0xBF  ||
+                  state == 2 && 0x0F != (0x0F & c) ))
+                nonchar = PR_FALSE;
 
-                  if ( !UTF8traits::isInSeq(c) || overlong && c <= olupper || 
-                       surrogate && slower <= c || nonchar && !state )
-                    return PR_FALSE; // Not UTF-8 string
-                  overlong = surrogate = PR_FALSE;
-                }
-            }
+            if ( !UTF8traits::isInSeq(c) || overlong && c <= olupper || 
+                  surrogate && slower <= c || nonchar && !state )
+              return PR_FALSE; // Not UTF-8 string
+            overlong = surrogate = PR_FALSE;
+          }
         }
     return !state; // state != 0 at the end indicates an invalid UTF-8 seq. 
   }
 
   /**
    * A character sink for in-place case conversion.
    */
 class ConvertToUpperCase