- 论坛徽章:
- 0
|
状态机...随便找一本离散数学、算法之类的书里面就有。
下面的是一个简单的状态机,作用是解析 Oracle 一个备份程序输出的信息,判断备份是否成功。
- /**
- * A state machine to determine whether db backup success.
- */
- class StateMachine {
- private:
- // state machine states
- enum {
- SM_NORMAL, // in backup
- SM_NEW_LINE, // new line begin
- SM_CHAR_EXPECTED, // expect an character (error condition is about to start)
- SM_BAR_EXPECTED, // expect a '-'
- SM_NUM_EXPECTED, // expect a number
- SM_COLON_EXPECTED, // expect a ':'
- };
- bool backupStart;
- bool error; // error occure
- int errorState; // error state
- int state; // state machine state
- int charNum; // number of char readed in error condition
- int digitNum; // number of digit readed in error condition
- std::string errMsg; // error message
- public:
- // error states
- enum {
- OB_OK = 0,
- EXP_ERROR, // unclassified client error
- EXP_ID_ERROR, // client error: invalid user name and/or password
- ORA_ERROR, // unclassified oracle error
- ORA_ID_ERROR, // user name and password error
- ORA_NO_CONNECTION, // no network adapter
- ORA_CONNECTION_TIMEOUT, // can't make connection to host
- ORA_CONNECTION_BROKEN, // network connection broken
- };
- StateMachine(void)
- : error(true)
- , errorState(OB_OK)
- , backupStart(false)
- , state(SM_NORMAL)
- , charNum(0)
- , digitNum(0)
- {
- }
- int parse(int c) {
- switch (state) {
- case SM_NORMAL:
- if (c == '\n')
- state = SM_NEW_LINE;
- break;
- case SM_NEW_LINE:
- if (c == '.') {
- state = SM_NORMAL;
- error = true;
- backupStart = true;
- } else if ((c != ' ') && (c != '\t')) {
- if (isalpha(c)) {
- state = SM_CHAR_EXPECTED; // an error is about to occur
- errMsg = "";
- errMsg += c;
- charNum = 1;
- digitNum = 0;
- } else { // ignore other character
- state = SM_NORMAL;
- }
- if (backupStart) {
- // if backup started and no error occured,
- // this maybe a successful message.
- if (errorState == OB_OK) {
- error = false;
- }
- } else {
- error = true;
- }
- }
- break;
- case SM_CHAR_EXPECTED:
- if (isalpha(c)) {
- errMsg += c;
- ++charNum;
- if (charNum == 3) {
- state = SM_BAR_EXPECTED;
- }
- } else {
- state = SM_NORMAL;
- }
- break;
- case SM_BAR_EXPECTED:
- if (c == '-') {
- errMsg += c;
- state = SM_NUM_EXPECTED;
- if (errMsg == "EXP-") {
- errorState = EXP_ERROR;
- } else if (errMsg == "ORA-") {
- errorState = ORA_ERROR;
- } else {
- state = SM_NORMAL;
- }
- } else {
- state = SM_NORMAL;
- }
- break;
- case SM_NUM_EXPECTED:
- if (isdigit(c)) {
- errMsg += c;
- ++digitNum;
- if (digitNum == 5) { // error detected
- state = SM_COLON_EXPECTED;
- }
- } else { // not an error message
- state = SM_NORMAL;
- errorState = OB_OK;
- }
- break;
- case SM_COLON_EXPECTED:
- if (c == ':') {
- state = SM_NORMAL;
- error = true;
- switch (errorState) {
- case EXP_ERROR:
- if (errMsg == "EXP-00004") {
- errorState = EXP_ID_ERROR;
- return EXP_ID_ERROR;
- }
- return EXP_ERROR;
- break;
- case ORA_ERROR:
- if (errMsg == "ORA-01017") {
- errorState = ORA_ID_ERROR;
- return ORA_ID_ERROR;
- } else if ((errMsg == "ORA-03113")
- || (errMsg == "ORA-03114")) {
- errorState = ORA_CONNECTION_BROKEN;
- return ORA_CONNECTION_BROKEN;
- } else if ((errMsg == "ORA-12535")
- || (errMsg == "ORA-12170")) {
- errorState = ORA_CONNECTION_TIMEOUT;
- return ORA_CONNECTION_TIMEOUT;
- } else if (errMsg == "ORA-12560") {
- errorState = ORA_NO_CONNECTION;
- return ORA_NO_CONNECTION;
- }
- return ORA_ERROR;
- break;
- }
- } else {
- state = SM_NORMAL;
- errorState = OB_OK;
- }
- break;
- default:
- state = SM_NORMAL;
- break;
- }
- return OB_OK;
- }
- void reset(void) {
- state = SM_NORMAL;
- error = true;
- }
- int getState(void) {
- if (error)
- return -1;
- else
- return 0;
- }
- };
复制代码 |
|