@Inline privatevoid clearStrBufBeforeUse() { assert strBufLen == 0: "strBufLen not reset after previous use!";
strBufLen = 0; // no-op in the absence of bugs
}
@Inline privatevoid clearStrBufAfterOneHyphen() { assert strBufLen == 1: "strBufLen length not one!"; assert strBuf[0] == '-': "strBuf does not start with a hyphen!";
strBufLen = 0;
}
@Inline privatevoid appendSecondHyphenToBogusComment() throws SAXException { // [NOCPP[ switch (commentPolicy) { case ALTER_INFOSET:
appendStrBuf(' '); // CPPONLY: MOZ_FALLTHROUGH; case ALLOW:
warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment."); // ]NOCPP]
appendStrBuf('-'); // [NOCPP[ break; case FATAL:
fatal("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment."); break;
} // ]NOCPP]
}
// [NOCPP[ privatevoid maybeAppendSpaceToBogusComment() throws SAXException { switch (commentPolicy) { case ALTER_INFOSET:
appendStrBuf(' '); // CPPONLY: MOZ_FALLTHROUGH; case ALLOW:
warn("The document is not mappable to XML 1.0 due to a trailing hyphen in a comment."); break; case FATAL:
fatal("The document is not mappable to XML 1.0 due to a trailing hyphen in a comment."); break;
}
}
// ]NOCPP]
@Inline privatevoid adjustDoubleHyphenAndAppendToStrBufAndErr(char c, boolean reportedConsecutiveHyphens) throws SAXException { // [NOCPP[ switch (commentPolicy) { case ALTER_INFOSET:
strBufLen--; // WARNING!!! This expands the worst case of the buffer length // given the length of input!
appendStrBuf(' ');
appendStrBuf('-'); // CPPONLY: MOZ_FALLTHROUGH; case ALLOW: if (!reportedConsecutiveHyphens) {
warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
} // ]NOCPP]
appendStrBuf(c); // [NOCPP[ break; case FATAL:
fatal("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment."); break;
} // ]NOCPP]
}
@Inline privatevoid appendStrBuf(@NoLength char[] buffer, int offset, int length) throws SAXException { // Years of crash stats have shown that the this addition doesn't overflow, as it logically // shouldn't. int newLen = strBufLen + length; // CPPONLY: if (strBuf.length < newLen) { // CPPONLY: EnsureBufferSpaceShouldNeverHappen(length); // CPPONLY: }
System.arraycopy(buffer, offset, strBuf, strBufLen, length);
strBufLen = newLen;
}
publicvoid start() throws SAXException {
initializeWithoutStarting();
tokenHandler.startTokenization(this); // CPPONLY: if (mViewSource) { // CPPONLY: line = 1; // CPPONLY: col = -1; // CPPONLY: nextCharOnNewLine = false; // CPPONLY: } else if (tokenHandler.WantsLineAndColumn()) { // CPPONLY: line = 0; // CPPONLY: col = 1; // CPPONLY: nextCharOnNewLine = true; // CPPONLY: } else { // CPPONLY: line = -1; // CPPONLY: col = -1; // CPPONLY: nextCharOnNewLine = false; // CPPONLY: } // [NOCPP[
startErrorReporting(); // ]NOCPP]
}
publicboolean tokenizeBuffer(UTF16Buffer buffer) throws SAXException { int state = stateSave; int returnState = returnStateSave; char c = '\u0000';
shouldSuspend = false;
lastCR = false;
int start = buffer.getStart(); int end = buffer.getEnd();
// In C++, the caller of tokenizeBuffer needs to do this explicitly. // [NOCPP[
ensureBufferSpace(end - start); // ]NOCPP]
/** *Theindexofthelast<code>char</code>readfrom<code>buf</code>.
*/ int pos = start - 1;
switch (state) { case DATA: case RCDATA: case SCRIPT_DATA: case PLAINTEXT: case RAWTEXT: case CDATA_SECTION: case SCRIPT_DATA_ESCAPED: case SCRIPT_DATA_ESCAPE_START: case SCRIPT_DATA_ESCAPE_START_DASH: case SCRIPT_DATA_ESCAPED_DASH: case SCRIPT_DATA_ESCAPED_DASH_DASH: case SCRIPT_DATA_DOUBLE_ESCAPE_START: case SCRIPT_DATA_DOUBLE_ESCAPED: case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: case SCRIPT_DATA_DOUBLE_ESCAPE_END:
cstart = start; break; default:
cstart = Integer.MAX_VALUE; break;
}
// [NOCPP[ privatevoid ensureBufferSpace(int inputLength) throws SAXException { // Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB. // Adding to the general worst case instead of only the // TreeBuilder-exposed worst case to avoid re-introducing a bug when // unifying the tokenizer and tree builder buffers in the future. int worstCase = strBufLen + inputLength + charRefBufLen + 2;
tokenHandler.ensureBufferSpace(worstCase); if (commentPolicy == XmlViolationPolicy.ALTER_INFOSET) { // When altering infoset, if the comment contents are consecutive // hyphens, each hyphen generates a space, too. These buffer // contents never get emitted as characters() to the tokenHandler, // which is why this calculation happens after the call to // ensureBufferSpace on tokenHandler.
worstCase *= 2;
} if (strBuf == null) { // Add an arbitrary small value to avoid immediate reallocation // once there are a few characters in the buffer.
strBuf = newchar[worstCase + 128];
} elseif (worstCase > strBuf.length) { // HotSpot reportedly allocates memory with 8-byte accuracy, so // there's no point in trying to do math here to avoid slop. // Maybe we should add some small constant to worstCase here // but not doing that without profiling. In C++ with jemalloc, // the corresponding method should do math to round up here // to avoid slop. char[] newBuf = newchar[Math.max(worstCase, (strBuf.length*5)/4)];
System.arraycopy(strBuf, 0, newBuf, 0, strBufLen);
strBuf = newBuf;
}
} // ]NOCPP]
@SuppressWarnings("unused") @Inline privateint stateLoop(int state, char c, int pos, @NoLength char[] buf, boolean reconsume, int returnState, int endPos) throws SAXException { boolean reportedConsecutiveHyphens = false; /* *Idiomsusedinthiscode: * * *Consumingthenextinputcharacter * *Toconsumethenextinputcharacter,thecodedoesthis:if(++pos== *endPos){breakstateloop;}c=checkChar(buf,pos); * * *Stayinginastate * *Whenthere'sastatethatthetokenizermaystayinovermultiple *inputcharacters,thestatehasawrapper|for(;;)|loopandstaying *inthestatecontinuestheloop. * * *Switchingtoanotherstate * *Toswitchtoanotherstate,thecodesetsthestatevariabletothe *magicnumberofthenewstate.Theniteithercontinuesstateloopor *breaksoutofthestate'sownwrapperloopifthetargetstateis *rightafterthecurrentstateinsourceorder.(Thisisapartial *workaroundforJava'slackofgoto.) * * *Reconsumesupport * *Thespecsometimessaysthataninputcharacterisreconsumedin *anotherstate.Ifastatecaneverbeenteredsothataninput *charactercanbereconsumedinit,thestate'scodestartswithan *|if(reconsume)|thatsetsreconsumetofalseandskipsoverthe *normalcodeforconsuminganewcharacter. * *Toreconsumethecurrentcharacterinanotherstate,thecodesets *|reconsume|totrueandthenswitchestotheotherstate. * * *Emittingcharactertokens * *Thismethodemitscharactertokenslazily.Wheneveranewrangeof *charactertokensstarts,thefieldcstartmustbesettothestart *indexoftherange.TheflushChars()methodmustbecalledattheend *ofarangetoflushit. * * *U+0000handling * *ThevariousstateshavetohandlethereplacementofU+0000with *U+FFFD.However,ifU+0000wouldbereconsumedinanotherstate,the *replacementdoesn'tneedtohappen,becauseit'shandledbythe *reconsumingstate. * * *LFhandling * *EverystateneedstoincrementthelinenumberuponLFunlesstheLF *getsreconsumedbyanotherstatewhichincrementsthelinenumber. * * *CRhandling * *EverystateneedstohandleCRunlesstheCRgetsreconsumedandis *handledbythereconsumingstate.TheCRneedstobehandledasifit *wereandLF,thelastCRfieldmustbesettotrueandthenthis *methodmustreturn.TheIOdriverwillthenswallowthenext *characterifitisanLFtocoalesceCRLF.
*/
stateloop: for (;;) { switch (state) { case DATA:
dataloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementData(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case'&': /* *U+0026AMPERSAND(&)Switchtothecharacter *referenceindatastate.
*/
flushChars(buf, pos); assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\u0000');
returnState = state;
state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); continue stateloop; case'<': /* *U+003CLESS-THANSIGN(<)Switchtothetag *openstate.
*/
flushChars(buf, pos);
state = transition(state, Tokenizer.ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
noteUnquotedAttributeValue(); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
attributevaluedoublequotedloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementAttributeValueDoubleQuoted(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'"': /* *U+0022QUOTATIONMARK(")Switchtotheafter *attributevalue(quoted)state.
*/
addAttributeWithValue();
state = transition(state, Tokenizer.AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break attributevaluedoublequotedloop; case'&': /* *U+0026AMPERSAND(&)Switchtothecharacter *referenceinattributevaluestate,withthe *additionalallowedcharacterbeingU+0022 *QUOTATIONMARK(").
*/ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\"');
returnState = state;
state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentattribute'svalue.
*/
appendStrBuf(c); /* *Stayintheattributevalue(double-quoted) *state.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_ATTRIBUTE_VALUE_QUOTED:
afterattributevaluequotedloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *Switchtothebeforeattributenamestate.
*/
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); continue stateloop; case'/': /* *U+002FSOLIDUS(/)Switchtotheself-closing *starttagstate.
*/
state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterattributevaluequotedloop; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *tagtoken.
*/
state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos); if (shouldSuspend) { break stateloop;
} /* *Switchtothedatastate.
*/ continue stateloop; default: /* *AnythingelseParseerror.
*/
errNoSpaceBetweenAttributes(); /* *Reconsumethecharacterinthebefore *attributenamestate.
*/
reconsume = true;
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SELF_CLOSING_START_TAG: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'>': /* *U+003EGREATER-THANSIGN(>)Settheself-closing *flagofthecurrenttagtoken.Emitthecurrent *tagtoken.
*/
state = transition(state, emitCurrentTagToken(true, pos), reconsume, pos); if (shouldSuspend) { break stateloop;
} /* *Switchtothedatastate.
*/ continue stateloop; default: /* Anything else Parse error. */
errSlashNotFollowedByGt(); /* *Reconsumethecharacterinthebeforeattribute *namestate.
*/
reconsume = true;
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); continue stateloop;
} // no fallthrough, reordering opportunity case ATTRIBUTE_VALUE_UNQUOTED: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
addAttributeWithValue();
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *Switchtothebeforeattributenamestate.
*/
addAttributeWithValue();
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); continue stateloop; case'&': /* *U+0026AMPERSAND(&)Switchtothecharacter *referenceinattributevaluestate,withthe *additionalallowedcharacterbeingU+003E *GREATER-THANSIGN(>)
*/ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('>');
returnState = state;
state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); continue stateloop; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *tagtoken.
*/
addAttributeWithValue();
state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos); if (shouldSuspend) { break stateloop;
} /* *Switchtothedatastate.
*/ continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; case'<': case'\"': case'\'': case'=': case'`': /* *U+0022QUOTATIONMARK(")U+0027APOSTROPHE *(')U+003CLESS-THANSIGN(<)U+003DEQUALS *SIGN(=)U+0060GRAVEACCENT(`)Parseerror.
*/
errUnquotedAttributeValOrNull(c); /* *Treatitasperthe"anythingelse"entry *below.
*/ // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentattribute'svalue.
*/
appendStrBuf(c); /* *Stayintheattributevalue(unquoted)state.
*/ continue;
}
} // no fallthrough, reordering opportunity case AFTER_ATTRIBUTE_NAME: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *intheafterattributenamestate.
*/ continue; case'/': /* *U+002FSOLIDUS(/)Switchtotheself-closing *starttagstate.
*/
addAttributeWithoutValue();
state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos); continue stateloop; case'=': /* *U+003DEQUALSSIGN(=)Switchtothebefore *attributevaluestate.
*/
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_VALUE, reconsume, pos); continue stateloop; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *tagtoken.
*/
addAttributeWithoutValue();
state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos); if (shouldSuspend) { break stateloop;
} /* *Switchtothedatastate.
*/ continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; case'\"': case'\'': case'<':
errQuoteOrLtInAttributeNameOrNull(c); /* *Treatitasperthe"anythingelse"entry *below.
*/ // CPPONLY: MOZ_FALLTHROUGH; default:
addAttributeWithoutValue(); /* *AnythingelseStartanewattributeinthe *currenttagtoken.
*/ if (c >= 'A' && c <= 'Z') { /* *U+0041LATINCAPITALLETTERAthroughto *U+005ALATINCAPITALLETTERZSetthat *attribute'snametothelowercaseversion *ofthecurrentinputcharacter(add *0x0020tothecharacter'scodepoint)
*/
c += 0x20;
} /* *Setthatattribute'snametothecurrent *inputcharacter,
*/
clearStrBufBeforeUse();
appendStrBuf(c); /* *anditsvaluetotheemptystring.
*/ // Will do later. /* *Switchtotheattributenamestate.
*/
state = transition(state, Tokenizer.ATTRIBUTE_NAME, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case MARKUP_DECLARATION_OPEN:
markupdeclarationopenloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *IfthenexttwocharactersarebothU+002D *HYPHEN-MINUScharacters(-),consumethosetwo *characters,createacommenttokenwhosedataisthe *emptystring,andswitchtothecommentstartstate. * *Otherwise,ifthenextsevencharactersareanASCII *case-insensitivematchfortheword"DOCTYPE",then *consumethosecharactersandswitchtotheDOCTYPE *state. * *Otherwise,iftheinsertionmodeis *"inforeigncontent"andthecurrentnodeisnotan *elementintheHTMLnamespaceandthenextseven *charactersareancase-sensitivematchforthestring *"[CDATA["(thefiveuppercaseletters"CDATA"witha *U+005BLEFTSQUAREBRACKETcharacterbeforeand *after),thenconsumethosecharactersandswitchto *theCDATAsectionstate. * *Otherwise,isisaparseerror.Switchtothebogus *commentstate.Thenextcharacterthatisconsumed, *ifany,isthefirstcharacterthatwillbeinthe *comment.
*/ switch (c) { case'-':
clearStrBufBeforeUse();
appendStrBuf(c);
state = transition(state, Tokenizer.MARKUP_DECLARATION_HYPHEN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break markupdeclarationopenloop; case'd': case'D':
clearStrBufBeforeUse();
appendStrBuf(c);
index = 0;
state = transition(state, Tokenizer.MARKUP_DECLARATION_OCTYPE, reconsume, pos); continue stateloop; case'[': if (tokenHandler.cdataSectionAllowed()) {
clearStrBufBeforeUse();
appendStrBuf(c);
index = 0;
state = transition(state, Tokenizer.CDATA_START, reconsume, pos); continue stateloop;
} // CPPONLY: MOZ_FALLTHROUGH; default:
errBogusComment();
clearStrBufBeforeUse();
reconsume = true;
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case MARKUP_DECLARATION_HYPHEN:
markupdeclarationhyphenloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'-':
clearStrBufAfterOneHyphen();
state = transition(state, Tokenizer.COMMENT_START, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break markupdeclarationhyphenloop; default:
errBogusComment();
reconsume = true;
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_START:
reportedConsecutiveHyphens = false;
commentstartloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Commentstartstate * * *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)Switchtothecomment *startdashstate.
*/
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_START_DASH, reconsume, pos); continue stateloop; case'>': /* *U+003EGREATER-THANSIGN(>)Parseerror.
*/
errPrematureEndOfComment(); /* Emit the comment token. */
emitComment(0, pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break commentstartloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendtheinputcharacterto *thecommenttoken'sdata.
*/
appendStrBuf(c); /* *Switchtothecommentstate.
*/
state = transition(state, Tokenizer.COMMENT, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentstartloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT:
commentloop: for (;;) {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementComment(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *CommentstateConsumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)Switchtothecomment *enddashstate
*/
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentloop; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendtheinputcharacterto *thecommenttoken'sdata.
*/
appendStrBuf(c); /* *Stayinthecommentstate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_END_DASH:
commentenddashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *CommentenddashstateConsumethenextinput *character:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)Switchtothecomment *endstate
*/
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_END, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentenddashloop; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendaU+002DHYPHEN-MINUS *(-)characterandtheinputcharactertothe *commenttoken'sdata.
*/
appendStrBuf(c); /* *Switchtothecommentstate.
*/
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_END:
commentendloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *CommentenddashstateConsumethenextinput *character:
*/ switch (c) { case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecomment *token.
*/
emitComment(2, pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'-': /* U+002D HYPHEN-MINUS (-) Parse error. */ /* *AppendaU+002DHYPHEN-MINUS(-)characterto *thecommenttoken'sdata.
*/
adjustDoubleHyphenAndAppendToStrBufAndErr(c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true; /* *Stayinthecommentendstate.
*/ continue; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
adjustDoubleHyphenAndAppendToStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
adjustDoubleHyphenAndAppendToStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'!':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_END_BANG, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentendloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AppendtwoU+002DHYPHEN-MINUS(-)characters *andtheinputcharactertothecomment *token'sdata.
*/
adjustDoubleHyphenAndAppendToStrBufAndErr(c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true; /* *Switchtothecommentstate.
*/
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_END_BANG: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Commentendbangstate * *Consumethenextinputcharacter:
*/ switch (c) { case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecomment *token.
*/
emitComment(3, pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'-': /* *AppendtwoU+002DHYPHEN-MINUS(-)characters *andaU+0021EXCLAMATIONMARK(!)character *tothecommenttoken'sdata.
*/
appendStrBuf(c); /* *Switchtothecommentenddashstate.
*/
state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendtwoU+002DHYPHEN-MINUS *(-)characters,aU+0021EXCLAMATIONMARK(!) *character,andtheinputcharactertothe *commenttoken'sdata.Switchtothecomment *state.
*/
appendStrBuf(c); /* *Switchtothecommentstate.
*/
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case COMMENT_LESSTHAN:
commentlessthanloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'!':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN_BANG, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentlessthanloop; case'<':
appendStrBuf(c); continue; case'-':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_LESSTHAN_BANG:
commentlessthanbangloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'-':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN_BANG_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break commentlessthanbangloop; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_LESSTHAN_BANG_DASH: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'-':
appendStrBuf(c);
state = transition(state,
Tokenizer.COMMENT_LESSTHAN_BANG_DASH_DASH,
reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break; case'<':
appendStrBuf(c);
state = transition(state,
Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); continue stateloop;
} // CPPONLY: MOZ_FALLTHROUGH; case COMMENT_LESSTHAN_BANG_DASH_DASH: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'>':
appendStrBuf(c);
emitComment(3, pos);
state = transition(state, Tokenizer.DATA, reconsume,
pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'-':
errNestedComment();
adjustDoubleHyphenAndAppendToStrBufAndErr(c,
reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = transition(state, Tokenizer.COMMENT_END,
reconsume, pos); continue stateloop; case'\r':
c = '\n';
silentCarriageReturn();
errNestedComment();
adjustDoubleHyphenAndAppendToStrBufAndErr(c,
reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); break stateloop; case'\n':
silentLineFeed();
errNestedComment();
adjustDoubleHyphenAndAppendToStrBufAndErr(c,
reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); continue stateloop; case'!':
errNestedComment();
adjustDoubleHyphenAndAppendToStrBufAndErr(c,
reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = transition(state,
Tokenizer.COMMENT_END_BANG, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
errNestedComment();
adjustDoubleHyphenAndAppendToStrBufAndErr(c,
reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = transition(state, Tokenizer.COMMENT,
reconsume, pos); continue stateloop;
} // no fallthrough, reordering opportunity case COMMENT_START_DASH: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Commentstartdashstate * *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)Switchtothecommentend *state
*/
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_END, reconsume, pos); continue stateloop; case'>':
errPrematureEndOfComment(); /* Emit the comment token. */
emitComment(1, pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'<':
appendStrBuf(c);
state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos); continue stateloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AppendaU+002DHYPHEN-MINUScharacter(-)and *thecurrentinputcharactertothecomment *token'sdata.
*/
appendStrBuf(c); /* *Switchtothecommentstate.
*/
state = transition(state, Tokenizer.COMMENT, reconsume, pos); continue stateloop;
} // no fallthrough, reordering opportunity case CDATA_START: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); if (index < 6) { // CDATA_LSQB.length if (c == Tokenizer.CDATA_LSQB[index]) {
appendStrBuf(c);
} else {
errBogusComment();
reconsume = true;
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
index++; continue;
} else {
clearStrBufAfterUse();
cstart = pos; // start coalescing
reconsume = true;
state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break;
}
} // CPPONLY: MOZ_FALLTHROUGH; case CDATA_SECTION:
cdatasectionloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementCdataSection(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case']':
flushChars(buf, pos);
state = transition(state, Tokenizer.CDATA_RSQB, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break cdatasectionloop; case'\u0000':
maybeEmitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case CDATA_RSQB: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case']':
state = transition(state, Tokenizer.CDATA_RSQB_RSQB,
reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break; default:
tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1);
cstart = pos;
reconsume = true;
state = transition(state, Tokenizer.CDATA_SECTION,
reconsume, pos); continue stateloop;
} // CPPONLY: MOZ_FALLTHROUGH; case CDATA_RSQB_RSQB:
cdatarsqbrsqb: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case']': // Saw a third ]. Emit one ] (logically the // first one) and stay in this state to // remember that the last two characters seen // have been ]].
tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1); continue; case'>':
cstart = pos + 1;
state = transition(state, Tokenizer.DATA, reconsume, pos); // Since a CDATA section starts with a less-than sign, it // participates in the suspension-after-current-token // behavior. (The suspension can be requested when the // less-than sign has been seen but we don't yet know the // resulting token type.) Therefore, we need to deal with // a potential request here.
suspendIfRequestedAfterCurrentNonTextToken(); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2);
cstart = pos;
reconsume = true;
state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case ATTRIBUTE_VALUE_SINGLE_QUOTED:
attributevaluesinglequotedloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementAttributeValueSingleQuoted(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'\'': /* *U+0027APOSTROPHE(')Switchtotheafter *attributevalue(quoted)state.
*/
addAttributeWithValue();
state = transition(state, Tokenizer.AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos); continue stateloop; case'&': /* *U+0026AMPERSAND(&)Switchtothecharacter *referenceinattributevaluestate,withthe *+additionalallowedcharacterbeingU+0027 *APOSTROPHE(').
*/ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\'');
returnState = state;
state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break attributevaluesinglequotedloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentattribute'svalue.
*/
appendStrBuf(c); /* *Stayintheattributevalue(double-quoted) *state.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case CONSUME_CHARACTER_REFERENCE: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Unlikethedefinitionisthespec,thisstatedoesnot *returnavalueandneverrequiresthecallerto *backtrack.Thisstatetakescareofemittingcharacters *orappendingtothecurrentattributevalue.Italso *takescareofthatinthecasewhenconsumingthe *characterreferencefails.
*/ /* *Thissectiondefineshowtoconsumeacharacter *reference.Thisdefinitionisusedwhenparsingcharacter *referencesintextandinattributes. * *Thebehaviordependsontheidentityofthenext *character(theoneimmediatelyaftertheU+0026AMPERSAND *character):
*/ switch (c) { case' ': case'\t': case'\n': case'\r': // we'll reconsume! case'\u000C': case'<': case'&': case'\u0000': case';':
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop; case'#': /* *U+0023NUMBERSIGN(#)ConsumetheU+0023NUMBER *SIGN.
*/
appendCharRefBuf('#');
state = transition(state, Tokenizer.CONSUME_NCR, reconsume, pos); continue stateloop; default: if (c == additional) {
emitOrAppendCharRefBuf(returnState);
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} if (c >= 'a' && c <= 'z') {
firstCharKey = c - 'a' + 26;
} elseif (c >= 'A' && c <= 'Z') {
firstCharKey = c - 'A';
} else { // No match if (c == ';') {
errNoNamedCharacterMatch();
}
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} // Didn't fail yet
appendCharRefBuf(c);
state = transition(state, Tokenizer.CHARACTER_REFERENCE_HILO_LOOKUP, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break;
} // CPPONLY: MOZ_FALLTHROUGH; case CHARACTER_REFERENCE_HILO_LOOKUP:
{ if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Thedatastructureisasfollows: * *HILO_ACCELisatwo-dimensionalintarraywhosemajor *indexcorrespondstothesecondcharacterofthe *characterreference(codepointasindex)andthe *minorindexcorrespondstothefirstcharacterofthe *characterreference(packedsothatA-Zrunsfrom0 *to25anda-zrunsfrom26to51).Thislayoutmakes *iteasiertousethesparsenessofthedatastructure *toomitpartsofit:Theseconddimensionofthe *tableisnullwhennocharacterreferencestartswith *thecharactercorrespondingtothatrow. * *TheintvalueHILO_ACCEL(bytheseindeces)iszero *ifthereexistsnocharacterreferencestartingwith *thattwo-letterprefix.Otherwise,thevalueisan *intthatpackstwoshortssothatthehighershortis *theindexofthehighestcharacterreferencename *withthatprefixinNAMESandthelowershort *correspondstotheindexofthelowestcharacter *referencenamewiththatprefix.(Ithappensthatthe *firsttwocharacterreferencenamessharetheir *prefixsothepackedintcannotbe0bypackingthe *twoshorts.) * *NAMESisanarrayofbytearrayswhereeachbyte *arrayencodesthenameofacharacterreferencesas *ASCII.Thenamesomitthefirsttwolettersofthe *name.(Sincestoringthefirsttwoletterswouldbe *redundantwiththedatacontainedinHILO_ACCEL.)The *entriesarelexicallysorted. * *ForagivenindexinNAMES,thesameindexinVALUES *containsthecorrespondingexpansionasanarrayof *twoUTF-16codeunits(eitherthecharacterand *U+0000orasuggogatepair).
*/ int hilo = 0; if (c <= 'z') {
@Const @NoLength int[] row = NamedCharactersAccel.HILO_ACCEL[c]; if (row != null) {
hilo = row[firstCharKey];
}
} if (hilo == 0) { if (c == ';') {
errNoNamedCharacterMatch();
}
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} // Didn't fail yet
appendCharRefBuf(c);
lo = hilo & 0xFFFF;
hi = hilo >> 16;
entCol = -1;
candidate = -1;
charRefBufMark = 0;
state = transition(state, Tokenizer.CHARACTER_REFERENCE_TAIL, reconsume, pos); // fallthrough optimizes; `continue stateloop;` would also be valid
} // CPPONLY: MOZ_FALLTHROUGH; case CHARACTER_REFERENCE_TAIL:
outer: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
entCol++; /* *Consumethemaximumnumberofcharacterspossible, *withtheconsumedcharactersmatchingoneofthe *identifiersinthefirstcolumnofthenamed *characterreferencestable(inacase-sensitive *manner).
*/
loloop: for (;;) { if (hi < lo) { break outer;
} if (entCol == NamedCharacters.NAMES[lo].length()) {
candidate = lo;
charRefBufMark = charRefBufLen;
lo++;
} elseif (entCol > NamedCharacters.NAMES[lo].length()) { break outer;
} elseif (c > NamedCharacters.NAMES[lo].charAt(entCol)) {
lo++;
} else { break loloop;
}
}
if (c == ';') { // If we see a semicolon, there cannot be a // longer match. Break the loop. However, before // breaking, take the longest match so far as the // candidate, if we are just about to complete a // match. if (entCol + 1 == NamedCharacters.NAMES[lo].length()) {
candidate = lo;
charRefBufMark = charRefBufLen;
} break outer;
}
if (candidate == -1) { // reconsume deals with CR, LF or nul if (c == ';') {
errNoNamedCharacterMatch();
}
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} else { // c can't be CR, LF or nul if we got here
@Const @CharacterName String candidateName = NamedCharacters.NAMES[candidate]; if (candidateName.length() == 0
|| candidateName.charAt(candidateName.length() - 1) != ';') { /* *IfthelastcharactermatchedisnotaU+003B *SEMICOLON(;),thereisaparseerror.
*/ if ((returnState & DATA_AND_RCDATA_MASK) != 0) { /* *Iftheentityisbeingconsumedaspartofan *attribute,andthelastcharactermatchedis *notaU+003BSEMICOLON(;),
*/ char ch; if (charRefBufMark == charRefBufLen) {
ch = c;
} else {
ch = charRefBuf[charRefBufMark];
} if (ch == '=' || (ch >= '0' && ch <= '9')
|| (ch >= 'A' && ch <= 'Z')
|| (ch >= 'a' && ch <= 'z')) { /* *andthenextcharacteriseitheraU+003D *EQUALSSIGNcharacter(=)orintherange *U+0030DIGITZEROtoU+0039DIGITNINE, *U+0041LATINCAPITALLETTERAtoU+005A *LATINCAPITALLETTERZ,orU+0061LATIN *SMALLLETTERAtoU+007ALATINSMALL *LETTERZ,then,forhistoricalreasons, *allthecharactersthatwerematched *aftertheU+0026AMPERSAND(&)mustbe *unconsumed,andnothingisreturned.
*/ if (c == ';') {
errNoNamedCharacterMatch();
}
appendCharRefBufToStrBuf();
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
} if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
errUnescapedAmpersandInterpretedAsCharacterReference();
} else {
errNotSemicolonTerminated();
}
}
/* *Otherwise,returnacharactertokenforthecharacter *correspondingtotheentityname(asgivenbythe *secondcolumnofthenamedcharacterreferences *table).
*/ // CPPONLY: completedNamedCharacterReference();
@Const @NoLength char[] val = NamedCharacters.VALUES[candidate]; if ( // [NOCPP[
val.length == 1 // ]NOCPP] // CPPONLY: val[1] == 0
) {
emitOrAppendOne(val, returnState);
} else {
emitOrAppendTwo(val, returnState);
} // this is so complicated! if (charRefBufMark < charRefBufLen) { if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
appendStrBuf(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
} else {
tokenHandler.characters(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
}
} // charRefBufLen will be zeroed below!
// Check if we broke out early with c being the last // character that matched as opposed to being the // first one that didn't match. In the case of an // early break, the next run on text should start // *after* the current character and the current // character shouldn't be reconsumed. boolean earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
charRefBufLen = 0; if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = earlyBreak ? pos + 1 : pos;
}
reconsume = !earlyBreak;
state = transition(state, returnState, reconsume, pos); continue stateloop; /* *IfthemarkupcontainsI'm¬it;Itellyou,the *entityisparsedas"not",asin,I'm¬it;Itell *you.ButifthemarkupwasI'm∉Itellyou, *theentitywouldbeparsedas"notin;",resultingin *I'm∉Itellyou.
*/
} // no fallthrough, reordering opportunity case CONSUME_NCR: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
value = 0;
seenDigits = false; /* *Thebehaviorfurtherdependsonthecharacterafterthe *U+0023NUMBERSIGN:
*/ switch (c) { case'x': case'X':
/* *U+0078LATINSMALLLETTERXU+0058LATINCAPITAL *LETTERXConsumetheX. * *Followthestepsbelow,butusingtherangeof *charactersU+0030DIGITZEROthroughtoU+0039 *DIGITNINE,U+0061LATINSMALLLETTERAthrough *toU+0066LATINSMALLLETTERF,andU+0041LATIN *CAPITALLETTERA,throughtoU+0046LATINCAPITAL *LETTERF(inotherwords,0-9,A-F,a-f). * *Whenitcomestointerpretingthenumber, *interpretitasahexadecimalnumber.
*/
appendCharRefBuf(c);
state = transition(state, Tokenizer.HEX_NCR_LOOP, reconsume, pos); continue stateloop; default: /* *AnythingelseFollowthestepsbelow,butusing *therangeofcharactersU+0030DIGITZEROthrough *toU+0039DIGITNINE(i.e.just0-9). * *Whenitcomestointerpretingthenumber, *interpretitasadecimalnumber.
*/
reconsume = true;
state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break;
} // CPPONLY: MOZ_FALLTHROUGH; case DECIMAL_NRC_LOOP:
decimalloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumeasmanycharactersasmatchtherangeof *charactersgivenabove.
*/ assert value >= 0: "value must not become negative."; if (c >= '0' && c <= '9') {
seenDigits = true; // Avoid overflow if (value <= 0x10FFFF) {
value *= 10;
value += c - '0';
} continue;
} elseif (c == ';') { if (seenDigits) { if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos + 1;
}
state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break decimalloop;
} else {
errNoDigitsInNCR();
appendCharRefBuf(';');
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos + 1;
}
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
} else { /* *Ifnocharactersmatchtherange,thendon't *consumeanycharacters(andunconsumetheU+0023 *NUMBERSIGNcharacterand,ifappropriate,theX *character).Thisisaparseerror;nothingis *returned. * *Otherwise,ifthenextcharacterisaU+003B *SEMICOLON,consumethattoo.Ifitisn't,there *isaparseerror.
*/ if (!seenDigits) {
errNoDigitsInNCR();
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} else {
errCharRefLacksSemicolon(); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break decimalloop;
}
}
} // CPPONLY: MOZ_FALLTHROUGH; case HANDLE_NCR_VALUE: // WARNING previous state sets reconsume // We are not going to emit the contents of charRefBuf.
charRefBufLen = 0; // XXX inline this case if the method size can take it
handleNcrValue(returnState);
state = transition(state, returnState, reconsume, pos); continue stateloop; // no fallthrough, reordering opportunity case HEX_NCR_LOOP: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumeasmanycharactersasmatchtherangeof *charactersgivenabove.
*/ assert value >= 0: "value must not become negative."; if (c >= '0' && c <= '9') {
seenDigits = true; // Avoid overflow if (value <= 0x10FFFF) {
value *= 16;
value += c - '0';
} continue;
} elseif (c >= 'A' && c <= 'F') {
seenDigits = true; // Avoid overflow if (value <= 0x10FFFF) {
value *= 16;
value += c - 'A' + 10;
} continue;
} elseif (c >= 'a' && c <= 'f') {
seenDigits = true; // Avoid overflow if (value <= 0x10FFFF) {
value *= 16;
value += c - 'a' + 10;
} continue;
} elseif (c == ';') { if (seenDigits) { if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos + 1;
}
state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); continue stateloop;
} else {
errNoDigitsInNCR();
appendCharRefBuf(';');
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos + 1;
}
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
} else { /* *Ifnocharactersmatchtherange,thendon't *consumeanycharacters(andunconsumetheU+0023 *NUMBERSIGNcharacterand,ifappropriate,theX *character).Thisisaparseerror;nothingis *returned. * *Otherwise,ifthenextcharacterisaU+003B *SEMICOLON,consumethattoo.Ifitisn't,there *isaparseerror.
*/ if (!seenDigits) {
errNoDigitsInNCR();
emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} else {
errCharRefLacksSemicolon(); if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
cstart = pos;
}
reconsume = true;
state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); continue stateloop;
}
}
} // no fallthrough, reordering opportunity case PLAINTEXT:
plaintextloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementPlaintext(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case'\u0000':
emitPlaintextReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Stayinthe *RAWTEXTstate.
*/ continue;
}
} // no fallthrough, reordering opportunity case CLOSE_TAG_OPEN: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Otherwise,ifthecontentmodelflagissettothePCDATA *state,orifthenextfewcharactersdomatchthattag *name,consumethenextinputcharacter:
*/ switch (c) { case'>': /* U+003E GREATER-THAN SIGN (>) Parse error. */
errLtSlashGt(); /* *Switchtothedatastate.
*/
cstart = pos + 1;
state = transition(state, Tokenizer.DATA, reconsume, pos); continue stateloop; case'\r':
silentCarriageReturn(); /* Anything else Parse error. */
errGarbageAfterLtSlash(); /* *Switchtotheboguscommentstate.
*/
clearStrBufBeforeUse();
appendStrBuf('\n');
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); /* Anything else Parse error. */
errGarbageAfterLtSlash(); /* *Switchtotheboguscommentstate.
*/
clearStrBufBeforeUse();
appendStrBuf(c);
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: if (c >= 'A' && c <= 'Z') {
c += 0x20;
} if (c >= 'a' && c <= 'z') { /* *U+0061LATINSMALLLETTERAthroughtoU+007A *LATINSMALLLETTERZCreateanewendtag *token,
*/
endTag = true; /* *setitstagnametotheinputcharacter,
*/
clearStrBufBeforeUse();
appendStrBuf(c);
containsHyphen = false; /* *thenswitchtothetagnamestate.(Don't *emitthetokenyet;furtherdetailswillbe *filledinbeforeitisemitted.)
*/
state = transition(state, Tokenizer.TAG_NAME, reconsume, pos); continue stateloop;
} else { /* Anything else Parse error. */
errGarbageAfterLtSlash(); /* *Switchtotheboguscommentstate.
*/
clearStrBufBeforeUse();
appendStrBuf(c);
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case RCDATA:
rcdataloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // RCDATA and DATA have the same set of characters that they are indifferent to, hence accelerateData. // CPPONLY: pos += accelerateAdvancementData(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case'&': /* *U+0026AMPERSAND(&)Switchtothecharacter *referenceinRCDATAstate.
*/
flushChars(buf, pos); assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\u0000');
returnState = state;
state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); continue stateloop; case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *RCDATAless-thansignstate.
*/
flushChars(buf, pos);
returnState = state;
state = transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *Emitthecurrentinputcharacterasa *charactertoken.StayintheRCDATAstate.
*/ continue;
}
} // no fallthrough, reordering opportunity case RAWTEXT:
rawtextloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementRawtext(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *RAWTEXTless-thansignstate.
*/
flushChars(buf, pos);
returnState = state;
state = transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break rawtextloop; case'\u0000':
emitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *Emitthecurrentinputcharacterasa *charactertoken.StayintheRAWTEXTstate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case RAWTEXT_RCDATA_LESS_THAN_SIGN:
rawtextrcdatalessthansignloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'/': /* *U+002FSOLIDUS(/)Setthetemporarybuffer *totheemptystring.Switchtothescript *dataendtagopenstate.
*/
index = 0;
clearStrBufBeforeUse();
state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break rawtextrcdatalessthansignloop; default: /* *Otherwise,emitaU+003CLESS-THANSIGN *charactertoken
*/
tokenHandler.characters(Tokenizer.LT_GT, 0, 1); /* *andreconsumethecurrentinputcharacterin *thedatastate.
*/
cstart = pos;
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case NON_DATA_END_TAG_NAME: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *ASSERT!whenenteringthisstate,setindexto0and *callclearStrBufBeforeUse();Let'simplementtheabove *withoutlookahead.strBufisthe'temporarybuffer'.
*/ if (endTagExpectationAsArray == null) {
tokenHandler.characters(Tokenizer.LT_SOLIDUS, 0, 2);
cstart = pos;
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
} elseif (index < endTagExpectationAsArray.length) { char e = endTagExpectationAsArray[index]; char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded != e) { // [NOCPP[
errHtml4LtSlashInRcdata(folded); // ]NOCPP]
tokenHandler.characters(Tokenizer.LT_SOLIDUS, 0, 2);
emitStrBuf();
cstart = pos;
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
appendStrBuf(c);
index++; continue;
} else {
endTag = true; // XXX replace contentModelElement with different // type
tagName = endTagExpectation; switch (c) { case'\r':
silentCarriageReturn();
clearStrBufAfterUse(); // strBuf not used
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINE *FEED(LF)U+000CFORMFEED(FF)U+0020 *SPACEIfthecurrentendtagtokenisan *appropriateendtagtoken,thenswitchto *thebeforeattributenamestate.
*/
clearStrBufAfterUse(); // strBuf not used
state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); continue stateloop; case'/': /* *U+002FSOLIDUS(/)Ifthecurrentendtag *tokenisanappropriateendtagtoken, *thenswitchtotheself-closingstarttag *state.
*/
clearStrBufAfterUse(); // strBuf not used
state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos); continue stateloop; case'>': /* *U+003EGREATER-THANSIGN(>)Ifthe *currentendtagtokenisanappropriate *endtagtoken,thenemitthecurrenttag *tokenandswitchtothedatastate.
*/
clearStrBufAfterUse(); // strBuf not used
state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default: /* *EmitaU+003CLESS-THANSIGNcharacter *token,aU+002FSOLIDUScharactertoken, *acharactertokenforeachofthe *charactersinthetemporarybuffer(in *theordertheywereaddedtothebuffer), *andreconsumethecurrentinputcharacter *intheRAWTEXTstate.
*/ // [NOCPP[
errWarnLtSlashInRcdata(); // ]NOCPP]
tokenHandler.characters(
Tokenizer.LT_SOLIDUS, 0, 2);
emitStrBuf();
cstart = pos; // don't drop the // character
reconsume = true;
state = transition(state, returnState, reconsume, pos); continue stateloop;
}
}
} // no fallthrough, reordering opportunity // BEGIN HOTSPOT WORKAROUND case BOGUS_COMMENT:
boguscommentloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumeeverycharacteruptoandincludingthefirst *U+003EGREATER-THANSIGNcharacter(>)ortheendof *thefile(EOF),whichevercomesfirst.Emitacomment *tokenwhosedataistheconcatenationofallthe *charactersstartingfromandincludingthecharacter *thatcausedthestatemachinetoswitchintothe *boguscommentstate,uptoandincludingthe *characterimmediatelybeforethelastconsumed *character(i.e.uptothecharacterjustbeforethe *U+003EorEOFcharacter).(Ifthecommentwasstarted *bytheendofthefile(EOF),thetokenisempty.) * *Switchtothedatastate. * *Iftheendofthefilewasreached,reconsumetheEOF *character.
*/ switch (c) { case'>':
emitComment(0, pos);
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'-':
appendStrBuf(c);
state = transition(state, Tokenizer.BOGUS_COMMENT_HYPHEN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break boguscommentloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
appendStrBuf(c); continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BOGUS_COMMENT_HYPHEN:
boguscommenthyphenloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'>': // [NOCPP[
maybeAppendSpaceToBogusComment(); // ]NOCPP]
emitComment(0, pos);
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'-':
appendSecondHyphenToBogusComment(); continue boguscommenthyphenloop; case'\r':
appendStrBufCarriageReturn();
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); break stateloop; case'\n':
appendStrBufLineFeed();
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default:
appendStrBuf(c);
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case SCRIPT_DATA:
scriptdataloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // Using `accelerateAdvancementRawtext`, because this states has the same characters of interest as RAWTEXT. // CPPONLY: pos += accelerateAdvancementRawtext(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} switch (c) { case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *scriptdataless-thansignstate.
*/
flushChars(buf, pos);
returnState = state;
state = transition(state, Tokenizer.SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataloop; case'\u0000':
emitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Stayinthe *scriptdatastate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_LESS_THAN_SIGN:
scriptdatalessthansignloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'/': /* *U+002FSOLIDUS(/)Setthetemporarybuffer *totheemptystring.Switchtothescript *dataendtagopenstate.
*/
index = 0;
clearStrBufBeforeUse();
state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos); continue stateloop; case'!':
tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
cstart = pos;
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatalessthansignloop; default: /* *Otherwise,emitaU+003CLESS-THANSIGN *charactertoken
*/
tokenHandler.characters(Tokenizer.LT_GT, 0, 1); /* *andreconsumethecurrentinputcharacterin *thedatastate.
*/
cstart = pos;
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPE_START:
scriptdataescapestartloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdataescapestartdashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapestartloop; default: /* *AnythingelseReconsumethecurrentinput *characterinthescriptdatastate.
*/
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPE_START_DASH:
scriptdataescapestartdashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdataescapeddashdashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapestartdashloop; default: /* *AnythingelseReconsumethecurrentinput *characterinthescriptdatastate.
*/
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPED_DASH_DASH:
scriptdataescapeddashdashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Stayinthe *scriptdataescapeddashdashstate.
*/ continue; case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *scriptdataescapedless-thansignstate.
*/
flushChars(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos); continue stateloop; case'>': /* *U+003EGREATER-THANSIGN(>)EmitaU+003E *GREATER-THANSIGNcharactertoken.Switchto *thescriptdatastate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); break scriptdataescapeddashdashloop; case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Switchtothe *scriptdataescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapeddashdashloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPED:
scriptdataescapedloop: for (;;) { if (reconsume) {
reconsume = false;
} else {
++pos; // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today. // The line below advances pos by some number of code units that this state is indifferent to. // CPPONLY: pos += accelerateAdvancementScriptDataEscaped(buf, pos, endPos); if (pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdataescapeddashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapedloop; case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *scriptdataescapedless-thansignstate.
*/
flushChars(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Stayinthe *scriptdataescapedstate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPED_DASH:
scriptdataescapeddashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdataescapeddashdashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos); continue stateloop; case'<': /* *U+003CLESS-THANSIGN(<)Switchtothe *scriptdataescapedless-thansignstate.
*/
flushChars(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapeddashloop; case'\u0000':
emitReplacementCharacter(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop; case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Switchtothe *scriptdataescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
scriptdataescapedlessthanloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'/': /* *U+002FSOLIDUS(/)Setthetemporarybuffer *totheemptystring.Switchtothescript *dataescapedendtagopenstate.
*/
index = 0;
clearStrBufBeforeUse();
returnState = Tokenizer.SCRIPT_DATA_ESCAPED;
state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos); continue stateloop; case'S': case's': /* *U+0041LATINCAPITALLETTERAthroughto *U+005ALATINCAPITALLETTERZEmitaU+003C *LESS-THANSIGNcharactertokenandthe *currentinputcharacterasacharactertoken.
*/
tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
cstart = pos;
index = 1; /* *Setthetemporarybuffertotheemptystring. *Appendthelowercaseversionofthecurrent *inputcharacter(add0x0020tothe *character'scodepoint)tothetemporary *buffer.Switchtothescriptdatadouble *escapestartstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdataescapedlessthanloop; default: /* *AnythingelseEmitaU+003CLESS-THANSIGN *charactertokenandreconsumethecurrent *inputcharacterinthescriptdataescaped *state.
*/
tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
cstart = pos;
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPE_START:
scriptdatadoubleescapestartloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); assert index > 0; if (index < 6) { // SCRIPT_ARR.length char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded != Tokenizer.SCRIPT_ARR[index]) {
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop;
}
index++; continue;
} switch (c) { case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': case'/': case'>': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *U+002FSOLIDUS(/)U+003EGREATER-THANSIGN *(>)Emitthecurrentinputcharacterasa *charactertoken.Ifthetemporarybufferis *thestring"script",thenswitchtothe *scriptdatadoubleescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatadoubleescapestartloop; default: /* *AnythingelseReconsumethecurrentinput *characterinthescriptdataescapedstate.
*/
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPED:
scriptdatadoubleescapedloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdatadoubleescapeddashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatadoubleescapedloop; case'<': /* *U+003CLESS-THANSIGN(<)EmitaU+003C *LESS-THANSIGNcharactertoken.Switchtothe *scriptdatadoubleescapedless-thansign *state.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos); continue; case'\r':
emitCarriageReturn(buf, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Stayinthe *scriptdatadoubleescapedstate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
scriptdatadoubleescapeddashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Switchtothe *scriptdatadoubleescapeddashdashstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatadoubleescapeddashloop; case'<': /* *U+003CLESS-THANSIGN(<)EmitaU+003C *LESS-THANSIGNcharactertoken.Switchtothe *scriptdatadoubleescapedless-thansign *state.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop; case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Switchtothe *scriptdatadoubleescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
scriptdatadoubleescapeddashdashloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'-': /* *U+002DHYPHEN-MINUS(-)EmitaU+002D *HYPHEN-MINUScharactertoken.Stayinthe *scriptdatadoubleescapeddashdashstate.
*/ continue; case'<': /* *U+003CLESS-THANSIGN(<)EmitaU+003C *LESS-THANSIGNcharactertoken.Switchtothe *scriptdatadoubleescapedless-thansign *state.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatadoubleescapeddashdashloop; case'>': /* *U+003EGREATER-THANSIGN(>)EmitaU+003E *GREATER-THANSIGNcharactertoken.Switchto *thescriptdatastate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); continue stateloop; case'\u0000':
emitReplacementCharacter(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop; case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseEmitthecurrentinput *characterasacharactertoken.Switchtothe *scriptdatadoubleescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
scriptdatadoubleescapedlessthanloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'/': /* *U+002FSOLIDUS(/)EmitaU+002FSOLIDUS *charactertoken.Setthetemporarybufferto *theemptystring.Switchtothescriptdata *doubleescapeendstate.
*/
index = 0;
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break scriptdatadoubleescapedlessthanloop; default: /* *AnythingelseReconsumethecurrentinput *characterinthescriptdatadoubleescaped *state.
*/
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case SCRIPT_DATA_DOUBLE_ESCAPE_END:
scriptdatadoubleescapeendloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); if (index < 6) { // SCRIPT_ARR.length char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded != Tokenizer.SCRIPT_ARR[index]) {
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop;
}
index++; continue;
} switch (c) { case'\r':
emitCarriageReturn(buf, pos);
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': case'/': case'>': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *U+002FSOLIDUS(/)U+003EGREATER-THANSIGN *(>)Emitthecurrentinputcharacterasa *charactertoken.Ifthetemporarybufferis *thestring"script",thenswitchtothe *scriptdataescapedstate.
*/
state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos); continue stateloop; default: /* *Reconsumethecurrentinputcharacterinthe *scriptdatadoubleescapedstate.
*/
reconsume = true;
state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos); continue stateloop;
}
} // no fallthrough, reordering opportunity case MARKUP_DECLARATION_OCTYPE:
markupdeclarationdoctypeloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); if (index < 6) { // OCTYPE.length char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded == Tokenizer.OCTYPE[index]) {
appendStrBuf(c);
} else {
errBogusComment();
reconsume = true;
state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); continue stateloop;
}
index++; continue;
} else {
reconsume = true;
state = transition(state, Tokenizer.DOCTYPE, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break markupdeclarationdoctypeloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE:
doctypeloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
}
initDoctypeFields(); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *SwitchtothebeforeDOCTYPEnamestate.
*/
state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypeloop; default: /* *AnythingelseParseerror.
*/
errMissingSpaceBeforeDoctypeName(); /* *Reconsumethecurrentcharacterinthebefore *DOCTYPEnamestate.
*/
reconsume = true;
state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypeloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BEFORE_DOCTYPE_NAME:
beforedoctypenameloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *inthebeforeDOCTYPEnamestate.
*/ continue; case'>': /* *U+003EGREATER-THANSIGN(>)Parseerror.
*/
errNamelessDoctype(); /* *CreateanewDOCTYPEtoken.Setits *force-quirksflagtoon.
*/
forceQuirks = true; /* *Emitthetoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: if (c >= 'A' && c <= 'Z') { /* *U+0041LATINCAPITALLETTERAthroughto *U+005ALATINCAPITALLETTERZCreatea *newDOCTYPEtoken.Setthetoken'sname *tothelowercaseversionoftheinput *character(add0x0020tothecharacter's *codepoint).
*/
c += 0x20;
} /* Anything else Create a new DOCTYPE token. */ /* *Setthetoken'snamenametothecurrent *inputcharacter.
*/
clearStrBufBeforeUse();
appendStrBuf(c); /* *SwitchtotheDOCTYPEnamestate.
*/
state = transition(state, Tokenizer.DOCTYPE_NAME, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break beforedoctypenameloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE_NAME:
doctypenameloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
strBufToDoctypeName();
state = transition(state, Tokenizer.AFTER_DOCTYPE_NAME, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *SwitchtotheafterDOCTYPEnamestate.
*/
strBufToDoctypeName();
state = transition(state, Tokenizer.AFTER_DOCTYPE_NAME, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypenameloop; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *DOCTYPEtoken.
*/
strBufToDoctypeName();
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *U+0041LATINCAPITALLETTERAthroughto *U+005ALATINCAPITALLETTERZAppendthe *lowercaseversionoftheinputcharacter(add *0x0020tothecharacter'scodepoint)tothe *currentDOCTYPEtoken'sname.
*/ if (c >= 'A' && c <= 'Z') {
c += 0x0020;
} /* *AnythingelseAppendthecurrentinput *charactertothecurrentDOCTYPEtoken's *name.
*/
appendStrBuf(c); /* *StayintheDOCTYPEnamestate.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_DOCTYPE_NAME:
afterdoctypenameloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *intheafterDOCTYPEnamestate.
*/ continue; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *DOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'p': case'P':
index = 0;
state = transition(state, Tokenizer.DOCTYPE_UBLIC, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterdoctypenameloop; case's': case'S':
index = 0;
state = transition(state, Tokenizer.DOCTYPE_YSTEM, reconsume, pos); continue stateloop; default: /* *Otherwise,thisistheparseerror.
*/
bogusDoctype();
/* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE_UBLIC:
doctypeublicloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Ifthesixcharactersstartingfromthecurrentinput *characterareanASCIIcase-insensitivematchforthe *word"PUBLIC",thenconsumethosecharactersand *switchtothebeforeDOCTYPEpublicidentifierstate.
*/ if (index < 5) { // UBLIC.length char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded != Tokenizer.UBLIC[index]) {
bogusDoctype(); // forceQuirks = true;
reconsume = true;
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
index++; continue;
} else {
reconsume = true;
state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypeublicloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_DOCTYPE_PUBLIC_KEYWORD:
afterdoctypepublickeywordloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
state = transition(state, Tokenizer.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *SwitchtothebeforeDOCTYPEpublic *identifierstate.
*/
state = transition(state, Tokenizer.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterdoctypepublickeywordloop; case'"': /* *U+0022QUOTATIONMARK(")ParseError.
*/
errNoSpaceBetweenDoctypePublicKeywordAndQuote(); /* *SettheDOCTYPEtoken'spublicidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); continue stateloop; case'\'': /* *U+0027APOSTROPHE(')ParseError.
*/
errNoSpaceBetweenDoctypePublicKeywordAndQuote(); /* *SettheDOCTYPEtoken'spublicidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); continue stateloop; case'>': /* U+003E GREATER-THAN SIGN (>) Parse error. */
errExpectedPublicId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
beforedoctypepublicidentifierloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *inthebeforeDOCTYPEpublicidentifier *state.
*/ continue; case'"': /* *U+0022QUOTATIONMARK(")SettheDOCTYPE *token'spublicidentifiertotheemptystring *(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break beforedoctypepublicidentifierloop; case'\'': /* *U+0027APOSTROPHE(')SettheDOCTYPEtoken's *publicidentifiertotheemptystring(not *missing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); continue stateloop; case'>': /* U+003E GREATER-THAN SIGN (>) Parse error. */
errExpectedPublicId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
doctypepublicidentifierdoublequotedloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'"': /* *U+0022QUOTATIONMARK(")Switchtotheafter *DOCTYPEpublicidentifierstate.
*/
publicIdentifier = strBufToString();
state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypepublicidentifierdoublequotedloop; case'>': /* *U+003EGREATER-THANSIGN(>)Parseerror.
*/
errGtInPublicId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
publicIdentifier = strBufToString();
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentDOCTYPEtoken's *publicidentifier.
*/
appendStrBuf(c); /* *StayintheDOCTYPEpublicidentifier *(double-quoted)state.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
afterdoctypepublicidentifierloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
state = transition(state, Tokenizer.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *SwitchtothebetweenDOCTYPEpublicand *systemidentifiersstate.
*/
state = transition(state, Tokenizer.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterdoctypepublicidentifierloop; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *DOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'"': /* *U+0022QUOTATIONMARK(")Parseerror.
*/
errNoSpaceBetweenPublicAndSystemIds(); /* *SettheDOCTYPEtoken'ssystemidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); continue stateloop; case'\'': /* *U+0027APOSTROPHE(')Parseerror.
*/
errNoSpaceBetweenPublicAndSystemIds(); /* *SettheDOCTYPEtoken'ssystemidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
betweendoctypepublicandsystemidentifiersloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *inthebetweenDOCTYPEpublicandsystem *identifiersstate.
*/ continue; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *DOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'"': /* *U+0022QUOTATIONMARK(")SettheDOCTYPE *token'ssystemidentifiertotheemptystring *(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break betweendoctypepublicandsystemidentifiersloop; case'\'': /* *U+0027APOSTROPHE(')SettheDOCTYPEtoken's *systemidentifiertotheemptystring(not *missing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
doctypesystemidentifierdoublequotedloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'"': /* *U+0022QUOTATIONMARK(")Switchtotheafter *DOCTYPEsystemidentifierstate.
*/
systemIdentifier = strBufToString();
state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypesystemidentifierdoublequotedloop; case'>': /* *U+003EGREATER-THANSIGN(>)Parseerror.
*/
errGtInSystemId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
systemIdentifier = strBufToString();
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentDOCTYPEtoken's *systemidentifier.
*/
appendStrBuf(c); /* *StayintheDOCTYPEsystemidentifier *(double-quoted)state.
*/ continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
afterdoctypesystemidentifierloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *intheafterDOCTYPEsystemidentifierstate.
*/ continue; case'>': /* *U+003EGREATER-THANSIGN(>)Emitthecurrent *DOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default: /* *SwitchtothebogusDOCTYPEstate.(Thisdoes *notsettheDOCTYPEtoken'sforce-quirksflag *toon.)
*/
bogusDoctypeWithoutQuirks();
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterdoctypesystemidentifierloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BOGUS_DOCTYPE: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'>': /* *U+003EGREATER-THANSIGN(>)Emitthat *DOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseStayinthebogusDOCTYPE *state.
*/ continue;
}
} // no fallthrough, reordering opportunity case DOCTYPE_YSTEM:
doctypeystemloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Otherwise,ifthesixcharactersstartingfromthe *currentinputcharacterareanASCIIcase-insensitive *matchfortheword"SYSTEM",thenconsumethose *charactersandswitchtothebeforeDOCTYPEsystem *identifierstate.
*/ if (index < 5) { // YSTEM.length char folded = c; if (c >= 'A' && c <= 'Z') {
folded += 0x20;
} if (folded != Tokenizer.YSTEM[index]) {
bogusDoctype();
reconsume = true;
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
index++; continue stateloop;
} else {
reconsume = true;
state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break doctypeystemloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case AFTER_DOCTYPE_SYSTEM_KEYWORD:
afterdoctypesystemkeywordloop: for (;;) { if (reconsume) {
reconsume = false;
} else { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos);
} /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn();
state = transition(state, Tokenizer.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACE *SwitchtothebeforeDOCTYPEpublic *identifierstate.
*/
state = transition(state, Tokenizer.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break afterdoctypesystemkeywordloop; case'"': /* *U+0022QUOTATIONMARK(")ParseError.
*/
errNoSpaceBetweenDoctypeSystemKeywordAndQuote(); /* *SettheDOCTYPEtoken'ssystemidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); continue stateloop; case'\'': /* *U+0027APOSTROPHE(')ParseError.
*/
errNoSpaceBetweenDoctypeSystemKeywordAndQuote(); /* *SettheDOCTYPEtoken'spublicidentifierto *theemptystring(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEpublicidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); continue stateloop; case'>': /* U+003E GREATER-THAN SIGN (>) Parse error. */
errExpectedPublicId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
beforedoctypesystemidentifierloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\r':
silentCarriageReturn(); break stateloop; case'\n':
silentLineFeed(); // CPPONLY: MOZ_FALLTHROUGH; case' ': case'\t': case'\u000C': /* *U+0009CHARACTERTABULATIONU+000ALINEFEED *(LF)U+000CFORMFEED(FF)U+0020SPACEStay *inthebeforeDOCTYPEsystemidentifier *state.
*/ continue; case'"': /* *U+0022QUOTATIONMARK(")SettheDOCTYPE *token'ssystemidentifiertotheemptystring *(notmissing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(double-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos); continue stateloop; case'\'': /* *U+0027APOSTROPHE(')SettheDOCTYPEtoken's *systemidentifiertotheemptystring(not *missing),
*/
clearStrBufBeforeUse(); /* *thenswitchtotheDOCTYPEsystemidentifier *(single-quoted)state.
*/
state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break beforedoctypesystemidentifierloop; case'>': /* U+003E GREATER-THAN SIGN (>) Parse error. */
errExpectedSystemId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
bogusDoctype(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/ // done by bogusDoctype(); /* *SwitchtothebogusDOCTYPEstate.
*/
state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); continue stateloop;
}
} // CPPONLY: MOZ_FALLTHROUGH; case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\'': /* *U+0027APOSTROPHE(')Switchtotheafter *DOCTYPEsystemidentifierstate.
*/
systemIdentifier = strBufToString();
state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos); continue stateloop; case'>':
errGtInSystemId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
systemIdentifier = strBufToString();
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentDOCTYPEtoken's *systemidentifier.
*/
appendStrBuf(c); /* *StayintheDOCTYPEsystemidentifier *(double-quoted)state.
*/ continue;
}
} // no fallthrough, reordering opportunity case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); /* *Consumethenextinputcharacter:
*/ switch (c) { case'\'': /* *U+0027APOSTROPHE(')Switchtotheafter *DOCTYPEpublicidentifierstate.
*/
publicIdentifier = strBufToString();
state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos); continue stateloop; case'>':
errGtInPublicId(); /* *SettheDOCTYPEtoken'sforce-quirksflagto *on.
*/
forceQuirks = true; /* *EmitthatDOCTYPEtoken.
*/
publicIdentifier = strBufToString();
emitDoctypeToken(pos); /* *Switchtothedatastate.
*/
state = transition(state, Tokenizer.DATA, reconsume, pos); if (shouldSuspend) { break stateloop;
} continue stateloop; case'\r':
appendStrBufCarriageReturn(); break stateloop; case'\n':
appendStrBufLineFeed(); continue; case'\u0000':
c = '\uFFFD'; // CPPONLY: MOZ_FALLTHROUGH; default: /* *AnythingelseAppendthecurrentinput *charactertothecurrentDOCTYPEtoken's *publicidentifier.
*/
appendStrBuf(c); /* *StayintheDOCTYPEpublicidentifier *(single-quoted)state.
*/ continue;
}
} // no fallthrough, reordering opportunity case PROCESSING_INSTRUCTION:
processinginstructionloop: for (;;) { if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'?':
state = transition(
state,
Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK,
reconsume, pos); // `break` optimizes; `continue stateloop;` would be valid break processinginstructionloop; default: continue;
}
} // CPPONLY: MOZ_FALLTHROUGH; case PROCESSING_INSTRUCTION_QUESTION_MARK: if (++pos == endPos) { break stateloop;
}
c = checkChar(buf, pos); switch (c) { case'>':
state = transition(state, Tokenizer.DATA,
reconsume, pos); // Processing instruction syntax goes through these // states only in Gecko's XML View Source--not in HTML // parsing in Java or in Gecko. // Since XML View Source doesn't use the // suspension-after-current-token facility, its extension // to processing-instruction states is strictly unnecessary // at the moment. However, if these states ever were to be // used together with the suspension-after-current-token // facility, these states would need to participate, since // suspension could be requested when only less-than has been // seen and we don't yet know if we end up here. Handling // the currently-unnecessary case in order to avoid leaving // a trap for future modification.
suspendIfRequestedAfterCurrentNonTextToken(); if (shouldSuspend) { break stateloop;
} continue stateloop; default:
state = transition(state,
Tokenizer.PROCESSING_INSTRUCTION,
reconsume, pos); continue stateloop;
} // END HOTSPOT WORKAROUND
}
}
flushChars(buf, pos); /* *if(prevCR&&pos!=endPos){// why is this needed? pos--; col--; }
*/ // Save locals
stateSave = state;
returnStateSave = returnState; return pos;
}
// HOTSPOT WORKAROUND INSERTION POINT
// [NOCPP[
protectedint transition(int from, int to, boolean reconsume, int pos) throws SAXException { return to;
}
// ]NOCPP]
privatevoid initDoctypeFields() { // Discard the characters "DOCTYPE" accumulated as a potential bogus // comment into strBuf.
clearStrBufAfterUse();
doctypeName = null; if (systemIdentifier != null) {
Portability.releaseString(systemIdentifier);
systemIdentifier = null;
} if (publicIdentifier != null) {
Portability.releaseString(publicIdentifier);
publicIdentifier = null;
}
forceQuirks = false;
}
/* *Otherwise,returnacharactertokenforthecharacter *correspondingtotheentityname(asgivenbythe *secondcolumnofthenamedcharacterreferences *table).
*/
@Const @NoLength char[] val = NamedCharacters.VALUES[candidate]; if ( // [NOCPP[
val.length == 1 // ]NOCPP] // CPPONLY: val[1] == 0
) {
emitOrAppendOne(val, returnState);
} else {
emitOrAppendTwo(val, returnState);
} // this is so complicated! if (charRefBufMark < charRefBufLen) { if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
appendStrBuf(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
} else {
tokenHandler.characters(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
}
}
charRefBufLen = 0;
state = returnState; continue eofloop; /* *IfthemarkupcontainsI'm¬it;Itellyou,the *entityisparsedas"not",asin,I'm¬it;Itell *you.ButifthemarkupwasI'm∉Itellyou, *theentitywouldbeparsedas"notin;",resultingin *I'm∉Itellyou.
*/
} case CONSUME_NCR: case DECIMAL_NRC_LOOP: case HEX_NCR_LOOP: /* *Ifnocharactersmatchtherange,thendon'tconsumeany *characters(andunconsumetheU+0023NUMBERSIGN *characterand,ifappropriate,theXcharacter).Thisis *aparseerror;nothingisreturned. * *Otherwise,ifthenextcharacterisaU+003BSEMICOLON, *consumethattoo.Ifitisn't,thereisaparseerror.
*/ if (!seenDigits) {
errNoDigitsInNCR();
emitOrAppendCharRefBuf(returnState);
state = returnState; continue;
} else {
errCharRefLacksSemicolon();
} // WARNING previous state sets reconsume
handleNcrValue(returnState);
state = returnState; continue; case CDATA_RSQB:
tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1); break eofloop; case CDATA_RSQB_RSQB:
tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2); break eofloop; case DATA: default: break eofloop;
}
} // case DATA: /* *EOFEmitanend-of-filetoken.
*/
tokenHandler.eof(); return;
}
/** *Emitsadoctypetoken. * *NOTE:Themethodmayset<code>shouldSuspend</code>,sothecaller *musthavethispatternafterthestate's<code>transition</code>call: *<pre> *if(shouldSuspend){ *breakstateloop; *} *continuestateloop; *</pre> * *@parampos *@throwsSAXException
*/ privatevoid emitDoctypeToken(int pos) throws SAXException { // CPPONLY: RememberGt(pos);
cstart = pos + 1;
tokenHandler.doctype(doctypeName, publicIdentifier, systemIdentifier,
forceQuirks); // It is OK and sufficient to release these here, since // there's no way out of the doctype states than through paths // that call this method.
doctypeName = null;
Portability.releaseString(publicIdentifier);
publicIdentifier = null;
Portability.releaseString(systemIdentifier);
systemIdentifier = null;
suspendIfRequestedAfterCurrentNonTextToken();
}
// Making this private until the full Java implementation is done. /** *Requestsuspensionafterthecurrenttokenifthetokenizeriscurrently *inanon-textstate(i.e.it'sknownthatthenexttokenwillbea *non-texttoken). * *Mustnotbecalledwhen<code>tokenizeBuffer()</code>isonthecall *stack.
*/
@SuppressWarnings("unused") privatevoid suspendAfterCurrentTokenIfNotInText() { switch (stateSave) { case DATA: case RCDATA: case SCRIPT_DATA: case RAWTEXT: case SCRIPT_DATA_ESCAPED: case PLAINTEXT: case NON_DATA_END_TAG_NAME: // We haven't yet committed to the next // token being a non-text token, though // it could be. case SCRIPT_DATA_LESS_THAN_SIGN: case SCRIPT_DATA_ESCAPE_START: case SCRIPT_DATA_ESCAPE_START_DASH: case SCRIPT_DATA_ESCAPED_DASH: case SCRIPT_DATA_ESCAPED_DASH_DASH: case RAWTEXT_RCDATA_LESS_THAN_SIGN: case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: case SCRIPT_DATA_DOUBLE_ESCAPE_START: case SCRIPT_DATA_DOUBLE_ESCAPED: case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: case SCRIPT_DATA_DOUBLE_ESCAPE_END: return; case TAG_NAME: case BEFORE_ATTRIBUTE_NAME: case ATTRIBUTE_NAME: case AFTER_ATTRIBUTE_NAME: case BEFORE_ATTRIBUTE_VALUE: case AFTER_ATTRIBUTE_VALUE_QUOTED: case BOGUS_COMMENT: case MARKUP_DECLARATION_OPEN: case DOCTYPE: case BEFORE_DOCTYPE_NAME: case DOCTYPE_NAME: case AFTER_DOCTYPE_NAME: case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: case BOGUS_DOCTYPE: case COMMENT_START: case COMMENT_START_DASH: case COMMENT: case COMMENT_END_DASH: case COMMENT_END: case COMMENT_END_BANG: case TAG_OPEN: case CLOSE_TAG_OPEN: case MARKUP_DECLARATION_HYPHEN: case MARKUP_DECLARATION_OCTYPE: case DOCTYPE_UBLIC: case DOCTYPE_YSTEM: case AFTER_DOCTYPE_PUBLIC_KEYWORD: case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: case AFTER_DOCTYPE_SYSTEM_KEYWORD: case SELF_CLOSING_START_TAG: case ATTRIBUTE_VALUE_DOUBLE_QUOTED: case ATTRIBUTE_VALUE_SINGLE_QUOTED: case ATTRIBUTE_VALUE_UNQUOTED: case BOGUS_COMMENT_HYPHEN: case COMMENT_LESSTHAN: case COMMENT_LESSTHAN_BANG: case COMMENT_LESSTHAN_BANG_DASH: case COMMENT_LESSTHAN_BANG_DASH_DASH: case CDATA_START: case CDATA_SECTION: case CDATA_RSQB: case CDATA_RSQB_RSQB: case PROCESSING_INSTRUCTION: case PROCESSING_INSTRUCTION_QUESTION_MARK: break; case CONSUME_CHARACTER_REFERENCE: case CONSUME_NCR: case CHARACTER_REFERENCE_TAIL: case HEX_NCR_LOOP: case DECIMAL_NRC_LOOP: case HANDLE_NCR_VALUE: case HANDLE_NCR_VALUE_RECONSUME: case CHARACTER_REFERENCE_HILO_LOOKUP: if (returnStateSave == DATA || returnStateSave == RCDATA) { return;
} break; default: assertfalse : "Incomplete switch"; return;
}
suspendAfterCurrentNonTextToken = true;
}
// Making this private until the full Java implementation is done. /** *Queriesifweareabouttosuspendafterthecurrentnon-texttokenduetoarequest *from<code>suspendAfterCurrentTokenIfNotInText()</code>. *@return<code>true</code>iff<code>suspendAfterCurrentTokenIfNotInText()</code>was *calledinanon-textpositionandthethen-currenttokenhasnotbeenemittedyet.
*/
@SuppressWarnings("unused") privateboolean suspensionAfterCurrentNonTextTokenPending() { return suspendAfterCurrentNonTextToken;
}
containsHyphen = other.containsHyphen; if (other.tagName == null) {
tagName = null;
} elseif (other.tagName.isInterned()) {
tagName = other.tagName;
} else { // In the C++ case, the atoms in the other tokenizer are from a // different tokenizer-scoped atom table. Therefore, we have to // obtain the correspoding atom from our own atom table.
nonInternedTagName.setNameForNonInterned(other.tagName.getName() // CPPONLY: , other.tagName.isCustom()
);
tagName = nonInternedTagName;
}
// [NOCPP[
attributeName = other.attributeName; // ]NOCPP] // CPPONLY: if (other.attributeName == null) { // CPPONLY: attributeName = null; // CPPONLY: } else if (other.attributeName.isInterned()) { // CPPONLY: attributeName = other.attributeName; // CPPONLY: } else { // CPPONLY: // In the C++ case, the atoms in the other tokenizer are from a // CPPONLY: // different tokenizer-scoped atom table. Therefore, we have to // CPPONLY: // obtain the correspoding atom from our own atom table. // CPPONLY: nonInternedAttributeName.setNameForNonInterned(other.attributeName.getLocal(AttributeName.HTML)); // CPPONLY: attributeName = nonInternedAttributeName; // CPPONLY: }
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.958Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.