fsmReturnStatus normal_operating(Fsm * fsm, const Event* e) { static bool enable = false; switch (e->signal) { case ENTRY: td_time_increment.expire = 0; scheduler_add(&td_time_increment); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(set_alarm_hour); case ROTARY_PRESSED: enable = !enable; fsm->isAlarmEnabled = enable; if (enable) led_yellowOn(); else led_yellowOff(); return RET_HANDLED; case MATCHING: if (fsm->isAlarmEnabled) { return TRANSITION(led_toggle); } else return RET_HANDLED; case EXIT: scheduler_remove(&td_time_increment); return RET_HANDLED; default: return RET_IGNORED; } }
fsmReturnStatus led_toggle(Fsm * fsm, const Event* e) { //!!!!!!make all tasks global. //!!!mistake: set td.next=NULL will disrupt scheduler!!!! // static taskDescriptor td; // td.task = &wrapper_red_led; // //td.param = &; //void pointer point to void, param is of type void // td.expire = 0; // td.period = 250; //0.25s = 4Hz // td.execute = 0; // td.next = NULL; // // static taskDescriptor td2; // td2.task = &wrapper_turnoff_led; // td2.param = fsm; //void pointer point to void, param is of type void // td2.expire = 5000; //count 5s // td2.period = 0; // td2.execute = 0; // td2.next = NULL; // // static taskDescriptor td3; // td3.task = &time_increment; // td3.param = fsm; // td3.expire = 0; // td3.period = 1000; // every second update the time of the clock // td3.execute = 0; // td3.next = NULL; switch (e->signal) { case ENTRY: td_toggle_led.expire = 0; td_turnoff_led.expire = 5000; td_time_increment.expire = 0; scheduler_add(&td_toggle_led); scheduler_add(&td_turnoff_led); scheduler_add(&td_time_increment); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(normal_operating); case ROTARY_PRESSED: return TRANSITION(normal_operating); case EXIT: led_redOff(); scheduler_remove(&td_toggle_led); scheduler_remove(&td_turnoff_led); scheduler_remove(&td_time_increment); return RET_HANDLED; default: return RET_IGNORED; } }
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler, const TOOL_EVENT_LIST& aConditions ) { TOOL_STATE* st = m_toolState[aTool]; st->transitions.push_back( TRANSITION( aConditions, aHandler ) ); }
//----------------------------------------------------------------// void MOAITextStyler::Parse () { u32 c = 0; u32 state = TOKEN_TEXT; while ( state != DONE ) { switch ( state ) { //================================================================// // TOKEN //----------------------------------------------------------------// //----------------------------------------------------------------// // check to see if we've encountered a style escape case TOKEN_TEXT: { if ( this->ParseStyle ()) { TRANSITION ( TOKEN_TEXT ); } c = this->GetChar (); if ( c == 0 ) { this->FinishToken (); TRANSITION ( DONE ); } this->mCurrentStyle->AffirmGlyph ( c ); this->mTokenTop = this->mIdx; TRANSITION ( TOKEN_TEXT ); } } } u32 totalActiveStyles = this->mActiveStyles.GetTop (); for ( u32 i = 0; i < totalActiveStyles; ++i ) { MOAITextStyle* style = this->mActiveStyles [ i ]; style->mFont->ProcessGlyphs (); } }
void PGBuildLR1::EXPAND (int state) { int i, c, h, t, nt, tt, nfi; // Define all Nonterminal transitions out of this state. ALLOC (Ngotos[state], Closure_Head[state][0]+1); Ngotos[state][0] = Closure_Head[state][0]; nt = 1; for (c = 1; c <= Closure_Head[state][0]; c++) { h = Closure_Head[state][c]; ntt_item[n_nonttran++] = MAKE_KERNEL (state, -h); Ngotos[state][nt++] = TRANSITION (-h); } // Define all Terminal transitions out of this state. ALLOC (Tgotos[state], Closure_Term[state][0]+1); Tgotos[state][0] = Closure_Term[state][0]; tt = 1; for (c = 1; c <= Closure_Term[state][0]; c++) { t = Closure_Term[state][c]; MAKE_KERNEL (state, t); Tgotos[state][tt++] = TRANSITION (t); } n_termtran += --tt; if (optn[PG_STATELIST] > 1) { PRT_LRSTA (state); PRT_CLO (state); PRT_TRAN (state); } // Free up the stuff we no longer need. FREE (Closure_Term[state], N_terms); FREE (Closure_Head[state], N_heads); FREE (Closure[state], n_clo); }
fsmReturnStatus alarm_init(Fsm * fsm, const Event* e) { td_toggle_led.task = &wrapper_red_led; //td.param = ; td_toggle_led.expire = 0; td_toggle_led.period = 250; //0.25s = 4Hz td_toggle_led.execute = 0; td_toggle_led.next = NULL; td_turnoff_led.task = &wrapper_turnoff_led; td_turnoff_led.param = fsm; td_turnoff_led.expire = 5000; //count 5s td_turnoff_led.period = 0; td_turnoff_led.execute = 0; td_turnoff_led.next = NULL; td_time_increment.task = &time_increment; // td3.param ; td_time_increment.expire = 0; td_time_increment.period = 1000; // every second update the time of the clock td_time_increment.execute = 0; td_time_increment.next = NULL; td_check_matching.task = &check_matching; // td4.param td_check_matching.expire = 0; td_check_matching.period = 1000; // every second check if matching td_check_matching.execute = 0; td_check_matching.next = NULL; td_check_rotary_encoder.task = &wrapper_check_rotary; td_check_rotary_encoder.expire = 0; //immediately execute the task td_check_rotary_encoder.period = 1; // td_check_rotary_encoder.execute = 0; td_check_rotary_encoder.next = NULL; scheduler_add(&td_check_rotary_encoder); switch (e->signal) { case ENTRY: fsm->isAlarmEnabled = false; fprintf(lcdout, "%02d:%02d\n", 0, 0); fprintf(lcdout, "set clock hour"); (fsm->timeSet).hour = 0; (fsm->timeSet).minute = 0; (fsm->timeSet).second = 0; return TRANSITION(sethour); default: return RET_IGNORED; } }
fsmReturnStatus set_alarm_min(Fsm * fsm, const Event* e) { Time_t *temp = &(fsm->timeSet); switch (e->signal) { case ENTRY: lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_PRESSED: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_INC: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_DEC: if ((temp->minute) == 0) temp->minute = 60; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, --(temp->minute)); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(normal_operating); case EXIT: td_check_matching.param = fsm;//in order to get the timeSet in the check matching td_check_matching.expire = 0; scheduler_add(&td_check_matching); return RET_HANDLED; default: return RET_IGNORED; } }
fsmReturnStatus setmin(Fsm * fsm, const Event* e) { Time_t *temp = &(fsm->timeSet); systemTime_t now; switch (e->signal) { case ENTRY: lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set clock min"); return RET_HANDLED; case ROTARY_PRESSED: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set clock min"); return RET_HANDLED; case ROTARY_INC: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set clock min"); return RET_HANDLED; case ROTARY_DEC: if ((temp->minute) == 0) temp->minute = 60; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, --(temp->minute)); fprintf(lcdout, "set clock min"); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(normal_operating); case EXIT: //set the time variable in scheduler. The variable is the real clock. temp->second = 0; now = (systemTime_t) ((temp->hour) * 3600 + (temp->minute) * 60) * 1000; scheduler_setTime(now); return RET_HANDLED; default: return RET_IGNORED; } }
fsmReturnStatus set_alarm_hour(Fsm * fsm, const Event* e) { Time_t *temp = &(fsm->timeSet); switch (e->signal) { case ENTRY: lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm hour"); return RET_HANDLED; case ROTARY_PRESSED: if (++(temp->hour) > 23) temp->hour = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm hour"); return RET_HANDLED; case ROTARY_INC: if (++(temp->hour) > 23) temp->hour = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm hour"); return RET_HANDLED; case ROTARY_DEC: if ((temp->hour) == 0) temp->hour = 24; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", --(temp->hour), temp->minute); fprintf(lcdout, "set alarm hour"); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(set_alarm_min); case EXIT: return RET_HANDLED; default: return RET_IGNORED; } }
void buffalo_nopae (vmi_instance_t instance, uint32_t entry, int pde) { /* similar techniques are surely doable in linux, but for now * this is only testing for windows domains */ if (instance->os_type != VMI_OS_WINDOWS) { return; } if (!TRANSITION(entry) && !PROTOTYPE(entry)) { uint32_t pfnum = (entry >> 1) & VMI_BIT_MASK(0,3); uint32_t pfframe = entry & VMI_BIT_MASK(12,31); /* pagefile */ if (pfnum != 0 && pfframe != 0) { dbprint(VMI_DEBUG_PTLOOKUP, "--Buffalo: page file = %d, frame = 0x%.8x\n", pfnum, pfframe); } /* demand zero */ else if (pfnum == 0 && pfframe == 0) { dbprint(VMI_DEBUG_PTLOOKUP, "--Buffalo: demand zero page\n"); } }
test_fsm::test_fsm(gst::fsm::fsm_state st /* = 0 */, const gst::fsm::transition_table& trt /* = gst::fsm::transition_table() */) { m_state = st; gst::fsm::transition_table tr_t = { TRANSITION( STATE_IDLE, EV_GO_IDLE, STATE_IDLE, test_fsm::go_idle ), TRANSITION( STATE_IDLE, EV_BEGIN_PATROL, STATE_PATROL, test_fsm::start_patrol ), TRANSITION( STATE_IDLE, EV_DIE, STATE_DEAD, test_fsm::die ), TRANSITION( STATE_PATROL, EV_GO_IDLE, STATE_IDLE, test_fsm::go_idle ), TRANSITION( STATE_PATROL, EV_BEGIN_PATROL, STATE_PATROL, test_fsm::start_patrol ), TRANSITION( STATE_PATROL, EV_ENEMY_SIGHTED, STATE_ATTACK, test_fsm::attack_enemy ), TRANSITION( STATE_PATROL, EV_DIE, STATE_DEAD, test_fsm::die ), TRANSITION( STATE_ATTACK, EV_GO_IDLE, STATE_IDLE, test_fsm::go_idle ), TRANSITION( STATE_ATTACK, EV_ENEMY_SIGHTED, STATE_ATTACK, test_fsm::attack_enemy ), TRANSITION( STATE_ATTACK, EV_ENEMY_KILLED, STATE_PATROL, test_fsm::start_patrol ), TRANSITION( STATE_ATTACK, EV_DIE, STATE_DEAD, test_fsm::die ) }; m_transitiontable = tr_t; }
//----------------------------------------------------------------// void MOAITextFrame::Parse () { float xScaleAdvance = this->mRightToLeft ? -1.0f : 1.0f; this->mLineBottom = 0; this->mLineTop = 0; this->mLineCount = 0; this->mLineXMax = 0.0f; this->mTokenXMin = 0.0f; this->mTokenXMax = 0.0f; float points = this->mPoints; float lineHeight = this->mFont->GetLineSpacing () * this->mPoints * this->mLineSpacing; this->mTotalLines = ( u32 )floorf ( this->mFrame.Height () / lineHeight ); if ( !this->mTotalLines ) return; this->mPen.Init ( 0.0f, this->mFrame.mYMin ); u32 colorSize = 0; u8 color [ COLOR_MAX ]; u32 c = 0; this->mGlyph = 0; bool inToken = false; int resetIdx = 0; u32 state = META_START; while ( state != META_FINISH ) { switch ( state ) { //================================================================// // META //----------------------------------------------------------------// //----------------------------------------------------------------// // check to see if we've encountered a style escape case META_START: { resetIdx = this->mIdx; c = this->DecodeChar (); if ( c == 0 ) { this->FlushToken (); if ( this->mLineCount >= this->mTotalLines ) { TRANSITION ( META_FINISH ); } // save the cursor just before the EOF this->mCursor->mIndex = resetIdx; this->mCursor->mRGBA = this->mRGBA; this->FlushLine (); TRANSITION ( META_FINISH ); } TRANSITION_ON_MATCH ( '<', STYLE_START ); TRANSITION ( TEXT_START ); } //================================================================// // TEXT //----------------------------------------------------------------// //----------------------------------------------------------------// // process a single char as text (ignore style escape) case TEXT_START: { if ( c == '\n' ) { this->FlushToken (); inToken = false; if ( this->mLineCount >= this->mTotalLines ) { TRANSITION ( META_FINISH ); } this->mCursor->mIndex = resetIdx; this->mCursor->mRGBA = this->mRGBA; this->FlushLine (); this->mPen.mX = 0.0f; this->mTokenXMax = 0.0f; this->mTokenXMin = 0.0f; this->mGlyph = 0; TRANSITION ( META_START ); } const MOAIGlyph* prevGlyph = this->mGlyph; const MOAIGlyph* glyph = &this->mFont->GetGlyphForChar ( c ); this->mGlyph = glyph; assert ( glyph ); bool hasWidth = ( glyph->mWidth > 0.0f ); // apply kerning if ( prevGlyph ) { MOAIKernVec kernVec = prevGlyph->GetKerning ( glyph->mCode ); this->mPen.mX += kernVec.mX * points * xScaleAdvance; } if ( hasWidth ) { if ( inToken == false ) { // save the cursor just before the new token this->mCursor->mIndex = resetIdx; this->mCursor->mRGBA = this->mRGBA; this->mTokenXMin = this->mPen.mX; this->mTokenXMax = this->mPen.mX; inToken = true; } // push the glyph float penX = this->mPen.mX + (( glyph->mWidth + glyph->mBearingX ) * points * xScaleAdvance ); float glyphX = this->mRightToLeft ? penX : this->mPen.mX; this->mLayout->PushGlyph ( glyph, resetIdx, glyphX, 0.0f, points, this->mRGBA ); this->mTokenXMax = penX; } else if ( inToken ) { this->FlushToken (); // bail if line count overflow if ( this->mLineCount >= this->mTotalLines ) { TRANSITION ( META_FINISH ); } inToken = false; } // advance the pen this->mPen.mX += glyph->mAdvanceX * points * xScaleAdvance; // back to start TRANSITION ( META_START ); } //================================================================// // STYLE //----------------------------------------------------------------// //----------------------------------------------------------------// // see which style we're parsing case STYLE_START: { c = this->DecodeChar (); TRANSITION_ON_MATCH ( 'c', COLOR_START ); TRANSITION ( STYLE_ABORT ); } // reset the cursor and go directly to text mode case STYLE_ABORT: { this->mIdx = resetIdx; c = this->DecodeChar (); TRANSITION ( TEXT_START ); } //================================================================// // COLOR //----------------------------------------------------------------// //----------------------------------------------------------------// case COLOR_START: { colorSize = 0; c = this->DecodeChar (); if ( IsWhitespace ( c )) continue; if ( c == ':' ) { state = COLOR_BODY; break; } TRANSITION_ON_MATCH ( ':', COLOR_BODY ); TRANSITION_ON_MATCH ( '>', COLOR_FINISH ); TRANSITION ( STYLE_ABORT ); } //----------------------------------------------------------------// case COLOR_BODY: { c = this->DecodeChar (); if ( IsWhitespace ( c )) continue; TRANSITION_ON_MATCH ( '>', COLOR_FINISH ); u8 hex = HexToByte ( c ); if (( hex != 0xff ) && ( colorSize < COLOR_MAX )) { color [ colorSize++ ] = hex; break; } TRANSITION ( STYLE_ABORT ); } //----------------------------------------------------------------// case COLOR_FINISH: { this->mRGBA = this->PackColor ( color, colorSize ); TRANSITION ( META_START ); } } } // discard overflow this->mLayout->SetTop ( this->mLineTop ); }
//----------------------------------------------------------------// bool MOAITextStyler::ParseStyle () { if ( this->mStr [ this->mIdx ] != '<' ) return false; u32 colorSize = 0; u8 color [ COLOR_MAX ]; u32 c = 0; int startIdx = this->mIdx; u32 state = STYLE_START; while ( state != DONE ) { switch ( state ) { //================================================================// // STYLE //----------------------------------------------------------------// //----------------------------------------------------------------// // see which style we're parsing case STYLE_START: { c = this->GetChar (); TRANSITION_ON_MATCH ( '<', STYLE_BODY ); TRANSITION ( STYLE_ABORT ); } //----------------------------------------------------------------// case STYLE_BODY: { c = this->GetChar (); if ( c == '<' ) { this->mIdx = startIdx + 1; this->FinishToken (); startIdx = this->mIdx; TRANSITION ( DONE ); } TRANSITION_ON_MATCH ( '/', STYLE_POP_START ); TRANSITION_ON_MATCH ( '>', STYLE_POP_FINISH ); TRANSITION_ON_MATCH ( 'c', COLOR_START ); TRANSITION ( STYLE_NAME_START ); } //----------------------------------------------------------------// case STYLE_ABORT: { this->mIdx = startIdx; TRANSITION ( DONE ); } //================================================================// // COLOR //----------------------------------------------------------------// //----------------------------------------------------------------// case COLOR_START: { colorSize = 0; c = this->GetChar (); TRANSITION_ON_MATCH ( ':', COLOR_BODY ); // reset and try to parse style name instead this->mIdx = startIdx; TRANSITION ( STYLE_NAME_START ); } //----------------------------------------------------------------// case COLOR_BODY: { c = this->GetChar (); TRANSITION_ON_MATCH ( '>', COLOR_FINISH ); u8 hex = HexToByte ( c ); if (( hex != 0xff ) && ( colorSize < COLOR_MAX )) { color [ colorSize++ ] = hex; TRANSITION ( COLOR_BODY ); } TRANSITION ( STYLE_ABORT ); } //----------------------------------------------------------------// case COLOR_FINISH: { this->FinishToken (); MOAITextStyle* style = this->mTextBox->AddAnonymousStyle ( this->mCurrentStyle ); style->mColor = this->PackColor ( color, colorSize ); this->PushStyle ( style ); TRANSITION ( DONE ); } //================================================================// // STYLE_NAME //----------------------------------------------------------------// //----------------------------------------------------------------// case STYLE_NAME_START: { c = this->GetChar (); if ( MOAIFont::IsControl ( c ) || MOAIFont::IsWhitespace ( c )) { TRANSITION ( STYLE_ABORT ); } TRANSITION_ON_MATCH ( '>', STYLE_NAME_FINISH ); TRANSITION ( STYLE_NAME_START ); } //----------------------------------------------------------------// case STYLE_NAME_FINISH: { this->FinishToken (); int namesize = this->mIdx - startIdx - 2; assert ( namesize > 0 ); char* name = ( char* )alloca ( namesize + 1 ); memcpy ( name, &this->mStr [ startIdx + 1 ], namesize ); name [ namesize ] = 0; MOAITextStyle* style = this->mTextBox->GetStyle ( name ); this->PushStyle ( style ); TRANSITION ( DONE ); } //================================================================// // STYLE_POP //----------------------------------------------------------------// //----------------------------------------------------------------// case STYLE_POP_START: { c = this->GetChar (); if ( MOAIFont::IsControl ( c ) || MOAIFont::IsWhitespace ( c )) { TRANSITION ( STYLE_ABORT ); } TRANSITION_ON_MATCH ( '>', STYLE_POP_FINISH ); TRANSITION ( STYLE_POP_START ); } //----------------------------------------------------------------// case STYLE_POP_FINISH: { this->FinishToken (); this->PopStyle (); TRANSITION ( DONE ); } } } return ( this->mIdx > startIdx ); }
size_t SplitstreamJSONScanner(SplitstreamState* s, const char* buf, size_t len, size_t* start) { int escapeCounter = s->counter[0]; SplitstreamTokenizerState state = s->state; const char* end = buf + len, *cp = buf; #define LOOP_BEGIN \ for(; cp != end; ++cp) { \ char c = *cp; \ switch(c) { #define LOOP_END \ } \ s->last = c; \ } \ goto h_End; #define TRANSITION(x) \ state = State_##x; \ ++cp; \ goto h_##x; switch(state) { case State_Init: goto h_Init; case State_Document: goto h_Document; case State_String: goto h_String; default: abort(); } h_Init: LOOP_BEGIN case '[': case '{': *start = (cp - buf); ++s->depth; TRANSITION(Document) break; case '"': TRANSITION(String); break; LOOP_END h_Document: LOOP_BEGIN case '[': case '{': if (s->depth == s->startDepth && s->startDepth > 0) { *start = (cp - buf); } ++s->depth; break; case ']': case '}': if(--s->depth == s->startDepth) { s->last = c; s->state = state; s->counter[0] = 0; return (cp - buf + 1); } break; case '"': TRANSITION(String); break; LOOP_END h_String: LOOP_BEGIN default: escapeCounter = 0; break; case '"': if(!(escapeCounter & 1)) { escapeCounter = 0; TRANSITION(Document) }
int smellslike_msrpc_toserver(struct SmellsDCERPC *smell, const unsigned char *px, unsigned length) { unsigned i; unsigned s = smell->state; enum { /* +--------+--------+--------+--------+ | ver=5 |min=0/1 | type | flags | +----+---+--------+--------+--------+ |endn| | | | +----+---+--------+--------+--------+ | frag_length | auth_length | +--------+--------+--------+--------+ | call identifier | +--------+--------+--------+--------+ */ S_VER_MAJ=S_FIRST, S_VER_MIN, S_TYPE, S_BIND_FLAGS, S_FLAGS, S_ENDIAN, S_RESERVED1b, S_RESERVED2b, S_RESERVED3b, S_FRAGLEN1b, S_FRAGLEN2b, S_AUTHLEN1b, S_AUTHLEN2b, S_RESERVED1l, S_RESERVED2l, S_RESERVED3l, S_FRAGLEN1l, S_FRAGLEN2l, S_AUTHLEN1l, S_AUTHLEN2l, S_CALLID1, S_CALLID2, S_CALLID3, S_CALLID4, S_VARHEADER, S_PDU, /* */ S_AUTH_START, S_UNKNOWN, S_UNTILEND, /* parse data until end of PDU */ S_BAD_STATEX, S_BAD_STATE /* never leave this state */ }; for (i=0; i<length;) switch (s) { case S_START: case S_VER_MAJ: if (px[i++] != 0x05) { TRANSITION(S_NO); break; } else { TRANSITION(S_VER_MIN); break; } break; case S_VER_MIN: if (px[i++] > 0x01) { TRANSITION(S_NO); break; } else { TRANSITION(S_TYPE); break; } break; case S_TYPE: { unsigned c = px[i++]; if ((/*0x00 <= c &&*/ c <= 0x03) || (0x0b <= c && c <= 0x13)) { if (c == 0x0b) { TRANSITION(S_BIND_FLAGS); } else { TRANSITION(S_FLAGS); } } else { TRANSITION(S_NO); } } break; case S_BIND_FLAGS: if (px[i++] == 0x03) { TRANSITION(S_ENDIAN); } else { TRANSITION(S_NO); } break; case S_FLAGS: if ((px[i++]&0xFC) == 0) { TRANSITION(S_ENDIAN); } else { TRANSITION(S_NO); } break; case S_ENDIAN: switch (px[i++]) { case 0x00: TRANSITION(S_RESERVED1b); break; case 0x10: TRANSITION(S_RESERVED1l); break; default: TRANSITION(S_NO); break; } break; case S_RESERVED1b: case S_RESERVED1l: case S_RESERVED2b: case S_RESERVED2l: case S_RESERVED3b: case S_RESERVED3l: if (px[i++] != 0x00) { TRANSITION(S_NO); } else { s++; } break; case S_FRAGLEN1l: case S_AUTHLEN1l: smell->len = px[i++]; s++; break; case S_FRAGLEN2l: smell->len |= (px[i++]<<8); if (smell->len < 20 || 13000 < smell->len) { TRANSITION(S_NO); } else { TRANSITION(S_AUTHLEN1l); } break; case S_AUTHLEN2l: smell->len |= (px[i++]<<8); if (6000 < smell->len) { TRANSITION(S_NO); } else { TRANSITION(S_YES); } break; case S_FRAGLEN1b: case S_AUTHLEN1b: smell->len = (unsigned short)(px[i++]<<8); s++; break; case S_FRAGLEN2b: smell->len |= px[i++]; if (smell->len < 20 || 6000 < smell->len) { TRANSITION(S_NO); } else { TRANSITION(S_AUTHLEN1l); } break; case S_AUTHLEN2b: smell->len |= px[i++]; if (6000 < smell->len) { TRANSITION(S_NO); } else { TRANSITION(S_YES); } break; case S_YES: //i = length; smell->state = (unsigned short)s; return 1; case S_NO: i = length; break; default: assert(!"unknown state"); break; } smell->state = (unsigned short)s; return 0; }