493 lines
14 KiB
C++
493 lines
14 KiB
C++
|
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
// FILE : Process.cpp
|
|
// AUTHOR : Catalin Cocos
|
|
//__________________________________________________________________________________________________
|
|
|
|
#include "stdinc.h"
|
|
#include "process.h"
|
|
#include "app.h"
|
|
#include "Tree.h"
|
|
#include "resource.h"
|
|
|
|
BOOL volatile Stop;
|
|
|
|
HANDLE hProcessSemaphore, hStopSemaphore;
|
|
HANDLE hLogFile = INVALID_HANDLE_VALUE;
|
|
|
|
|
|
void SetTxtProp( COLORREF clr/* = RGB(0, 255, 0)*/, DWORD effects /*= 0*/)
|
|
{
|
|
CHARFORMAT cf= { sizeof(CHARFORMAT) };
|
|
cf.dwMask = CFM_BOLD|CFM_FACE|CFM_COLOR|CFM_SIZE;
|
|
cf.dwEffects = effects;
|
|
cf.yHeight = -10;
|
|
cf.crTextColor = clr;
|
|
cf.bCharSet = DEFAULT_CHARSET;
|
|
cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
|
|
strcpy(cf.szFaceName, "Arial");
|
|
SendMessage(hWOut, EM_SETCHARFORMAT, SCF_SELECTION , (LPARAM) &cf ); // set the character format
|
|
}
|
|
|
|
void AddTxt( const char* text)
|
|
{
|
|
CHARRANGE cr = { -1, -1};
|
|
SendMessage(hWOut,EM_EXSETSEL, 0, (LPARAM) &cr );
|
|
SendMessage(hWOut,EM_REPLACESEL, FALSE, (LPARAM) text);
|
|
if(hLogFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD bw;
|
|
WriteFile(hLogFile, text, strlen(text), &bw, NULL );
|
|
}
|
|
}
|
|
|
|
|
|
void AddItemChildren(CSTPArray<CDirInfo>* pData, HTREEITEM hChild)
|
|
{
|
|
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hChild, 0, ~0 };
|
|
TreeView_GetItem( hWTree, &ti);
|
|
ti.state &= TVIS_STATEIMAGEMASK;
|
|
CDirInfo* pDi = ((CDirInfo*)ti.lParam);
|
|
if(pDi->GetSize() ||
|
|
ti.state == TI_STATE_FILES ||
|
|
ti.state == TI_STATE_RECURSE)
|
|
{
|
|
// add this item
|
|
CDirInfo* pNewD = new CDirInfo((char*)pDi->FileName());
|
|
if(ti.state == TI_STATE_FILES) pNewD->m_Flags = CDIR_ALL;
|
|
if(ti.state == TI_STATE_RECURSE) pNewD->m_Flags = CDIR_RECURSE;
|
|
if(!pNewD->m_Flags)
|
|
{
|
|
// add the file list
|
|
pNewD->SetSize(pDi->GetSize());
|
|
for(int i = pNewD->GetUpperBound(); i>=0; i-- )
|
|
pNewD->SetAt(i, new CFileName( (char*)(*pDi)[i]->FileName() ));
|
|
}
|
|
BOOL NA;
|
|
pData->SAdd(pNewD, NA, FALSE);
|
|
}
|
|
for( HTREEITEM hNext = TreeView_GetChild( hWTree, hChild); hNext; hNext = TreeView_GetNextSibling( hWTree, hNext))
|
|
AddItemChildren( pData, hNext);
|
|
}
|
|
|
|
void AddFile( CSTPArray<CDirInfo>* pData, char* filename )
|
|
{
|
|
if(!CnvEng.IsFileSupported(filename))
|
|
return;
|
|
char Dir[_MAX_PATH];
|
|
char Fname[_MAX_FNAME];
|
|
_splitpath(filename, Dir, NULL, Fname, NULL);
|
|
_splitpath(filename, NULL, Dir+strlen(Dir), NULL, Fname+strlen(Fname));
|
|
Dir[strlen(Dir) - 1] = 0;
|
|
CDirInfo* pDi = new CDirInfo(Dir);
|
|
int idx, ins;
|
|
idx = pData->Index( pDi, &ins);
|
|
if(idx>=0)
|
|
{
|
|
delete pDi; // we have a match
|
|
if((*pData)[idx]->m_Flags) return;
|
|
BOOL NA;
|
|
CFileName * pName = new CFileName(Fname);
|
|
(*pData)[idx]->SAdd(pName, NA, FALSE);
|
|
if(NA) delete pName;
|
|
return;
|
|
}
|
|
if(ins>0 && strlen((*pData)[ins-1]->FileName()) <= strlen(Dir) &&
|
|
!_strnicmp((*pData)[ins-1]->FileName(), Dir, strlen((*pData)[ins-1]->FileName())) &&
|
|
(*pData)[ins-1]->m_Flags == CDIR_RECURSE)
|
|
{
|
|
delete pDi; // this is a sub-folder of a recursive folder, we need no info on it
|
|
return;
|
|
}
|
|
// we need to add the folder
|
|
pDi->Add(new CFileName(Fname)); // add its first file...
|
|
pData->InsertAt(ins, pDi, 1); // and add it in the list
|
|
}
|
|
|
|
void AddTextCollection( CSTPArray<CDirInfo>* pData, char* filename )
|
|
{
|
|
CTextParser P; // the file parser object
|
|
if(!P.AccessFile(filename)) // try to acces the txt file
|
|
return;
|
|
P.SetType( "\\._-", CTP_TEXT);
|
|
P.SetType( "^", CTP_LINE_COMMENT);
|
|
char Dir[_MAX_PATH];
|
|
_splitpath(filename, Dir, NULL, NULL, NULL);
|
|
_splitpath(filename, NULL, Dir+strlen(Dir), NULL, NULL);
|
|
Dir[strlen(Dir) - 1] = 0;
|
|
char* bksl = strrchr( Dir, '\\');
|
|
if(bksl) bksl[1] = 0;
|
|
else *Dir = 0;
|
|
char* Word = NULL, *NextWord;
|
|
DWORD i = P.Advance();
|
|
while(!(i & CTP_EOF ))
|
|
{
|
|
Word = P.Word();
|
|
char* Begin = strchr( Word, ')');
|
|
if(Begin) Word = Begin+1;
|
|
char FullName[_MAX_PATH+_MAX_FNAME];
|
|
strcpy( FullName, Dir);
|
|
strcat( FullName, Word );
|
|
AddFile( pData, FullName);
|
|
do
|
|
{
|
|
i = P.Advance();
|
|
NextWord = P.Word();
|
|
if(Begin = strchr( NextWord, ')')) NextWord = Begin+1;
|
|
}
|
|
while( !(i & CTP_EOF ) && !strcmpi(Word, NextWord));
|
|
}
|
|
}
|
|
|
|
void AddLogCollection( CSTPArray<CDirInfo>* pData, char* filename )
|
|
{
|
|
CTextParser P; // the file parser object
|
|
if(!P.AccessFile(filename)) // try to acces the log file
|
|
return;
|
|
P.SetType( "\\._-", CTP_TEXT);
|
|
P.SetType( "*", CTP_LINE_COMMENT);
|
|
DWORD i = P.Advance();
|
|
while(!(i & CTP_EOF ))
|
|
{
|
|
if(!strcmp(P.Word(), "Obtaining"))
|
|
{
|
|
i = P.Advance();
|
|
if( !(i & CTP_EOF ) )
|
|
AddFile( pData, P.Word());
|
|
}
|
|
i = P.Advance();
|
|
}
|
|
}
|
|
|
|
|
|
unsigned long Lines, Files, Directories, TotalFiles, Errors;
|
|
float Length, Output;
|
|
SYSTEMTIME systime;
|
|
BOOL DirectoryNotDisplayed;
|
|
CDirInfo* pCrtDir;
|
|
|
|
void ProcessFile( char* szFile)
|
|
{
|
|
char OutputName[_MAX_PATH +10];
|
|
strcpy(OutputName, szFile);
|
|
strcat(OutputName, BINEXTENSION);
|
|
|
|
switch(OperatingMode)
|
|
{
|
|
case ID_MODE_CLEAN:
|
|
{
|
|
char Ext[_MAX_EXT];
|
|
char fName[_MAX_FNAME];
|
|
_splitpath(szFile, NULL, NULL, fName, Ext );
|
|
if(!strcmp (Ext, BINEXTENSION) && (!CnvEng.IsFilteringActive() || CnvEng.IsFileSupported( fName )))
|
|
{
|
|
if(DirectoryNotDisplayed)
|
|
{
|
|
AddTxt("\r\n");//Processing ");
|
|
AddTxt( pCrtDir->FileName());
|
|
AddTxt( " ...\r\n");
|
|
DirectoryNotDisplayed = FALSE;
|
|
}
|
|
Files ++;
|
|
AddTxt("\t");
|
|
AddTxt(fName);
|
|
AddTxt(Ext);
|
|
if(!DeleteFile(szFile)) AddTxt(" Error: Deletion failed!");
|
|
AddTxt("\r\n");
|
|
}
|
|
}
|
|
break;
|
|
case ID_MODE_NORMAL:
|
|
{
|
|
HANDLE hOut = CreateFile( OutputName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if(hOut != INVALID_HANDLE_VALUE)
|
|
{
|
|
HANDLE hIn = CreateFile( szFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if( hIn != INVALID_HANDLE_VALUE )
|
|
{
|
|
BY_HANDLE_FILE_INFORMATION iIn, iOut;
|
|
GetFileInformationByHandle( hIn, &iIn);
|
|
GetFileInformationByHandle( hOut, &iOut);
|
|
CloseHandle(hIn);
|
|
if(CompareFileTime(&iIn.ftLastWriteTime, &iOut.ftLastWriteTime) <= 0 )
|
|
{
|
|
// the file is up to date
|
|
CloseHandle(hOut);
|
|
break;
|
|
}
|
|
}
|
|
CloseHandle(hOut);
|
|
}
|
|
}
|
|
case ID_MODE_FORCED:
|
|
{
|
|
DWORD len, Outlen;
|
|
unsigned line;
|
|
char Ext[_MAX_EXT];
|
|
char fName[_MAX_FNAME];
|
|
_splitpath(szFile, NULL, NULL, fName, Ext );
|
|
|
|
if(DirectoryNotDisplayed)
|
|
{
|
|
AddTxt("\r\n");//Processing ");
|
|
AddTxt( pCrtDir->FileName());
|
|
AddTxt( " ...\r\n");
|
|
DirectoryNotDisplayed = FALSE;
|
|
}
|
|
|
|
AddTxt("\t");
|
|
AddTxt(fName);
|
|
AddTxt(Ext);
|
|
Files ++;
|
|
|
|
SetTxtProp( RGB(255, 0, 0), CFE_BOLD );
|
|
int TheERROR = CnvEng.Convert( szFile, OutputName, &line, &len, &Outlen );
|
|
switch(TheERROR )
|
|
{
|
|
case SB_ERR_OUTPUT_FILEOPEN: AddTxt(" Error! Unable to create the output file."); break;
|
|
case SB_ERR_FILEOPEN: AddTxt(" Error! Unable to open the file."); break;
|
|
case SB_ERR_BAD_FILE_EXTENSION: AddTxt(" Error! This file type is not currently supported."); break;
|
|
case SB_ERR_PARAMETER_MISSING:
|
|
AddTxt(" Error (line ");
|
|
itoa( line, OutputName, 10);
|
|
AddTxt( OutputName );
|
|
AddTxt( ")! Parameter Missing.");
|
|
break;
|
|
case SB_ERR_UNKNOWN_DIRECTIVE:
|
|
AddTxt(" Error (line ");
|
|
itoa( line, OutputName, 10);
|
|
AddTxt( OutputName );
|
|
AddTxt( ")! Unknown Directive.");
|
|
break;
|
|
case SB_ERR_UNKNOWN_SECTION:
|
|
AddTxt(" Error (line ");
|
|
itoa( line, OutputName, 10);
|
|
AddTxt( OutputName );
|
|
AddTxt( ")! Unknown Section Type.");
|
|
break;
|
|
case SB_ERR_UNKNOWN_ENTRY:
|
|
AddTxt(" Error (line ");
|
|
itoa( line, OutputName, 10);
|
|
AddTxt( OutputName );
|
|
AddTxt( ")! Unknown Entry Type.");
|
|
break;
|
|
case SB_ERR_UNEXPECTED_EOF:
|
|
AddTxt(" Error (line ");
|
|
itoa( line, OutputName, 10);
|
|
AddTxt( OutputName );
|
|
AddTxt( ")! Unexpected End of File.");
|
|
break;
|
|
}
|
|
SetTxtProp();
|
|
AddTxt("\r\n");
|
|
Lines += line;
|
|
Length += ((float)len)/1024/1024;
|
|
Output += ((float)Outlen)/1024/1024;
|
|
if(TheERROR)
|
|
Errors++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ProcessDirectory( CDirInfo* pDi )
|
|
{
|
|
char buffer[_MAX_PATH];
|
|
|
|
DirectoryNotDisplayed = TRUE;
|
|
pCrtDir = pDi;
|
|
|
|
// AddTxt("\r\n");//Processing ");
|
|
// AddTxt( pDi->FileName());
|
|
// AddTxt( " ...\r\n");
|
|
|
|
Directories ++;
|
|
if(pDi->m_Flags)
|
|
{
|
|
CTypedPtrArray<CDirInfo*> arRecFolders;
|
|
arRecFolders.SetGranularity(5);
|
|
|
|
strcpy(buffer, pDi->FileName());
|
|
strcat(buffer, "\\*.*");
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hSearch = FindFirstFile( buffer, &fd );
|
|
for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found && !Stop; Found = FindNextFile( hSearch, &fd))
|
|
{
|
|
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
//we found a sub-directory
|
|
if(pDi->m_Flags == CDIR_RECURSE && *fd.cFileName != '.')
|
|
{
|
|
strcpy( buffer, pDi->FileName());
|
|
strcat( buffer, "\\");
|
|
strcat( buffer, fd.cFileName);
|
|
//create the new structure
|
|
CDirInfo* pNewDir = new CDirInfo( buffer );
|
|
pNewDir->m_Flags = CDIR_RECURSE;
|
|
arRecFolders.Add(pNewDir);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//we found a file
|
|
TotalFiles++;
|
|
if(OperatingMode == ID_MODE_CLEAN || CnvEng.IsFileSupported(fd.cFileName))
|
|
{
|
|
strcpy( buffer, pDi->FileName());
|
|
strcat( buffer, "\\");
|
|
strcat( buffer, fd.cFileName);
|
|
ProcessFile( buffer ); // convert the file
|
|
}
|
|
}
|
|
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
|
|
}
|
|
if(hSearch != INVALID_HANDLE_VALUE) FindClose(hSearch);
|
|
for( int i = 0, k = arRecFolders.GetSize(); i<k && !Stop; i++) // process the subdirectories
|
|
{
|
|
ProcessDirectory(arRecFolders[i]);
|
|
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
|
|
}
|
|
arRecFolders.DeleteAll();
|
|
}
|
|
else for(int i = 0, k = pDi->GetSize(); i<k && !Stop; i++)
|
|
{
|
|
TotalFiles++;
|
|
//process the selected files
|
|
strcpy( buffer, pDi->FileName());
|
|
strcat( buffer, "\\");
|
|
strcat( buffer, (*pDi)[i]->FileName());
|
|
if(OperatingMode == ID_MODE_CLEAN)
|
|
strcat( buffer,BINEXTENSION );
|
|
ProcessFile( buffer ); // convert the file
|
|
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
|
|
}
|
|
}
|
|
|
|
void __cdecl ProcessThread(void* pParam)
|
|
{
|
|
char buffer[_MAX_PATH];
|
|
strcpy(buffer, CrtCfg);
|
|
char* ext = strrchr(buffer, '.');
|
|
if(ext) strcpy(ext, ".log");
|
|
else strcat(buffer, ".log");
|
|
hLogFile = CreateFile( buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
SetWindowText(hWOut, "");
|
|
AddTxt("------------ Configuration: ");
|
|
AddTxt( CrtCfg );
|
|
AddTxt(" ------------\r\n");
|
|
|
|
Output = Length = 0.f;
|
|
Errors = TotalFiles = Lines = Files = Directories = 0;
|
|
GetSystemTime( &systime );
|
|
|
|
CSTPArray<CDirInfo>* pData = (CSTPArray<CDirInfo>*) pParam;
|
|
//--------------------------------------------------------
|
|
for(int i = 0, k = pData->GetSize(); i<k && !Stop; i++)
|
|
{
|
|
ProcessDirectory( (*pData)[i] );
|
|
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
|
|
}
|
|
//--------------------------------------------------------
|
|
|
|
pData->DeleteAll();
|
|
delete pData;
|
|
// compute the elapsed time
|
|
SYSTEMTIME finalTime;
|
|
GetSystemTime( &finalTime );
|
|
|
|
AddTxt("\r\n");
|
|
if(Stop) AddTxt( "Processing canceled by user.\r\n" );
|
|
AddTxt("--------------------------------------\r\n");
|
|
AddTxt("Processing Mode:\t");
|
|
switch(OperatingMode)
|
|
{
|
|
case ID_MODE_NORMAL: AddTxt(" NORMAL\r\n"); break;
|
|
case ID_MODE_FORCED: AddTxt(" FORCED\r\n"); break;
|
|
case ID_MODE_CLEAN: AddTxt(" CLEAN-UP\r\n"); break;
|
|
}
|
|
sprintf( buffer,"Total Directories :\t%u\r\n", Directories);
|
|
AddTxt( buffer );
|
|
sprintf( buffer,"Total Files :\t\t%u\r\n", TotalFiles);
|
|
AddTxt( buffer );
|
|
sprintf( buffer,"Processed Files :\t%u\r\n",Files);
|
|
AddTxt( buffer );
|
|
sprintf( buffer,"Processed Lines :\t%u\r\n",Lines);
|
|
AddTxt( buffer );
|
|
sprintf( buffer,"Read Data (MB) :\t%.3f\r\n",Length);
|
|
AddTxt( buffer );
|
|
sprintf( buffer,"Output Data (MB) :\t%.3f\r\n",Output);
|
|
AddTxt( buffer );
|
|
int hour = finalTime.wHour - systime.wHour;
|
|
int minute = finalTime.wMinute - systime.wMinute + hour*60;
|
|
int second = finalTime.wSecond - systime.wSecond;
|
|
if( second<0)
|
|
{
|
|
minute--;
|
|
second+=60;
|
|
}
|
|
sprintf( buffer,"Processing Time :\t%i:%02i\r\n",minute,second);
|
|
AddTxt( buffer );
|
|
AddTxt("--------------------------------------\r\n");
|
|
if(Errors)
|
|
{
|
|
SetTxtProp( RGB(255, 0, 0), CFE_BOLD );
|
|
sprintf( buffer,"\t%u Error%s.\r\n",Errors, Errors>1?"s":"");
|
|
AddTxt( buffer );
|
|
SetTxtProp();
|
|
AddTxt("--------------------------------------\r\n");
|
|
}
|
|
if(hLogFile != INVALID_HANDLE_VALUE) CloseHandle(hLogFile);
|
|
PlaySound( "SystemAsterisk", NULL, SND_ALIAS|SND_NOWAIT|SND_ASYNC);
|
|
Processing = FALSE;
|
|
ReleaseSemaphore( hProcessSemaphore, 1, NULL);
|
|
OnIdle();
|
|
}
|
|
|
|
void Process( int What )
|
|
{
|
|
// initializing data...
|
|
HCURSOR hOldCursor = SetCursor( LoadCursor(NULL, IDC_WAIT));
|
|
SetWindowText( hWStatusbar, "Initializing, please wait...");
|
|
|
|
CSTPArray<CDirInfo>* pData = new CSTPArray<CDirInfo>;
|
|
pData->SetGranularity(20);
|
|
|
|
if(What & PROCESS_SELECTION)
|
|
// set the tree selection
|
|
for(HTREEITEM hChild = TreeView_GetRoot(hWTree); hChild; hChild = TreeView_GetNextSibling(hWTree, hChild))
|
|
AddItemChildren( pData, hChild);
|
|
if(What & PROCESS_COLLECTIONS)
|
|
for( int i = ListView_GetItemCount( hWList ) -1 ; i>=0; i-- )
|
|
{
|
|
LV_ITEM it = {LVIF_STATE|LVIF_PARAM, i, 0, 0, ~0};
|
|
ListView_GetItem( hWList, &it);
|
|
if(it.state & LSTATE_CHECKED)
|
|
{
|
|
char Ext[_MAX_EXT];
|
|
_splitpath((char*)it.lParam, NULL, NULL, NULL, Ext);
|
|
if(!strcmpi(Ext+1, "txt"))
|
|
AddTextCollection( pData, (char*)it.lParam);
|
|
else if(!strcmpi(Ext+1, "log"))
|
|
AddLogCollection( pData, (char*)it.lParam);
|
|
}
|
|
}
|
|
|
|
SetCursor( hOldCursor );
|
|
SetWindowText( hWStatusbar, "Ready");
|
|
|
|
Processing = TRUE;
|
|
Stop = FALSE;
|
|
WaitForSingleObject(hStopSemaphore, 0);
|
|
WaitForSingleObject(hProcessSemaphore, 0); // reset the semaphores state
|
|
OnIdle();
|
|
_beginthread(ProcessThread, 0, pData); // launch the processing
|
|
// SetFocus( hWOut );
|
|
}
|
|
|
|
void StopProcessing()
|
|
{
|
|
if(!Processing) return;
|
|
ReleaseSemaphore( hStopSemaphore, 1, NULL);
|
|
}
|
|
|