void StateLoop3_RawText_CData_RcRef(CDataLexerState state, CDataLexerState returnState) { /* * Idioms used in this code: * * * Consuming the next input character * * To consume the next input character, the code does this: if (++pos == * endPos) { goto breakStateloop; } c = buf[pos]; * * * Staying in a state * * When there's a state that the tokenizer may stay in over multiple * input characters, the state has a wrapper |for(;;)| loop and staying * in the state continues the loop. * * * Switching to another state * * To switch to another state, the code sets the state variable to the * magic number of the new state. Then it either continues stateloop or * breaks out of the state's own wrapper loop if the target state is * right after the current state in source order. (This is a partial * workaround for Java's lack of goto.) * * * Reconsume support * * The spec sometimes says that an input character is reconsumed in * another state. If a state can ever be entered so that an input * character can be reconsumed in it, the state's code starts with an * |if (reconsume)| that sets reconsume to false and skips over the * normal code for consuming a new character. * * To reconsume the current character in another state, the code sets * |reconsume| to true and then switches to the other state. * * * Emitting character tokens * * This method emits character tokens lazily. Whenever a new range of * character tokens starts, the field cstart must be set to the start * index of the range. The flushChars() method must be called at the end * of a range to flush it. * * * U+0000 handling * * The various states have to handle the replacement of U+0000 with * U+FFFD. However, if U+0000 would be reconsumed in another state, the * replacement doesn't need to happen, because it's handled by the * reconsuming state. * * * LF handling * * Every state needs to increment the line number upon LF unless the LF * gets reconsumed by another state which increments the line number. * * * CR handling * * Every state needs to handle CR unless the CR gets reconsumed and is * handled by the reconsuming state. The CR needs to be handled as if it * were and LF, the lastCR field must be set to true and then this * method must return. The IO driver will then swallow the next * character if it is an LF to coalesce CRLF. */ /* * As there is no support for labeled loops in C#, instead of break <loop>; * the port uses goto break<loop>; and a label after the loop. * Instead of continue <loop>; it uses goto continue<loop>; and a label * at the beginning or end of the loop (which doesn't matter in for(;;) loops) */ /*stateloop:*/ for (; ; ) { //************* continueStateloop: //************* switch (state) { // XXX reorder point case (CDataLexerState)InterLexerState.CDATA_START_i: { char c; while (reader.ReadNext(out c)) { if (index < 6) { // CDATA_LSQB.Length if (c == CDATA_LSQB[index]) { AppendLongStrBuf(c); } else { ErrBogusComment(); //state = Transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); //state = TokenizerState.s44_BOGUS_COMMENT_i; SetInterLexerState(InterLexerState.s44_BOGUS_COMMENT_i); //reconsume = true; reader.StepBack(); goto continueStateloop; } index++; continue; } else { reader.StartCollect(); // start coalescing //state = Transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); state = CDataLexerState.s68_CDATA_SECTION_p; //reconsume = true; reader.StepBack(); goto case CDataLexerState.s68_CDATA_SECTION_p; //break; // FALL THROUGH goto continueStateloop; } } //------------------------------- //eof goto breakStateloop; //------------------------------------ } // WARNING FALLTHRU case TokenizerState.TRANSITION: DON'T REORDER case CDataLexerState.s68_CDATA_SECTION_p: /*cdatasectionloop:*/ { char c; while (reader.ReadNext(out c)) { switch (c) { case ']': FlushChars(); //state = Transition(state, Tokenizer.CDATA_RSQB, reconsume, pos); state = CDataLexerState.CDATA_RSQB_p; goto breakCdatasectionloop; // FALL THROUGH case '\u0000': EmitReplacementCharacter(); continue; case '\r': EmitCarriageReturn(); goto breakStateloop; case '\n': default: continue; } } goto breakStateloop; //------------------------------------ breakCdatasectionloop: goto case CDataLexerState.CDATA_RSQB_p; } // WARNING FALLTHRU case TokenizerState.TRANSITION: DON'T REORDER case CDataLexerState.CDATA_RSQB_p: /*cdatarsqb:*/ { char c; while (reader.ReadNext(out c)) { switch (c) { case ']': //state = Transition(state, Tokenizer.CDATA_RSQB_RSQB, reconsume, pos); state = CDataLexerState.CDATA_RSQB_RSQB_p; goto breakCdatarsqb; default: TokenListener.Characters(RSQB_RSQB, 0, 1); reader.StartCollect(); //state = Transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); state = CDataLexerState.s68_CDATA_SECTION_p; //reconsume = true; reader.StepBack(); goto continueStateloop; } } //------------------------------- //eof goto breakStateloop; //------------------------------------ breakCdatarsqb: goto case CDataLexerState.CDATA_RSQB_RSQB_p; } // WARNING FALLTHRU case TokenizerState.TRANSITION: DON'T REORDER case CDataLexerState.CDATA_RSQB_RSQB_p: { char c; if (!reader.ReadNext(out c)) { goto breakStateloop; } switch (c) { case '>': //cstart = pos + 1; reader.SkipOneAndStartCollect(); //state = Transition(state, Tokenizer.DATA, reconsume, pos); //state = TokenizerState.s01_DATA_i; SetInterLexerState(InterLexerState.s01_DATA_i); goto continueStateloop; default: TokenListener.Characters(RSQB_RSQB, 0, 2); reader.StartCollect(); //state = Transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); state = CDataLexerState.s68_CDATA_SECTION_p; reader.StepBack(); //reconsume = true; goto continueStateloop; } } // XXX reorder point case CDataLexerState.s07_PLAINTEXT_p: /*plaintextloop:*/ { char c; while (reader.ReadNext(out c)) { switch (c) { case '\u0000': EmitPlaintextReplacementCharacter(); continue; case '\r': EmitCarriageReturn(); goto breakStateloop; case '\n': default: /* * Anything else Emit the current input * character as a character token. Stay in the * RAWTEXT state. */ continue; } } //------------------------------------ //eof goto breakStateloop; } // XXX reorder point case CDataLexerState.s03_RCDATA_p: /*rcdataloop:*/ { char c; while (reader.ReadNext(out c)) { switch (c) { case '&': /* * U+0026 AMPERSAND (&) Switch to the character * reference in RCDATA state. */ //FlushChars(buf, pos); FlushChars(); ClearStrBufAndAppend(c); additional = '\u0000'; returnState = state; //state = Transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos); //state = TokenizerState.CONSUME_CHARACTER_REFERENCE_i; SetInterLexerState(InterLexerState.CONSUME_CHARACTER_REFERENCE_i); goto continueStateloop; case '<': /* * U+003C LESS-THAN SIGN (<) Switch to the * RCDATA less-than sign state. */ //FlushChars(buf, pos); FlushChars(); returnState = state; //state = Transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos); state = CDataLexerState.s11_RAWTEXT_RCDATA_LESS_THAN_SIGN_p; goto continueStateloop; case '\u0000': EmitReplacementCharacter(); continue; case '\r': EmitCarriageReturn(); goto breakStateloop; case '\n': default: /* * Emit the current input character as a * character token. Stay in the RCDATA state. */ continue; } } //------------------------------------ //eof goto breakStateloop; } case CDataLexerState.PROCESSING_INSTRUCTION_p: //processinginstructionloop: { char c; while (reader.ReadNext(out c)) { switch (c) { case '?': //state = Transition(state,Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK,reconsume, pos); state = CDataLexerState.PROCESSING_INSTRUCTION_QUESTION_MARK_p; break; // continue stateloop; default: continue; } } //------------------------------------ //eof goto breakStateloop; } //breakProcessingInstructionLoop: case CDataLexerState.PROCESSING_INSTRUCTION_QUESTION_MARK_p: { char c; if (!reader.ReadNext(out c)) { goto breakStateloop; } switch (c) { case '>': //state = Transition(state, Tokenizer.DATA,reconsume, pos); //state = TokenizerState.s01_DATA_i; SetInterLexerState(InterLexerState.s01_DATA_i); continue; default: //state = Transition(state,Tokenizer.PROCESSING_INSTRUCTION,reconsume, pos); state = CDataLexerState.PROCESSING_INSTRUCTION_p; continue; } } // END HOTSPOT WORKAROUND } } // stateloop breakStateloop: //FlushChars(buf, pos); FlushChars(); /* * if (prevCR && pos != endPos) { // why is this needed? pos--; col--; } */ // Save locals SaveStates(state, returnState); //stateSave = state; //returnStateSave = returnState; }
void SaveStates(CDataLexerState state, CDataLexerState returnState) { }