Reviewed by Mitz.
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Nov 2007 04:09:30 +0000 (04:09 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Nov 2007 04:09:30 +0000 (04:09 +0000)
        - http://bugs.webkit.org/show_bug.cgi?id=15944
          streamline SegmentedString to speed up parsing

        I measured a speed-up of the page load test while developing this patch. I don't
        have a precise figure, though.

        * html/HTMLTokenizer.h: Removed unneeded lineNumberPtr() function. Also renamed
        lineno to m_lineNumber.
        * html/HTMLTokenizer.cpp:
        (WebCore::HTMLTokenizer::processListing): Don't pass 0 to the advance function
        since we don't want to update a line number.
        (WebCore::HTMLTokenizer::parseSpecial): Ditto.
        (WebCore::HTMLTokenizer::parseComment): Pass the line number data member directly
        instead of lineNumberPtr() since the advance function now takes a reference.
        (WebCore::HTMLTokenizer::parseServer): Ditto.
        (WebCore::HTMLTokenizer::parseProcessingInstruction): Ditto.
        (WebCore::HTMLTokenizer::parseText): Ditto.
        (WebCore::HTMLTokenizer::parseEntity): Ditto.
        (WebCore::HTMLTokenizer::parseTag): Ditto.
        (WebCore::HTMLTokenizer::write): Ditto.

        * loader/FTPDirectoryDocument.cpp: (WebCore::FTPDirectoryTokenizer::write):
        * loader/TextDocument.cpp: (WebCore::TextTokenizer::write):
        Don't pass 0 to the advance function.

        * platform/SegmentedString.h: (WebCore::SegmentedString::advance): Streamlined
        the most common case, and pushed less common cases into a separate function
        that is not inlined. Also got rid of a branch by separating the case with a
        line number from the case without one.

        * platform/SegmentedString.cpp: (WebCore::SegmentedString::advanceSlowCase):
        Added. The aforementioned less common cases are here.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@27699 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/html/HTMLTokenizer.cpp
WebCore/html/HTMLTokenizer.h
WebCore/loader/FTPDirectoryDocument.cpp
WebCore/loader/TextDocument.cpp
WebCore/platform/SegmentedString.cpp
WebCore/platform/SegmentedString.h

index 73be6c41a2bc73a3233f9130bbc6a7ca872d5a76..65c2a68412471b5176aea377a5a3edd889b52b69 100644 (file)
@@ -1,3 +1,40 @@
+2007-11-11  Darin Adler  <darin@apple.com>
+
+        Reviewed by Mitz.
+
+        - http://bugs.webkit.org/show_bug.cgi?id=15944
+          streamline SegmentedString to speed up parsing
+
+        I measured a speed-up of the page load test while developing this patch. I don't
+        have a precise figure, though.
+
+        * html/HTMLTokenizer.h: Removed unneeded lineNumberPtr() function. Also renamed
+        lineno to m_lineNumber.
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::processListing): Don't pass 0 to the advance function
+        since we don't want to update a line number.
+        (WebCore::HTMLTokenizer::parseSpecial): Ditto.
+        (WebCore::HTMLTokenizer::parseComment): Pass the line number data member directly
+        instead of lineNumberPtr() since the advance function now takes a reference.
+        (WebCore::HTMLTokenizer::parseServer): Ditto.
+        (WebCore::HTMLTokenizer::parseProcessingInstruction): Ditto.
+        (WebCore::HTMLTokenizer::parseText): Ditto.
+        (WebCore::HTMLTokenizer::parseEntity): Ditto.
+        (WebCore::HTMLTokenizer::parseTag): Ditto.
+        (WebCore::HTMLTokenizer::write): Ditto.
+
+        * loader/FTPDirectoryDocument.cpp: (WebCore::FTPDirectoryTokenizer::write):
+        * loader/TextDocument.cpp: (WebCore::TextTokenizer::write):
+        Don't pass 0 to the advance function.
+
+        * platform/SegmentedString.h: (WebCore::SegmentedString::advance): Streamlined
+        the most common case, and pushed less common cases into a separate function
+        that is not inlined. Also got rid of a branch by separating the case with a
+        line number from the case without one.
+
+        * platform/SegmentedString.cpp: (WebCore::SegmentedString::advanceSlowCase):
+        Added. The aforementioned less common cases are here.
+
 2007-11-11  Antti Koivisto  <antti@apple.com>
 
         Forgot to do this review change (and test HTTP commit).
index a9c8160c474ddae3420c467f1fe17a484a1be38f..3c7f8a4f6295b8707ef3c99ace3a44854d148baa 100644 (file)
@@ -242,7 +242,7 @@ void HTMLTokenizer::begin()
     noMoreData = false;
     brokenComments = false;
     brokenServer = false;
-    lineno = 0;
+    m_lineNumber = 0;
     scriptStartLineno = 0;
     tagStartLineno = 0;
     m_state.setForceSynchronous(false);
@@ -261,7 +261,7 @@ HTMLTokenizer::State HTMLTokenizer::processListing(SegmentedString list, State s
         if (state.skipLF()) {
             state.setSkipLF(false);
             if (*list == '\n') {
-                list.advance(0);
+                list.advance();
                 continue;
             }
         }
@@ -279,11 +279,11 @@ HTMLTokenizer::State HTMLTokenizer::processListing(SegmentedString list, State s
             if (*list == '\r')
                 state.setSkipLF(true);
 
-            list.advance(0);
+            list.advance();
         } else {
             state.setDiscardLF(false);
             *dest++ = *list;
-            list.advance(0);
+            list.advance();
         }
     }
 
@@ -296,7 +296,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
     ASSERT(!state.hasTagState());
     ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() == 1 );
     if (state.inScript())
-        scriptStartLineno = lineno;
+        scriptStartLineno = m_lineNumber;
 
     if (state.inComment()) 
         state = parseComment(src, state);
@@ -311,7 +311,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
             continue;
         }
         if (scriptCodeResync && !tquote && ch == '>') {
-            src.advance(lineNumberPtr());
+            src.advance(m_lineNumber);
             scriptCodeSize = scriptCodeResync-1;
             scriptCodeResync = 0;
             scriptCode[ scriptCodeSize ] = scriptCode[ scriptCodeSize + 1 ] = 0;
@@ -363,12 +363,12 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
         state.setEscaped(!state.escaped() && ch == '\\');
         if (!scriptCodeResync && (state.inTextArea() || state.inTitle()) && !src.escaped() && ch == '&') {
             UChar* scriptCodeDest = scriptCode+scriptCodeSize;
-            src.advance(lineNumberPtr());
+            src.advance(m_lineNumber);
             state = parseEntity(src, scriptCodeDest, state, m_cBufferPos, true, false);
             scriptCodeSize = scriptCodeDest-scriptCode;
         } else {
             scriptCode[scriptCodeSize++] = *src;
-            src.advance(lineNumberPtr());
+            src.advance(m_lineNumber);
         }
     }
 
@@ -578,7 +578,7 @@ HTMLTokenizer::State HTMLTokenizer::parseComment(SegmentedString &src, State sta
                 endCharsCount = 4;
             }
             if (handleBrokenComments || endCharsCount > 1) {
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
                 if (!(state.inTitle() || state.inScript() || state.inXmp() || state.inTextArea() || state.inStyle())) {
                     checkScriptBuffer();
                     scriptCode[scriptCodeSize] = 0;
@@ -596,7 +596,7 @@ HTMLTokenizer::State HTMLTokenizer::parseComment(SegmentedString &src, State sta
                 return state; // Finished parsing comment
             }
         }
-        src.advance(lineNumberPtr());
+        src.advance(m_lineNumber);
     }
 
     return state;
@@ -609,12 +609,12 @@ HTMLTokenizer::State HTMLTokenizer::parseServer(SegmentedString& src, State stat
         scriptCode[scriptCodeSize++] = *src;
         if (*src == '>' &&
             scriptCodeSize > 1 && scriptCode[scriptCodeSize-2] == '%') {
-            src.advance(lineNumberPtr());
+            src.advance(m_lineNumber);
             state.setInServer(false);
             scriptCodeSize = 0;
             return state; // Finished parsing server include
         }
-        src.advance(lineNumberPtr());
+        src.advance(m_lineNumber);
     }
     return state;
 }
@@ -634,11 +634,11 @@ HTMLTokenizer::State HTMLTokenizer::parseProcessingInstruction(SegmentedString &
         else if (chbegin == '>' && (!tquote || oldchar == '?')) {
             // We got a '?>' sequence
             state.setInProcessingInstruction(false);
-            src.advance(lineNumberPtr());
+            src.advance(m_lineNumber);
             state.setDiscardLF(true);
             return state; // Finished parsing comment!
         }
-        src.advance(lineNumberPtr());
+        src.advance(m_lineNumber);
         oldchar = chbegin;
     }
     
@@ -653,7 +653,7 @@ HTMLTokenizer::State HTMLTokenizer::parseText(SegmentedString &src, State state)
         if (state.skipLF()) {
             state.setSkipLF(false);
             if (cc == '\n') {
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
                 continue;
             }
         }
@@ -666,7 +666,7 @@ HTMLTokenizer::State HTMLTokenizer::parseText(SegmentedString &src, State state)
             *dest++ = '\n';
         } else
             *dest++ = cc;
-        src.advance(lineNumberPtr());
+        src.advance(m_lineNumber);
     }
 
     return state;
@@ -693,7 +693,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
         case SearchEntity:
             if(cc == '#') {
                 cBuffer[cBufferPos++] = cc;
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
                 state.setEntityState(NumericSearch);
             }
             else
@@ -704,7 +704,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
         case NumericSearch:
             if (cc == 'x' || cc == 'X') {
                 cBuffer[cBufferPos++] = cc;
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
                 state.setEntityState(Hexadecimal);
             } else if (cc >= '0' && cc <= '9')
                 state.setEntityState(Decimal);
@@ -727,7 +727,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
                     digit = (cc - 'A' + 10) & 0xF; // handle both upper and lower case without a branch
                 EntityUnicodeValue = EntityUnicodeValue * 16 + digit;
                 cBuffer[cBufferPos++] = cc;
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
             }
             if (cBufferPos == 10)  
                 state.setEntityState(SearchSemicolon);
@@ -746,7 +746,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
 
                 EntityUnicodeValue = EntityUnicodeValue * 10 + (cc - '0');
                 cBuffer[cBufferPos++] = cc;
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
             }
             if (cBufferPos == 9)  
                 state.setEntityState(SearchSemicolon);
@@ -764,7 +764,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
                 }
 
                 cBuffer[cBufferPos++] = cc;
-                src.advance(lineNumberPtr());
+                src.advance(m_lineNumber);
             }
             if (cBufferPos == 9) 
                 state.setEntityState(SearchSemicolon);
@@ -787,7 +787,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
             if (EntityUnicodeValue > 0 && EntityUnicodeValue <= 0x10FFFF) {
                 if (!inViewSourceMode()) {
                     if (*src == ';')
-                        src.advance(lineNumberPtr());
+                        src.advance(m_lineNumber);
                     if (EntityUnicodeValue <= 0xFFFF) {
                         checkBuffer();
                         src.push(fixUpChar(EntityUnicodeValue));
@@ -806,7 +806,7 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
                     dest += cBufferPos;
                     if (*src == ';') {
                         *dest++ = ';';
-                        src.advance(lineNumberPtr());
+                        src.advance(m_lineNumber);
                     }
                 }
             } else {
@@ -832,7 +832,6 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
 
     unsigned cBufferPos = m_cBufferPos;
 
-    int* lineNoPtr = lineNumberPtr();
     bool lastIsSlash = false;
 
     while (!src.isEmpty()) {
@@ -859,7 +858,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         kdDebug( 6036 ) << "Found comment" << endl;
 #endif
                         // Found '<!--' sequence
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                         dest = buffer; // ignore the previous part of this tag
                         state.setInComment(true);
                         state.setTagState(NoTag);
@@ -869,7 +868,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         // can handle this case.  Only do this in quirks mode. -dwh
                         if (!src.isEmpty() && *src == '>' && m_doc->inCompatMode()) {
                           state.setInComment(false);
-                          src.advance(lineNoPtr);
+                          src.advance(m_lineNumber);
                           if (!src.isEmpty())
                               // cuts off high bits, which is okay
                               cBuffer[cBufferPos++] = *src;
@@ -882,7 +881,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     }
                     // cuts off high bits, which is okay
                     cBuffer[cBufferPos++] = *src;
-                    src.advance(lineNoPtr);
+                    src.advance(m_lineNumber);
                     break;
                 }
                 else
@@ -903,7 +902,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     cBuffer[cBufferPos++] = curchar + ('a' - 'A');
                 else
                     cBuffer[cBufferPos++] = curchar;
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
 
             // Disadvantage: we add the possible rest of the tag
@@ -957,7 +956,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 }
                 if (inViewSourceMode())
                     currToken.addViewSourceChar(curchar);
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             break;
         case AttributeName:
@@ -987,7 +986,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 else
                     cBuffer[cBufferPos++] = curchar;
                     
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             if ( cBufferPos == CBUFLEN ) {
                 cBuffer[cBufferPos] = '\0';
@@ -1024,7 +1023,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         state.setTagState(SearchValue);
                         if (inViewSourceMode())
                             currToken.addViewSourceChar(curchar);
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                     }
                     else {
                         currToken.addAttribute(m_doc, attrName, emptyAtom, inViewSourceMode());
@@ -1039,7 +1038,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     
                 lastIsSlash = curchar == '/';
 
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             break;
         case SearchValue:
@@ -1051,7 +1050,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         state.setTagState(QuotedValue);
                         if (inViewSourceMode())
                             currToken.addViewSourceChar(curchar);
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                     } else
                         state.setTagState(Value);
 
@@ -1059,7 +1058,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 }
                 if (inViewSourceMode())
                     currToken.addViewSourceChar(curchar);
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             break;
         case QuotedValue:
@@ -1095,7 +1094,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     // ### attributes like '&{blaa....};' are supposed to be treated as jscript.
                     if ( curchar == '&' )
                     {
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                         state = parseEntity(src, dest, state, cBufferPos, true, true);
                         break;
                     }
@@ -1118,12 +1117,12 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         tquote = NoQuote;
                         if (inViewSourceMode())
                             currToken.addViewSourceChar(curchar);
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                         break;
                     }
                 }
                 *dest++ = *src;
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             break;
         case Value:
@@ -1137,7 +1136,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                     // parse Entities
                     if ( curchar == '&' )
                     {
-                        src.advance(lineNoPtr);
+                        src.advance(m_lineNumber);
                         state = parseEntity(src, dest, state, cBufferPos, true, true);
                         break;
                     }
@@ -1156,7 +1155,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                 }
 
                 *dest++ = *src;
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             break;
         case SearchEnd:
@@ -1173,7 +1172,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
 
                 if (inViewSourceMode())
                     currToken.addViewSourceChar(*src);
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
             }
             if (src.isEmpty()) break;
 
@@ -1182,7 +1181,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
             tquote = NoQuote;
 
             if (*src != '<')
-                src.advance(lineNoPtr);
+                src.advance(m_lineNumber);
 
             if (currToken.tagName == nullAtom) { //stop if tag is unknown
                 m_cBufferPos = cBufferPos;
@@ -1253,7 +1252,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                         searchStopperLen = 7;
                         State savedState = state;
                         SegmentedString savedSrc = src;
-                        long savedLineno = lineno;
+                        long savedLineno = m_lineNumber;
                         state.setInTitle(true);
                         state = parseSpecial(src, state);
                         if (state.inTitle() && src.isEmpty()) {
@@ -1266,7 +1265,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
                             // than a local variable.
                             state = savedState;
                             src = savedSrc;
-                            lineno = savedLineno;
+                            m_lineNumber = savedLineno;
                             scriptCodeSize = 0;
                         }
                     }
@@ -1366,8 +1365,6 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
 
     State state = m_state;
 
-    int* lineNoPtr = lineNumberPtr();
-
     while (!src.isEmpty() && (!frame || !frame->loader()->isScheduledLocationChangePending())) {
         if (!continueProcessing(processedCount, startTime, state))
             break;
@@ -1382,7 +1379,7 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
             state.setSkipLF(false);
 
         if (wasSkipLF && (cc == '\n'))
-            src.advance(0);
+            src.advance();
         else if (state.needsSpecialWriteHandling()) {
             // it's important to keep needsSpecialWriteHandling with the flags this block tests
             if (state.hasEntityState())
@@ -1449,11 +1446,11 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
                 state = parseTag(src, state);
             }
         } else if (cc == '&' && !src.escaped()) {
-            src.advance(lineNoPtr);
+            src.advance(m_lineNumber);
             state = parseEntity(src, dest, state, m_cBufferPos, true, state.hasTagState());
         } else if (cc == '<' && !src.escaped()) {
-            tagStartLineno = lineno;
-            src.advance(lineNoPtr);
+            tagStartLineno = m_lineNumber;
+            src.advance(m_lineNumber);
             state.setStartTag(true);
         } else if (cc == '\n' || cc == '\r') {
             if (state.discardLF())
@@ -1463,17 +1460,17 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
                 // Process this LF
                 *dest++ = '\n';
                 if (cc == '\r' && !src.excludeLineNumbers())
-                    lineno++;
+                    m_lineNumber++;
             }
 
             /* Check for MS-DOS CRLF sequence */
             if (cc == '\r')
                 state.setSkipLF(true);
-            src.advance(lineNoPtr);
+            src.advance(m_lineNumber);
         } else {
             state.setDiscardLF(false);
             *dest++ = cc;
-            src.advance(lineNoPtr);
+            src.advance(m_lineNumber);
         }
     }
     
@@ -1614,7 +1611,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
     } else if (currToken.tagName == nullAtom) {
         currToken.reset();
         if (jsProxy)
-            jsProxy->setEventHandlerLineno(lineno);
+            jsProxy->setEventHandlerLineno(m_lineNumber);
         return 0;
     }
 
index f76039d5b00cedbd69a2e10a726b3262981929eb..56d936f4f52a841445b25f2b0cf7abbb2705498a 100644 (file)
@@ -3,7 +3,7 @@
               (C) 1997 Torben Weis (weis@kde.org)
               (C) 1998 Waldo Bastian (bastian@kde.org)
               (C) 2001 Dirk Mueller (mueller@kde.org)
-    Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+    Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -100,11 +100,9 @@ public:
     virtual bool processingData() const;
     virtual int executingScript() const { return m_executingScript; }
 
-    virtual int lineNumber() const { return lineno; }
+    virtual int lineNumber() const { return m_lineNumber; }
     virtual int columnNumber() const { return 1; }
 
-    int* lineNumberPtr() { return &lineno; }
-
     bool processingContentWrittenByScript() const { return src.excludeLineNumbers(); }
     
     virtual void executeScriptsWaitingForStylesheets();
@@ -333,7 +331,7 @@ private:
     // store a flag to get rid of the O(n^2) behaviour in such a case.
     bool brokenComments;
     // current line number
-    int lineno;
+    int m_lineNumber;
     // line number at which the current <script> started
     int scriptStartLineno;
     int tagStartLineno;
index 2ff17ba1ca5e61657195c2bc3d24ea3388d51f99..dada9aec4bfe3235221e62d0278516dfd3264c40 100644 (file)
@@ -402,7 +402,7 @@ bool FTPDirectoryTokenizer::write(const SegmentedString& s, bool appendData)
             m_skipLF = false;
         }
         
-        str.advance(0);
+        str.advance();
         
         // Maybe enlarge the buffer
         checkBuffer();
index 01c0ebcc7637ff5aa77020c2d8b95b0aabeb3bff..b5124b41c5f25ab7269025d07ead6ad4959740c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,7 +23,6 @@
  */
 
 #include "config.h"
-
 #include "TextDocument.h"
 
 #include "Element.h"
@@ -87,7 +86,7 @@ bool TextTokenizer::write(const SegmentedString& s, bool appendData)
             m_skipLF = false;
         }
         
-        str.advance(0);
+        str.advance();
         
         // Maybe enlarge the buffer
         checkBuffer();
index cfe84cd1e1f34223ff667150a2917c5b01e5d3e8..410c6e2b71dd410e62346d0e641979de369fc8a6 100644 (file)
@@ -1,7 +1,5 @@
 /*
-    This file is part of the KDE libraries
-
-    Copyright (C) 2004-6 Apple Computer
+    Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -174,4 +172,31 @@ String SegmentedString::toString() const
     return result;
 }
 
+void SegmentedString::advanceSlowCase()
+{
+    if (m_pushedChar1) {
+        m_pushedChar1 = m_pushedChar2;
+        m_pushedChar2 = 0;
+    } else if (m_currentString.m_current) {
+        ++m_currentString.m_current;
+        if (--m_currentString.m_length == 0)
+            advanceSubstring();
+    }
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
+}
+
+void SegmentedString::advanceSlowCase(int& lineNumber)
+{
+    if (m_pushedChar1) {
+        m_pushedChar1 = m_pushedChar2;
+        m_pushedChar2 = 0;
+    } else if (m_currentString.m_current) {
+        if (*m_currentString.m_current++ == '\n' && !m_currentString.excludeLineNumbers())
+            ++lineNumber;
+        if (--m_currentString.m_length == 0)
+            advanceSubstring();
+    }
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
+}
+
 }
index 26d8c1dea6024619a7736d0623d758ae239685e8..58420987c03602d680626ea703a54c265fb478fa 100644 (file)
@@ -1,7 +1,5 @@
 /*
-    This file is part of the KDE libraries
-
-    Copyright (C) 2004, 2005, 2006 Apple Computer
+    Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -83,7 +81,8 @@ public:
     bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers(); }
     void setExcludeLineNumbers();
 
-    void push(UChar c) {
+    void push(UChar c)
+    {
         if (!m_pushedChar1) {
             m_pushedChar1 = c;
             m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
@@ -96,17 +95,25 @@ public:
     bool isEmpty() const { return !current(); }
     unsigned length() const;
 
-    void advance(int* lineNumber = 0) {
-        if (m_pushedChar1) {
-            m_pushedChar1 = m_pushedChar2;
-            m_pushedChar2 = 0;
-        } else if (m_currentString.m_current) {
-            if (*m_currentString.m_current++ == '\n' && lineNumber && !m_currentString.excludeLineNumbers())
-                *lineNumber = *lineNumber + 1;
-            if (--m_currentString.m_length == 0)
-                advanceSubstring();
+    void advance()
+    {
+        if (!m_pushedChar1 && m_currentString.m_length > 1) {
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
+            return;
+        }
+        advanceSlowCase();
+    }
+    
+    void advance(int& lineNumber)
+    {
+        if (!m_pushedChar1 && m_currentString.m_length > 1) {
+            lineNumber += (*m_currentString.m_current == '\n') & m_currentString.excludeLineNumbers();
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
+            return;
         }
-        m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
+        advanceSlowCase(lineNumber);
     }
     
     bool escaped() const { return m_pushedChar1; }
@@ -120,6 +127,8 @@ private:
     void append(const SegmentedSubstring &);
     void prepend(const SegmentedSubstring &);
 
+    void advanceSlowCase();
+    void advanceSlowCase(int& lineNumber);
     void advanceSubstring();
     const UChar* current() const { return m_currentChar; }