/*
* Copyright ( c ) 2005 - 2007 Henri Sivonen
* Copyright ( c ) 2007 - 2017 Mozilla Foundation
* Portions of comments Copyright 2004 - 2010 Apple Computer , Inc . , Mozilla
* Foundation , and Opera Software ASA .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE .
*/
/*
* THIS IS A GENERATED FILE . PLEASE DO NOT EDIT .
* Please edit Tokenizer . java instead and regenerate .
*/
#define nsHtml5Tokenizer_cpp__
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"
#include "nsHtml5Tokenizer.h"
char16_t nsHtml5Tokenizer::LT_GT[] = {'<' , '>' };
char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = {'<' , '/' };
char16_t nsHtml5Tokenizer::RSQB_RSQB[] = {']' , ']' };
char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = {0 xfffd};
char16_t nsHtml5Tokenizer::LF[] = {'\n' };
char16_t nsHtml5Tokenizer::CDATA_LSQB[] = {'C' , 'D' , 'A' , 'T' , 'A' , '[' };
char16_t nsHtml5Tokenizer::OCTYPE[] = {'o' , 'c' , 't' , 'y' , 'p' , 'e' };
char16_t nsHtml5Tokenizer::UBLIC[] = {'u' , 'b' , 'l' , 'i' , 'c' };
char16_t nsHtml5Tokenizer::YSTEM[] = {'y' , 's' , 't' , 'e' , 'm' };
static char16_t const TITLE_ARR_DATA[] = {'t' , 'i' , 't' , 'l' , 'e' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TITLE_ARR = {
TITLE_ARR_DATA, std::size(TITLE_ARR_DATA)};
static char16_t const SCRIPT_ARR_DATA[] = {'s' , 'c' , 'r' , 'i' , 'p' , 't' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::SCRIPT_ARR = {
SCRIPT_ARR_DATA, std::size(SCRIPT_ARR_DATA)};
static char16_t const STYLE_ARR_DATA[] = {'s' , 't' , 'y' , 'l' , 'e' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::STYLE_ARR = {
STYLE_ARR_DATA, std::size(STYLE_ARR_DATA)};
static char16_t const PLAINTEXT_ARR_DATA[] = {'p' , 'l' , 'a' , 'i' , 'n' ,
't' , 'e' , 'x' , 't' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = {
PLAINTEXT_ARR_DATA, std::size(PLAINTEXT_ARR_DATA)};
static char16_t const XMP_ARR_DATA[] = {'x' , 'm' , 'p' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::XMP_ARR = {
XMP_ARR_DATA, std::size(XMP_ARR_DATA)};
static char16_t const TEXTAREA_ARR_DATA[] = {'t' , 'e' , 'x' , 't' ,
'a' , 'r' , 'e' , 'a' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = {
TEXTAREA_ARR_DATA, std::size(TEXTAREA_ARR_DATA)};
static char16_t const IFRAME_ARR_DATA[] = {'i' , 'f' , 'r' , 'a' , 'm' , 'e' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::IFRAME_ARR = {
IFRAME_ARR_DATA, std::size(IFRAME_ARR_DATA)};
static char16_t const NOEMBED_ARR_DATA[] = {'n' , 'o' , 'e' , 'm' , 'b' , 'e' , 'd' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOEMBED_ARR = {
NOEMBED_ARR_DATA, std::size(NOEMBED_ARR_DATA)};
static char16_t const NOSCRIPT_ARR_DATA[] = {'n' , 'o' , 's' , 'c' ,
'r' , 'i' , 'p' , 't' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = {
NOSCRIPT_ARR_DATA, std::size(NOSCRIPT_ARR_DATA)};
static char16_t const NOFRAMES_ARR_DATA[] = {'n' , 'o' , 'f' , 'r' ,
'a' , 'm' , 'e' , 's' };
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = {
NOFRAMES_ARR_DATA, std::size(NOFRAMES_ARR_DATA)};
nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler,
bool viewingXmlSource)
: tokenHandler(tokenHandler),
encodingDeclarationHandler(nullptr),
lastCR(false ),
stateSave(0 ),
returnStateSave(0 ),
index(0 ),
forceQuirks(false ),
additional('\0' ),
entCol(0 ),
firstCharKey(0 ),
lo(0 ),
hi(0 ),
candidate(0 ),
charRefBufMark(0 ),
value(0 ),
seenDigits(false ),
suspendAfterCurrentNonTextToken(false ),
cstart(0 ),
strBufLen(0 ),
charRefBuf(jArray<char16_t, int32_t>::newJArray(32 )),
charRefBufLen(0 ),
bmpChar(jArray<char16_t, int32_t>::newJArray(1 )),
astralChar(jArray<char16_t, int32_t>::newJArray(2 )),
endTagExpectation(nullptr),
endTagExpectationAsArray(nullptr),
endTag(false ),
containsHyphen(false ),
tagName(nullptr),
nonInternedTagName(new nsHtml5ElementName()),
attributeName(nullptr),
nonInternedAttributeName(new nsHtml5AttributeName()),
doctypeName(nullptr),
publicIdentifier(nullptr),
systemIdentifier(nullptr),
attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0 )
: nullptr),
newAttributesEachTime(!tokenHandler->HasBuilder()),
shouldSuspend(false ),
keepBuffer(false ),
confident(false ),
line(0 ),
attributeLine(0 ),
interner(nullptr),
viewingXmlSource(viewingXmlSource) {
MOZ_COUNT_CTOR(nsHtml5Tokenizer);
}
void nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner) {
this->interner = interner;
}
void nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
nsHtml5String newSystemId) {
this->systemId = newSystemId;
this->publicId = newPublicId;
}
bool nsHtml5Tokenizer::isViewingXmlSource() { return viewingXmlSource; }
void nsHtml5Tokenizer::setKeepBuffer(bool keepBuffer) {
this->keepBuffer = keepBuffer;
}
bool nsHtml5Tokenizer::dropBufferIfLongerThan(int32_t length) {
if (strBuf.length > length) {
strBuf = nullptr;
return true;
}
return false ;
}
void nsHtml5Tokenizer::setState(int32_t specialTokenizerState) {
this->stateSave = specialTokenizerState;
this->endTagExpectation = nullptr;
this->endTagExpectationAsArray = nullptr;
}
void nsHtml5Tokenizer::setStateAndEndTagExpectation(
int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation) {
this->stateSave = specialTokenizerState;
this->endTagExpectation = endTagExpectation;
endTagExpectationToArray();
}
void nsHtml5Tokenizer::endTagExpectationToArray() {
switch (endTagExpectation->getGroup()) {
case nsHtml5TreeBuilder::TITLE: {
endTagExpectationAsArray = TITLE_ARR;
return ;
}
case nsHtml5TreeBuilder::SCRIPT: {
endTagExpectationAsArray = SCRIPT_ARR;
return ;
}
case nsHtml5TreeBuilder::STYLE: {
endTagExpectationAsArray = STYLE_ARR;
return ;
}
case nsHtml5TreeBuilder::PLAINTEXT: {
endTagExpectationAsArray = PLAINTEXT_ARR;
return ;
}
case nsHtml5TreeBuilder::XMP: {
endTagExpectationAsArray = XMP_ARR;
return ;
}
case nsHtml5TreeBuilder::TEXTAREA: {
endTagExpectationAsArray = TEXTAREA_ARR;
return ;
}
case nsHtml5TreeBuilder::IFRAME: {
endTagExpectationAsArray = IFRAME_ARR;
return ;
}
case nsHtml5TreeBuilder::NOEMBED: {
endTagExpectationAsArray = NOEMBED_ARR;
return ;
}
case nsHtml5TreeBuilder::NOSCRIPT: {
endTagExpectationAsArray = NOSCRIPT_ARR;
return ;
}
case nsHtml5TreeBuilder::NOFRAMES: {
endTagExpectationAsArray = NOFRAMES_ARR;
return ;
}
default : {
MOZ_ASSERT(false , "Bad end tag expectation." );
return ;
}
}
}
void nsHtml5Tokenizer::setLineNumber(int32_t line) {
this->attributeLine = line;
this->line = line;
}
void nsHtml5Tokenizer::appendCharRefBuf(char16_t c) {
MOZ_RELEASE_ASSERT(charRefBufLen < charRefBuf.length,
"Attempted to overrun charRefBuf!" );
charRefBuf[charRefBufLen++] = c;
}
void nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState) {
if ((returnState & DATA_AND_RCDATA_MASK)) {
appendCharRefBufToStrBuf();
} else {
if (charRefBufLen > 0 ) {
tokenHandler->characters(charRefBuf, 0 , charRefBufLen);
charRefBufLen = 0 ;
}
}
}
void nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos) {
RememberGt(pos);
tokenHandler->comment(strBuf, 0 , strBufLen - provisionalHyphens);
clearStrBufAfterUse();
cstart = pos + 1 ;
suspendIfRequestedAfterCurrentNonTextToken();
}
void nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos) {
if (pos > cstart) {
tokenHandler->characters(buf, cstart, pos - cstart);
}
cstart = INT32_MAX;
}
void nsHtml5Tokenizer::strBufToElementNameString() {
if (containsHyphen) {
nsAtom* annotationName = nsHtml5ElementName::ELT_ANNOTATION_XML->getName();
if (nsHtml5Portability::localEqualsBuffer(annotationName, strBuf,
strBufLen)) {
tagName = nsHtml5ElementName::ELT_ANNOTATION_XML;
} else {
nonInternedTagName->setNameForNonInterned(
nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
interner),
true);
tagName = nonInternedTagName;
}
} else {
tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, strBufLen);
if (!tagName) {
nonInternedTagName->setNameForNonInterned(
nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
interner),
false );
tagName = nonInternedTagName;
}
}
containsHyphen = false ;
clearStrBufAfterUse();
}
int32_t nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos) {
RememberGt(pos);
cstart = pos + 1 ;
maybeErrSlashInEndTag(selfClosing);
stateSave = nsHtml5Tokenizer::DATA;
nsHtml5HtmlAttributes* attrs =
(!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
if (endTag) {
maybeErrAttributesOnEndTag(attrs);
if (!viewingXmlSource) {
tokenHandler->endTag(tagName);
}
if (newAttributesEachTime) {
delete attributes;
attributes = nullptr;
}
} else {
if (viewingXmlSource) {
MOZ_ASSERT(newAttributesEachTime);
delete attributes;
attributes = nullptr;
} else {
tokenHandler->startTag(tagName, attrs, selfClosing);
}
}
tagName = nullptr;
if (newAttributesEachTime) {
attributes = nullptr;
} else {
attributes->clear(0 );
}
suspendIfRequestedAfterCurrentNonTextToken();
return stateSave;
}
void nsHtml5Tokenizer::attributeNameComplete() {
attributeName =
nsHtml5AttributeName::nameByBuffer(strBuf, strBufLen, interner);
if (!attributeName) {
nonInternedAttributeName->setNameForNonInterned(
nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
interner));
attributeName = nonInternedAttributeName;
}
clearStrBufAfterUse();
if (!attributes) {
attributes = new nsHtml5HtmlAttributes(0 );
}
if (attributes->contains(attributeName)) {
errDuplicateAttribute();
attributeName = nullptr;
}
}
void nsHtml5Tokenizer::addAttributeWithoutValue() {
if (attributeName) {
attributes->addAttribute(
attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
attributeName = nullptr;
} else {
clearStrBufAfterUse();
}
}
void nsHtml5Tokenizer::addAttributeWithValue() {
if (attributeName) {
nsHtml5String val = strBufToAttributeValueString();
if (mViewSource) {
mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
}
attributes->addAttribute(attributeName, val, attributeLine);
attributeName = nullptr;
} else {
clearStrBufAfterUse();
}
}
void nsHtml5Tokenizer::start() {
initializeWithoutStarting();
tokenHandler->startTokenization(this);
if (mViewSource) {
line = 1 ;
col = -1 ;
nextCharOnNewLine = false ;
} else if (tokenHandler->WantsLineAndColumn()) {
line = 0 ;
col = 1 ;
nextCharOnNewLine = true;
} else {
line = -1 ;
col = -1 ;
nextCharOnNewLine = false ;
}
}
bool nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) {
int32_t state = stateSave;
int32_t returnState = returnStateSave;
char16_t c = '\0' ;
shouldSuspend = false ;
lastCR = false ;
int32_t start = buffer->getStart();
int32_t end = buffer->getEnd();
int32_t 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 = INT32_MAX;
break ;
}
}
if (mViewSource) {
mViewSource->SetBuffer(buffer);
if (mozilla::htmlaccel::htmlaccelEnabled()) {
pos = StateLoopViewSourceSIMD(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
} else {
pos = StateLoopViewSourceALU(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
}
mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1 );
} else if (tokenHandler->WantsLineAndColumn()) {
if (mozilla::htmlaccel::htmlaccelEnabled()) {
pos = StateLoopLineColSIMD(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
} else {
pos = StateLoopLineColALU(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
}
} else if (mozilla::htmlaccel::htmlaccelEnabled()) {
pos = StateLoopFastestSIMD(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
} else {
pos = StateLoopFastestALU(state, c, pos, buffer->getBuffer(), false ,
returnState, buffer->getEnd());
}
if (pos == end) {
buffer->setStart(pos);
} else {
buffer->setStart(pos + 1 );
}
return lastCR;
}
void nsHtml5Tokenizer::initDoctypeFields() {
clearStrBufAfterUse();
doctypeName = nullptr;
if (systemIdentifier) {
systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
publicIdentifier.Release();
publicIdentifier = nullptr;
}
forceQuirks = false ;
}
void nsHtml5Tokenizer::emitReplacementCharacter(char16_t* buf, int32_t pos) {
flushChars(buf, pos);
tokenHandler->zeroOriginatingReplacementCharacter();
cstart = pos + 1 ;
}
void nsHtml5Tokenizer::maybeEmitReplacementCharacter(char16_t* buf,
int32_t pos) {
flushChars(buf, pos);
tokenHandler->zeroOrReplacementCharacter();
cstart = pos + 1 ;
}
void nsHtml5Tokenizer::emitPlaintextReplacementCharacter(char16_t* buf,
int32_t pos) {
flushChars(buf, pos);
tokenHandler->characters(REPLACEMENT_CHARACTER, 0 , 1 );
cstart = pos + 1 ;
}
void nsHtml5Tokenizer::bogusDoctype() {
errBogusDoctype();
forceQuirks = true;
}
void nsHtml5Tokenizer::bogusDoctypeWithoutQuirks() {
errBogusDoctype();
forceQuirks = false ;
}
void nsHtml5Tokenizer::handleNcrValue(int32_t returnState) {
if (value <= 0 xFFFF) {
if (value >= 0 x80 && value <= 0 x9f) {
errNcrInC1Range();
char16_t* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0 x80];
emitOrAppendOne(val, returnState);
} else if (value == 0 x0) {
errNcrZero();
emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
} else if ((value & 0 xF800) == 0 xD800) {
errNcrSurrogate();
emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
} else {
char16_t ch = (char16_t)value;
bmpChar[0 ] = ch;
emitOrAppendOne(bmpChar, returnState);
}
} else if (value <= 0 x10FFFF) {
astralChar[0 ] = (char16_t)(nsHtml5Tokenizer::LEAD_OFFSET + (value >> 10 ));
astralChar[1 ] = (char16_t)(0 xDC00 + (value & 0 x3FF));
emitOrAppendTwo(astralChar, returnState);
} else {
errNcrOutOfRange();
emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
}
}
void nsHtml5Tokenizer::eof() {
int32_t state = stateSave;
int32_t returnState = returnStateSave;
eofloop:
for (;;) {
switch (state) {
case SCRIPT_DATA_LESS_THAN_SIGN:
case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0 , 1 );
NS_HTML5_BREAK(eofloop);
}
case TAG_OPEN: {
errEofAfterLt();
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0 , 1 );
NS_HTML5_BREAK(eofloop);
}
case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0 , 1 );
NS_HTML5_BREAK(eofloop);
}
case NON_DATA_END_TAG_NAME: {
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0 , 2 );
emitStrBuf();
NS_HTML5_BREAK(eofloop);
}
case CLOSE_TAG_OPEN: {
errEofAfterLt();
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0 , 2 );
NS_HTML5_BREAK(eofloop);
}
case TAG_NAME: {
errEofInTagName();
NS_HTML5_BREAK(eofloop);
}
case BEFORE_ATTRIBUTE_NAME:
case AFTER_ATTRIBUTE_VALUE_QUOTED:
case SELF_CLOSING_START_TAG: {
errEofWithoutGt();
NS_HTML5_BREAK(eofloop);
}
case ATTRIBUTE_NAME: {
errEofInAttributeName();
NS_HTML5_BREAK(eofloop);
}
case AFTER_ATTRIBUTE_NAME:
case BEFORE_ATTRIBUTE_VALUE: {
errEofWithoutGt();
NS_HTML5_BREAK(eofloop);
}
case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
case ATTRIBUTE_VALUE_SINGLE_QUOTED:
case ATTRIBUTE_VALUE_UNQUOTED: {
errEofInAttributeValue();
NS_HTML5_BREAK(eofloop);
}
case BOGUS_COMMENT: {
emitComment(0 , 0 );
NS_HTML5_BREAK(eofloop);
}
case BOGUS_COMMENT_HYPHEN: {
emitComment(0 , 0 );
NS_HTML5_BREAK(eofloop);
}
case MARKUP_DECLARATION_OPEN: {
errBogusComment();
emitComment(0 , 0 );
NS_HTML5_BREAK(eofloop);
}
case MARKUP_DECLARATION_HYPHEN: {
errBogusComment();
emitComment(0 , 0 );
NS_HTML5_BREAK(eofloop);
}
case MARKUP_DECLARATION_OCTYPE: {
if (index < 6 ) {
errBogusComment();
emitComment(0 , 0 );
} else {
errEofInDoctype();
doctypeName = nullptr;
if (systemIdentifier) {
systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
publicIdentifier.Release();
publicIdentifier = nullptr;
}
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
NS_HTML5_BREAK(eofloop);
}
case COMMENT_START:
case COMMENT:
case COMMENT_LESSTHAN:
case COMMENT_LESSTHAN_BANG: {
errEofInComment();
emitComment(0 , 0 );
NS_HTML5_BREAK(eofloop);
}
case COMMENT_END:
case COMMENT_LESSTHAN_BANG_DASH_DASH: {
errEofInComment();
emitComment(2 , 0 );
NS_HTML5_BREAK(eofloop);
}
case COMMENT_END_DASH:
case COMMENT_START_DASH:
case COMMENT_LESSTHAN_BANG_DASH: {
errEofInComment();
emitComment(1 , 0 );
NS_HTML5_BREAK(eofloop);
}
case COMMENT_END_BANG: {
errEofInComment();
emitComment(3 , 0 );
NS_HTML5_BREAK(eofloop);
}
case DOCTYPE:
case BEFORE_DOCTYPE_NAME: {
errEofInDoctype();
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case DOCTYPE_NAME: {
errEofInDoctype();
strBufToDoctypeName();
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case DOCTYPE_UBLIC:
case DOCTYPE_YSTEM:
case AFTER_DOCTYPE_NAME:
case AFTER_DOCTYPE_PUBLIC_KEYWORD:
case AFTER_DOCTYPE_SYSTEM_KEYWORD:
case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
errEofInDoctype();
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
errEofInPublicId();
forceQuirks = true;
publicIdentifier = strBufToString();
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
errEofInDoctype();
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
errEofInSystemId();
forceQuirks = true;
systemIdentifier = strBufToString();
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
errEofInDoctype();
forceQuirks = true;
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case BOGUS_DOCTYPE: {
emitDoctypeToken(0 );
NS_HTML5_BREAK(eofloop);
}
case CONSUME_CHARACTER_REFERENCE: {
emitOrAppendCharRefBuf(returnState);
state = returnState;
continue ;
}
case CHARACTER_REFERENCE_HILO_LOOKUP: {
emitOrAppendCharRefBuf(returnState);
state = returnState;
continue ;
}
case CHARACTER_REFERENCE_TAIL: {
for (;;) {
char16_t c = '\0' ;
entCol++;
for (;;) {
if (hi == -1 ) {
NS_HTML5_BREAK(hiloop);
}
if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
NS_HTML5_BREAK(hiloop);
}
if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
NS_HTML5_BREAK(outer);
} else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
hi--;
} else {
NS_HTML5_BREAK(hiloop);
}
}
hiloop_end:;
for (;;) {
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
candidate = lo;
charRefBufMark = charRefBufLen;
lo++;
} else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
NS_HTML5_BREAK(outer);
} else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
lo++;
} else {
NS_HTML5_BREAK(loloop);
}
}
loloop_end:;
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
continue ;
}
outer_end:;
if (candidate == -1 ) {
emitOrAppendCharRefBuf(returnState);
state = returnState;
NS_HTML5_CONTINUE(eofloop);
} else {
const nsHtml5CharacterName& candidateName =
nsHtml5NamedCharacters::NAMES[candidate];
if (!candidateName.length() ||
candidateName.charAt(candidateName.length() - 1 ) != ';' ) {
if ((returnState & DATA_AND_RCDATA_MASK)) {
char16_t ch;
if (charRefBufMark == charRefBufLen) {
ch = '\0' ;
} else {
ch = charRefBuf[charRefBufMark];
}
if ((ch >= '0' && ch <= '9' ) || (ch >= 'A' && ch <= 'Z' ) ||
(ch >= 'a' && ch <= 'z' )) {
appendCharRefBufToStrBuf();
state = returnState;
NS_HTML5_CONTINUE(eofloop);
}
}
if ((returnState & DATA_AND_RCDATA_MASK)) {
errUnescapedAmpersandInterpretedAsCharacterReference();
} else {
errNotSemicolonTerminated();
}
}
const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
if (!val[1 ]) {
emitOrAppendOne(val, returnState);
} else {
emitOrAppendTwo(val, returnState);
}
if (charRefBufMark < charRefBufLen) {
if ((returnState & DATA_AND_RCDATA_MASK)) {
appendStrBuf(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
} else {
tokenHandler->characters(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
}
}
charRefBufLen = 0 ;
state = returnState;
NS_HTML5_CONTINUE(eofloop);
}
}
case CONSUME_NCR:
case DECIMAL_NRC_LOOP:
case HEX_NCR_LOOP: {
if (!seenDigits) {
errNoDigitsInNCR();
emitOrAppendCharRefBuf(returnState);
state = returnState;
continue ;
} else {
errCharRefLacksSemicolon();
}
handleNcrValue(returnState);
state = returnState;
continue ;
}
case CDATA_RSQB: {
tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0 , 1 );
NS_HTML5_BREAK(eofloop);
}
case CDATA_RSQB_RSQB: {
tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0 , 2 );
NS_HTML5_BREAK(eofloop);
}
case DATA:
default : {
NS_HTML5_BREAK(eofloop);
}
}
}
eofloop_end:;
tokenHandler->eof();
return ;
}
void nsHtml5Tokenizer::emitDoctypeToken(int32_t pos) {
RememberGt(pos);
cstart = pos + 1 ;
tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier,
forceQuirks);
doctypeName = nullptr;
publicIdentifier.Release();
publicIdentifier = nullptr;
systemIdentifier.Release();
systemIdentifier = nullptr;
suspendIfRequestedAfterCurrentNonTextToken();
}
void nsHtml5Tokenizer::suspendAfterCurrentTokenIfNotInText() {
switch (stateSave) {
case DATA:
case RCDATA:
case SCRIPT_DATA:
case RAWTEXT:
case SCRIPT_DATA_ESCAPED:
case PLAINTEXT:
case NON_DATA_END_TAG_NAME:
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 : {
MOZ_ASSERT(false , "Incomplete switch" );
return ;
}
}
suspendAfterCurrentNonTextToken = true;
}
bool nsHtml5Tokenizer::suspensionAfterCurrentNonTextTokenPending() {
return suspendAfterCurrentNonTextToken;
}
bool nsHtml5Tokenizer::internalEncodingDeclaration(
nsHtml5String internalCharset) {
if (encodingDeclarationHandler) {
return encodingDeclarationHandler->internalEncodingDeclaration(
internalCharset);
}
return false ;
}
void nsHtml5Tokenizer::end() {
if (!keepBuffer) {
strBuf = nullptr;
}
doctypeName = nullptr;
if (systemIdentifier) {
systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
publicIdentifier.Release();
publicIdentifier = nullptr;
}
tagName = nullptr;
nonInternedTagName->setNameForNonInterned(nullptr, false );
attributeName = nullptr;
nonInternedAttributeName->setNameForNonInterned(nullptr);
tokenHandler->endTokenization();
if (attributes) {
attributes->clear(0 );
}
}
void nsHtml5Tokenizer::resetToDataState() {
clearStrBufAfterUse();
charRefBufLen = 0 ;
stateSave = nsHtml5Tokenizer::DATA;
lastCR = false ;
index = 0 ;
forceQuirks = false ;
additional = '\0' ;
entCol = -1 ;
firstCharKey = -1 ;
lo = 0 ;
hi = 0 ;
candidate = -1 ;
charRefBufMark = 0 ;
value = 0 ;
seenDigits = false ;
suspendAfterCurrentNonTextToken = false ;
endTag = false ;
shouldSuspend = false ;
initDoctypeFields();
containsHyphen = false ;
tagName = nullptr;
attributeName = nullptr;
if (newAttributesEachTime) {
if (attributes) {
delete attributes;
attributes = nullptr;
}
}
}
void nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other) {
strBufLen = other->strBufLen;
if (strBufLen > strBuf.length) {
strBuf = jArray<char16_t, int32_t>::newJArray(strBufLen);
}
nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
charRefBufLen = other->charRefBufLen;
nsHtml5ArrayCopy::arraycopy(other->charRefBuf, charRefBuf, charRefBufLen);
stateSave = other->stateSave;
returnStateSave = other->returnStateSave;
endTagExpectation = other->endTagExpectation;
endTagExpectationAsArray = other->endTagExpectationAsArray;
lastCR = other->lastCR;
index = other->index;
forceQuirks = other->forceQuirks;
additional = other->additional;
entCol = other->entCol;
firstCharKey = other->firstCharKey;
lo = other->lo;
hi = other->hi;
candidate = other->candidate;
charRefBufMark = other->charRefBufMark;
value = other->value;
seenDigits = other->seenDigits;
endTag = other->endTag;
shouldSuspend = false ;
suspendAfterCurrentNonTextToken = false ;
doctypeName = other->doctypeName;
systemIdentifier.Release();
if (!other->systemIdentifier) {
systemIdentifier = nullptr;
} else {
systemIdentifier =
nsHtml5Portability::newStringFromString(other->systemIdentifier);
}
publicIdentifier.Release();
if (!other->publicIdentifier) {
publicIdentifier = nullptr;
} else {
publicIdentifier =
nsHtml5Portability::newStringFromString(other->publicIdentifier);
}
containsHyphen = other->containsHyphen;
if (!other->tagName) {
tagName = nullptr;
} else if (other->tagName->isInterned()) {
tagName = other->tagName;
} else {
nonInternedTagName->setNameForNonInterned(other->tagName->getName(),
other->tagName->isCustom());
tagName = nonInternedTagName;
}
if (!other->attributeName) {
attributeName = nullptr;
} else if (other->attributeName->isInterned()) {
attributeName = other->attributeName;
} else {
nonInternedAttributeName->setNameForNonInterned(
other->attributeName->getLocal(nsHtml5AttributeName::HTML));
attributeName = nonInternedAttributeName;
}
delete attributes;
if (!other->attributes) {
attributes = nullptr;
} else {
attributes = other->attributes->cloneAttributes();
}
}
void nsHtml5Tokenizer::initializeWithoutStarting() {
confident = false ;
if (!keepBuffer) {
strBuf = nullptr;
}
line = 1 ;
attributeLine = 1 ;
resetToDataState();
}
void nsHtml5Tokenizer::setEncodingDeclarationHandler(
nsHtml5StreamParser* encodingDeclarationHandler) {
this->encodingDeclarationHandler = encodingDeclarationHandler;
}
nsHtml5Tokenizer::~nsHtml5Tokenizer() {
MOZ_COUNT_DTOR(nsHtml5Tokenizer);
delete nonInternedTagName;
nonInternedTagName = nullptr;
delete nonInternedAttributeName;
nonInternedAttributeName = nullptr;
delete attributes;
attributes = nullptr;
}
void nsHtml5Tokenizer::initializeStatics() {}
void nsHtml5Tokenizer::releaseStatics() {}
#include "nsHtml5TokenizerCppSupplement.h"
Messung V0.5 in Prozent C=99 H=96 G=97
¤ Dauer der Verarbeitung: 0.13 Sekunden
¤
*© Formatika GbR, Deutschland