forked from LosaDev/ls-2019-source
370 lines
7.2 KiB
C++
370 lines
7.2 KiB
C++
#include "StdAfx.h"
|
|
#include "BatchScanner.h"
|
|
#include "PlayCommand.h"
|
|
#include "StopCommand.h"
|
|
#include "SyncCommand.h"
|
|
#include "QuitCommand.h"
|
|
#include "InstallCommand.h"
|
|
#include "UninstallCommand.h"
|
|
|
|
|
|
BatchScanner::BatchScanner(void)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
|
|
BatchScanner::~BatchScanner(void)
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void BatchScanner::Init()
|
|
{
|
|
InitCommand();
|
|
InitOption();
|
|
}
|
|
|
|
void BatchScanner::Destroy()
|
|
{
|
|
}
|
|
|
|
void BatchScanner::InitCommand()
|
|
{
|
|
strcpy_s(m_commandTokens[BCT_PLAY], "play" );
|
|
strcpy_s(m_commandTokens[BCT_STOP], "stop");
|
|
strcpy_s(m_commandTokens[BCT_SYNC], "sync");
|
|
strcpy_s(m_commandTokens[BCT_INSTALL], "install");
|
|
strcpy_s(m_commandTokens[BCT_UNINSTALL],"uninstall");
|
|
strcpy_s(m_commandTokens[BCT_BACKUP], "backup");
|
|
strcpy_s(m_commandTokens[BCT_REMOVE], "remove");
|
|
strcpy_s(m_commandTokens[BCT_WAIT], "wait");
|
|
strcpy_s(m_commandTokens[BCT_QUIT], "quit");
|
|
}
|
|
|
|
void BatchScanner::InitOption()
|
|
{
|
|
strcpy_s(m_optionTokens[BOT_SERVICE_WAIT], "/w");
|
|
strcpy_s(m_optionTokens[BOT_ALL_SERVICE], "/a");
|
|
strcpy_s(m_optionTokens[BOT_TABINDEX], "/t");
|
|
}
|
|
|
|
BaseCommand* BatchScanner::Scanner( const char* commandLine )
|
|
{
|
|
if( !commandLine )
|
|
return NULL;
|
|
|
|
int commandLen = strlen(commandLine);
|
|
if( 0 == commandLen ) return NULL;
|
|
|
|
VECCHARTOKEN tokens;
|
|
if( SplitToken( commandLine, commandLen, tokens ) )
|
|
{
|
|
return MakeCommand( tokens );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL BatchScanner::SplitToken( const char* commandLine, int commandLen, VECCHARTOKEN& tokens )
|
|
{
|
|
if( !commandLine || strlen(commandLine) == 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
int index = -1;
|
|
do
|
|
{
|
|
JumpSplitChar( commandLine, commandLen, index ); //공백을 제외한 첫글자 위치를 index에 넣어줌.
|
|
|
|
if( commandLine[index] == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
tokens.push_back( &commandLine[index] ); //첫 문자열을 집어넣음.
|
|
|
|
FindSplitChar(commandLine, commandLen, index ); //공백을 만날때 까지 index ++;
|
|
}while(commandLine[index] != NULL); //배치 파일의 글자 시작 index를 VECCHARTOKEN에 push
|
|
|
|
if( tokens.size() < 1 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void BatchScanner::JumpSplitChar( const char* commandLine, int commandLen, int& index )
|
|
{
|
|
while( (TOKEN_SPLIT_CHAR == commandLine[++index]) && (commandLen >= index) )
|
|
{
|
|
}
|
|
}
|
|
|
|
void BatchScanner::FindSplitChar( const char* commandLine, int commandLen, int& index )
|
|
{
|
|
while( (TOKEN_SPLIT_CHAR != commandLine[++index]) && (commandLen >= index ) )
|
|
{
|
|
if( NULL == commandLine[index] )
|
|
break;
|
|
}
|
|
}
|
|
|
|
BaseCommand* BatchScanner::MakeCommand( VECCHARTOKEN& tokens )
|
|
{
|
|
if( tokens.size() < 1 )
|
|
return NULL;
|
|
|
|
DWORD commandType = BCT_NONE; //CommandState()를 통해 play,stop 같은 커멘트 타입이 정해짐.
|
|
DWORD optionBit = 0;
|
|
SETINDEXES tabIndexes;
|
|
SETINDEXES stringIndexes;
|
|
|
|
int index = 0;
|
|
CommandStateType state = CS_COMMAND; //배치파일 처음은 play stop 같은 commend임,
|
|
while( (CS_DONE != state) && (CS_FAIL != state) )
|
|
{
|
|
if( (unsigned int)index >= tokens.size() )
|
|
{
|
|
state = CS_DONE;
|
|
}
|
|
|
|
switch(state)
|
|
{
|
|
case CS_COMMAND:
|
|
{
|
|
state = CommandState( tokens[index], commandType );
|
|
index++;
|
|
}
|
|
break;
|
|
case CS_OPTION:
|
|
{
|
|
state = OptionState( tokens[index], optionBit );
|
|
if( CS_STRING != state ) // 서비스네임이라면 인덱스 증가 시키면 안됨
|
|
{
|
|
index++;
|
|
}
|
|
}
|
|
break;
|
|
case CS_TABINDEX:
|
|
{
|
|
state = TabIndexState( tokens[index], tabIndexes );
|
|
if( CS_TABINDEX == state )
|
|
{
|
|
index++;
|
|
}
|
|
}
|
|
break;
|
|
case CS_STRING:
|
|
{
|
|
stringIndexes.insert( index );
|
|
state = CS_OPTION;
|
|
index++;
|
|
}
|
|
break;
|
|
case CS_DONE:
|
|
{
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( CS_FAIL == state )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//분리한 각 코맨드 및 문자들 처리./////////////////
|
|
BaseCommand* command = GetCommand( commandType );
|
|
|
|
command->SetCommandText( tokens[0] );
|
|
command->SetOption( optionBit );
|
|
for( INDEXESITER it = tabIndexes.begin() ; it != tabIndexes.end() ; ++it )
|
|
{
|
|
int tabIndex = *it;
|
|
command->AddIndex( tabIndex );
|
|
}
|
|
|
|
for( INDEXESITER it = stringIndexes.begin() ; it != stringIndexes.end() ; ++it )
|
|
{
|
|
int stringIndex = *it;
|
|
command->AddString( tokens[stringIndex], GetServiceNameLen( tokens[stringIndex] ) );
|
|
}
|
|
|
|
return command; //batchCommand;
|
|
}
|
|
|
|
BaseCommand* BatchScanner::GetCommand( DWORD type )
|
|
{
|
|
BaseCommand* command = NULL;
|
|
switch( type )
|
|
{
|
|
case BCT_PLAY:
|
|
command = new PlayCommand;
|
|
break;
|
|
case BCT_STOP:
|
|
command = new StopCommand;
|
|
break;
|
|
case BCT_SYNC:
|
|
command = new SyncCommand;
|
|
break;
|
|
case BCT_INSTALL:
|
|
command = new InstallCommand;
|
|
break;
|
|
case BCT_UNINSTALL:
|
|
command = new UninstallCommand;
|
|
break;
|
|
case BCT_QUIT:
|
|
command = new QuitCommand;
|
|
break;
|
|
case BCT_BACKUP:
|
|
case BCT_REMOVE:
|
|
case BCT_WAIT:
|
|
default:
|
|
break;
|
|
}
|
|
return command;
|
|
}
|
|
|
|
BatchScanner::CommandStateType BatchScanner::CommandState( const char* command, DWORD& commandType )
|
|
{
|
|
commandType = GetCommandType( command );
|
|
|
|
if( BCT_END == commandType )
|
|
{
|
|
return CS_FAIL;
|
|
}
|
|
else
|
|
{
|
|
return CS_OPTION;
|
|
}
|
|
}
|
|
|
|
BatchScanner::CommandStateType BatchScanner::OptionState( const char* command, DWORD& optionBit )
|
|
{
|
|
DWORD option = GetOptionType( command );
|
|
|
|
if( BOT_END == option )
|
|
{
|
|
return CS_STRING;
|
|
}
|
|
else if( BOT_TABINDEX == option )
|
|
{
|
|
return CS_TABINDEX;
|
|
}
|
|
else
|
|
{
|
|
if( BITCHK( optionBit, option ) )
|
|
{
|
|
return CS_FAIL;
|
|
}
|
|
else
|
|
{
|
|
BITON( optionBit, option ); // /w (optionBit == 1), /a (potionBit == 5)
|
|
return CS_OPTION;
|
|
}
|
|
}
|
|
}
|
|
|
|
BatchScanner::CommandStateType BatchScanner::TabIndexState( const char* command, SETINDEXES& tabIndexes )
|
|
{
|
|
DWORD digit;
|
|
if( GetDigit( command, digit ) )
|
|
{
|
|
tabIndexes.insert( digit );
|
|
return CS_TABINDEX;
|
|
}
|
|
return CS_OPTION;
|
|
}
|
|
|
|
int BatchScanner::GetCommandType( const char* command )
|
|
{
|
|
int type = 0;
|
|
for( type ; type < BCT_END ; type++ )
|
|
{
|
|
if( TokenCompare( m_commandTokens[type], command ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
int BatchScanner::GetOptionType( const char* command )
|
|
{
|
|
unsigned int type = 0;
|
|
for( type ; type < BOT_END ; type++ )
|
|
{
|
|
if( TokenCompare( m_optionTokens[type], command ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
BOOL BatchScanner::GetDigit( const char* command, DWORD& digit )
|
|
{
|
|
digit = 0;
|
|
char ch = 0;
|
|
while( true )
|
|
{
|
|
ch = *command;
|
|
if( IsDigit( ch ) )
|
|
{
|
|
digit = digit*10 + ( ch - '0' );
|
|
command++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( (TOKEN_SPLIT_CHAR == ch) || (NULL == ch) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL BatchScanner::TokenCompare( const char* token, const char* command )
|
|
{
|
|
//미리 저장해둔 명령어 비교.
|
|
unsigned int tokenLen = strlen(token);
|
|
if( strlen(command) < tokenLen )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if( strncmp( token, command, tokenLen ) == 0)
|
|
{
|
|
if( (TOKEN_SPLIT_CHAR == command[tokenLen]) ||
|
|
(NULL == command[tokenLen]) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int BatchScanner::GetServiceNameLen( const char* serviceName )
|
|
{
|
|
int len = 0;
|
|
while(true)
|
|
{
|
|
if( (TOKEN_SPLIT_CHAR == serviceName[len]) ||
|
|
(NULL == serviceName[len]) )
|
|
{
|
|
break;
|
|
}
|
|
len++;
|
|
}
|
|
|
|
return len;
|
|
} |