switch (state)
case 1:
switch (input)
case USER: state = 2; break;
case QUIT: state = 4; break;
default: state = 5; break;
case 2:
switch (input)
case PASS: state = 3; break;
case QUIT: state = 4; break;
default: state = 5; break;
case 3:
switch (input)
case LIST: state = 3; break;
case QUIT: state = 4; break;
default: state = 5; break;
case 4:
state = 4; break;
case 5:
switch (input)
case QUIT: state = 4; break;
default: state = 5; break;
1 2 3 4 5 USER 2 5 5 4 5 PASS 5 3 5 4 5 LIST 5 5 3 4 5 QUIT 4 4 4 4 4
typedef struct
{
char *command;
int (*function)();
int valid_in;
int win;
int lose;
} vector;
vector switchtable[] =
{
{"user", user, AUTH1, AUTH2, AUTH1},
{"pass", pass, AUTH2, TRANS, AUTH},
.
.
.
{NULL, NULL, 0, 0, 0}
};
class SPop { public: SPop(); void USER(); void PASS(); char* LIST(); void QUIT(); private: friend class SPopState; void ChangeState (SPopState* NewState) SPopState* CurrentState; }; SPop :: SPop () { CurrentState = new Start(); } void SPop :: ChangeState (SPopState* NewState) { CurrentState = NewState; } void SPop :: USER () { CurrentState -> USER( this ) } void SPop :: PASS () { CurrentState -> PASS ( this ) } char* SPop :: LIST () { return CurrentState -> LIST ( this ) } void SPop :: QUIT () { CurrentState -> QUIT ( this ) }
class SPopState { public: virtual void USER ( SPop* Context ); virtual void PASS ( SPop* Context ); virtual char* LIST ( SPop* Context ); virtual void QUIT ( SPop* Context ); } void SPopState :: USER ( SPop* Context ) { Context -> ChangeState( new Error() ); } void SPopState :: PASS ( SPop* Context ) { Context -> ChangeState( new Error() ); } void SPopState :: LIST ( SPop* Context ) { Context -> ChangeState( new Error() ); } void SPopState :: QUIT ( SPop* Context ) { Context -> ChangeState( new Quit() ); }
class Start : public SPopState { public: virtual void USER ( SPop* Context ); } void Start :: USER ( SPop* Context ) { Context -> ChangeState( new Authenticate() ); }
class Authenticate : public SPopState { public: virtual void PASS ( SPop* Context ); } void Authenticate :: PASS ( SPop* Context ) { Context -> ChangeState( new List() ); }
class List : public SPopState { public: char* List ( SPop* Context ); } char* List :: List ( SPop* Context ) { Get and return list }
class Error : public SPopState { void QUIT ( SPop* Context ); } void Error :: QUIT ( SPop* Context ) { Context -> ChangeState( new Quit() ); }
class Error : public SPopState { void QUIT ( SPop* Context ); }
class SPop { public: SPop(); void USER(); void PASS(); char* LIST(); void QUIT(); private: char* User; char* Password; friend class SPopState; void ChangeState (SPopState* NewState) SPopState* CurrentState; };
class Start : public SPopState { public: virtual void USER (char* UserName, SPop* Context ); } void Start :: USER (char* UserName, SPop* Context ) { Context -> User = UserName; Context -> ChangeState( new Authenticate() ); }
class Start : public SPopState { public: static SPopState* Instance(); void USER ( SPop* Context ); protected: Start(); private: static SPopState* _instance; } SPopState* Start :: _instance = 0; SPopState* Start :: Instance() { if (_instance == 0) _instance = new Start(); return _instance; }
if (Input == "USER") x -> USER() else if (Input == "PASS") x -> PASS() else if (Input == "LIST") x -> LIST()
class SPopState { public: virtual void input( char* Message, SPop* Context) = 0; // Common commands virtual void QUIT ( SPop* Context ); virtual void Error ( SPop* Context ); } void SPopState :: LIST ( SPop* Context ) { Context -> ChangeState( new Error() ); } void SPopState :: QUIT ( SPop* Context ) { Context -> ChangeState( new Quit() ); }
class Start : public SPopState { public: virtual void USER (char* Name, SPop* Context ); virtual void input( char* Message, SPop* Context); } void Start :: input( char* Message, SPop* Context) { if (Message starts with "USER") USER(last part of Message, Context) else if (Message starts with "QUIT") QUIT(Context) } void Start :: USER (char* Name, SPop* Context ) { Context -> User = Name; Context -> ChangeState( Authenticate::Instance() ); }
Dictionary < string, (SPopState ::*) ( *SPop ) > Commands; Commands["USER"] = SPop :: User( *SPop ); //Usage string Message read( Message ) Commands[ first part of message](second part of message)
SPop Protocol; while ( SPop.state() =! "Quit" ) { readn( ClientSocket , message ) ; response = SPop.input ( message ); if ( response =! null ) writen( ClientSocket , response ); }SPop
SPop Protocol; Protocol.interactWithClient( ClientSocket );
int main(int argc; char* argv[]) { CommandLineOption ServerOptions(argc, argv); if ( ServerOptions.containsOneOfFlags( "ip" ) =! TRUE) { write error message; exit(); }; if ( ServerOptions.containsFlag( "i") == TRUE ) {// inetd respondToResquestOn(cin, cout); } else { int PortNumber; int ConvertError; ConvertError = stringToInt( ServerOptions.flagValue("p"), PortNumber); assert( ConvertError =! -1); runConcurrentServerOn(PortNumber); } }