@@ -1721,36 +1721,57 @@ static char[] consumeCharacterReference(int additionalCharacter, boolean inAttri
17211721
17221722 private static char [] parseEntity (boolean inAttribute , ProcessedInputStream processedInputStream , Tokenizer tokenHandler , int chr ) {
17231723 int matchedCount = 0 ;
1724- var currentPrefix = EntitiesPrefix .ENTITIES ;
1724+ int currentNodeIdx = 0 ;
1725+ int lastCompleteNodeIdx = -1 ;
1726+ int lastCompleteMatchedCount = 0 ;
1727+
17251728 ResizableCharBuilder tentativelyMatched = new ResizableCharBuilder ();
17261729
17271730 for (;;) {
1731+ if (EntitiesPrefix .NODE_RESULTS [currentNodeIdx ] != null ) {
1732+ lastCompleteNodeIdx = currentNodeIdx ;
1733+ lastCompleteMatchedCount = matchedCount ;
1734+ }
1735+
17281736 int next = processedInputStream .peekNextInputCharacter (matchedCount + 1 );
17291737 if (next != Characters .EOF ) {
17301738 tentativelyMatched .append ((char ) next );
1731- }
1732- var tmpPrefix = currentPrefix .getNode ((char ) next );
1733- if (tmpPrefix != null ) {
1734- currentPrefix = tmpPrefix ;
1735- matchedCount ++;
17361739 } else {
17371740 break ;
17381741 }
1739- }
17401742
1741- if (!currentPrefix .isComplete ()) {
1742- var maybeCompleteParent = currentPrefix .getMaybeCompleteParent ();
1743- if (maybeCompleteParent != null ) {
1744- currentPrefix = maybeCompleteParent ;
1743+ char nextChar = (char ) next ;
1744+ int childrenBase = EntitiesPrefix .NODE_CHILDREN_BASE [currentNodeIdx ];
1745+ boolean found = false ;
1746+ if (childrenBase != -1 ) {
1747+ int offset = nextChar - EntitiesPrefix .NODE_MIN_CHILD_CHAR [currentNodeIdx ];
1748+ if (offset >= 0 && offset < EntitiesPrefix .NODE_CHILDREN_COUNT [currentNodeIdx ]) {
1749+ int nextNodeIdx = EntitiesPrefix .CHILD_POINTERS [childrenBase + offset ];
1750+ if (nextNodeIdx != -1 ) {
1751+ currentNodeIdx = nextNodeIdx ;
1752+ matchedCount ++;
1753+ found = true ;
1754+ }
1755+ }
1756+ }
1757+
1758+ if (!found ) {
1759+ break ;
17451760 }
17461761 }
17471762
1748- if (currentPrefix .isComplete ()) {
1749- String entityMatched = currentPrefix .getString ();
1763+ if (EntitiesPrefix .NODE_RESULTS [currentNodeIdx ] == null ) {
1764+ currentNodeIdx = lastCompleteNodeIdx ;
1765+ matchedCount = lastCompleteMatchedCount ;
1766+ }
1767+
1768+ if (currentNodeIdx != -1 && EntitiesPrefix .NODE_RESULTS [currentNodeIdx ] != null ) {
1769+ char nodeChar = EntitiesPrefix .NODE_CHAR [currentNodeIdx ];
1770+ char [] result = EntitiesPrefix .NODE_RESULTS [currentNodeIdx ];
17501771 if (inAttribute ) {
1751- return handleCompleteEntityInAttribute (processedInputStream , tokenHandler , currentPrefix , entityMatched );
1772+ return handleCompleteEntityInAttribute (processedInputStream , tokenHandler , nodeChar , matchedCount , result );
17521773 } else {
1753- return handleCompleteEntityNotInAttribute (processedInputStream , tokenHandler , currentPrefix , entityMatched );
1774+ return handleCompleteEntityNotInAttribute (processedInputStream , tokenHandler , nodeChar , matchedCount , result );
17541775 }
17551776 } else {
17561777 // handleUncompleteEntity
@@ -1766,7 +1787,7 @@ private static char[] parseEntity(boolean inAttribute, ProcessedInputStream proc
17661787 boolean emitParseError = tentativelyMatchedLength > 1 && tentativelyMatched .at (tentativelyMatchedLength - 1 ) == Characters .SEMICOLON ;
17671788 if (emitParseError ) {
17681789 for (int i = 0 ; emitParseError && i < tentativelyMatchedLength - 1 ; i ++) {
1769- emitParseError = Common .isAlphaNumericASCII (chr );
1790+ emitParseError = Common .isAlphaNumericASCII (tentativelyMatched . at ( i ) );
17701791 }
17711792 }
17721793
@@ -1777,32 +1798,30 @@ private static char[] parseEntity(boolean inAttribute, ProcessedInputStream proc
17771798 }
17781799 }
17791800
1780-
1781-
1782- private static char [] handleCompleteEntityNotInAttribute (ProcessedInputStream processedInputStream , Tokenizer tokenHandler , EntitiesPrefix currentPrefix , String entityMatched ) {
1783- if ((currentPrefix .c ) != Characters .SEMICOLON ) {
1801+ private static char [] handleCompleteEntityNotInAttribute (ProcessedInputStream processedInputStream , Tokenizer tokenHandler , char nodeChar , int matchedCount , char [] chars ) {
1802+ if (nodeChar != Characters .SEMICOLON ) {
17841803 tokenHandler .emitParseError ();
17851804 }
17861805
1787- processedInputStream .consume (entityMatched . length () - 1 );
1788- return currentPrefix . chars ;
1806+ processedInputStream .consume (matchedCount );
1807+ return chars ;
17891808 }
17901809
1791- private static char [] handleCompleteEntityInAttribute (ProcessedInputStream processedInputStream , Tokenizer tokenHandler , EntitiesPrefix currentPrefix , String entityMatched ) {
1792- if (currentPrefix . c != Characters .SEMICOLON ) {
1793- int nextCharacterAfterMatchedEntity = processedInputStream .peekNextInputCharacter (entityMatched . length () );
1810+ private static char [] handleCompleteEntityInAttribute (ProcessedInputStream processedInputStream , Tokenizer tokenHandler , char nodeChar , int matchedCount , char [] chars ) {
1811+ if (nodeChar != Characters .SEMICOLON ) {
1812+ int nextCharacterAfterMatchedEntity = processedInputStream .peekNextInputCharacter (matchedCount + 1 );
17941813 if (Common .isAlphaNumericASCII (nextCharacterAfterMatchedEntity )) {
17951814 return null ;
17961815 } else if (Characters .EQUALS_SIGN == nextCharacterAfterMatchedEntity ) {
17971816 tokenHandler .emitParseError ();
17981817 return null ;
17991818 } else {
1800- return handleCompleteEntityNotInAttribute (processedInputStream , tokenHandler , currentPrefix , entityMatched );
1819+ return handleCompleteEntityNotInAttribute (processedInputStream , tokenHandler , nodeChar , matchedCount , chars );
18011820 }
18021821
18031822 } else {
1804- processedInputStream .consume (entityMatched . length () - 1 );
1805- return currentPrefix . chars ;
1823+ processedInputStream .consume (matchedCount );
1824+ return chars ;
18061825 }
18071826 }
18081827
0 commit comments