ZT/sources/LogMgr.cpp

645 lines
15 KiB
C++

/*******************************************************************************
* *
* Société de Transports de Montréal. *
* 2012 - 2013 *
* *
* Projet Zones Tests *
* *
* *
* *
*******************************************************************************/
/*
Description:
Cette classe est responsable de la création d'une liste d'objets CLogElement
à partir des données de passage des trains contenues dans les fichiers log.
Cette classe est principalement utilisée par l'interface graphique pour la
visualisation des passages.
*/
/* ************************************************************************** */
/* Revision:
### 20121024 JFM
### YYYYMMDD Description du besoin ou du bug
Description du changement.
*/
/* ************************************************************************** */
#include "LogMgr.h"
#include "TrainLogFileMgr.h"
#include "ZTLog.h"
CLogMgr::CLogMgr()
{
mMaxFileCount = MAX_LOG_FILE_COUNT;
mKeepMPM10Logs = false;
}
CLogMgr::~CLogMgr()
{
DestroyLogList();
}
unsigned int CLogMgr::DestroyLogList()
{
for(int i = 0; i < mPassagesList.size(); i++)
{
delete mPassagesList.at(i);
}
mPassagesList.clear();
return RET_OK;
}
int CLogMgr::KeepAllMPM10Logs(bool keep)
{
mKeepMPM10Logs = keep;
return RET_OK;
}
int CLogMgr::KeepAllZT1Logs(bool keep)
{
mKeepZT1Logs = keep;
return RET_OK;
}
int CLogMgr::KeepAllZT2Logs(bool keep)
{
mKeepZT2Logs = keep;
return RET_OK;
}
int CLogMgr::SetMaxLogFilesCount(int count)
{
mMaxFileCount = count;
return RET_OK;
}
//Parse all the logs at once. This may freeze the program and the GUI depending
//on the number of log files.
//The KeepData parameter determines if the raw data should be kept in RAM (Not recommended).
//It is recommended to load it when needed via LoadLogData().
unsigned int CLogMgr::ParseLogs(bool KeepData)
{
DestroyLogList();
// QStringList LogFilters;
// LogFilters << "*.bin";
// QDir LogDir("./Trains/");
// LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
// LogDir.setNameFilters(LogFilters);
// LogDir.setSorting(QDir::Name);
QFileInfoList list = GetLogsFilenameList();//LogDir.entryInfoList();
if(list.size() == 0)
return RET_OK;
//Extract data for each passage
for(int i = 0; i < list.size(); i++)
{
ParseNewLog(list.at(i).filePath(),KeepData,false);
}
return RET_OK;
}
QFileInfoList CLogMgr::GetLogsFilenameList()
{
QStringList LogFilters;
LogFilters << "*.bin";
QDir LogDir("./Trains/");
LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
LogDir.setNameFilters(LogFilters);
LogDir.setSorting(QDir::Name);
QFileInfoList list = LogDir.entryInfoList();
return list;
}
////This function checks the number of log files on the disk and
////makes shure there are not too many. The number of files can be
////limited by MaxNbLog for the max file count or MaxSize for the maximum
////number of bytes on the disk.
//unsigned int CLogMgr::CleanLogsOnDisk(qint32 MaxNbLogs, qint64 MaxSize)
//{
// int RemovedFiles = 0;
// QStringList LogFilters;
// LogFilters << "*.bin";
// QDir *LogDir = new QDir("./Trains/");
// LogDir->setFilter(QDir::Files | QDir::NoDotAndDotDot);
// LogDir->setNameFilters(LogFilters);
// LogDir->setSorting(QDir::Name);
// QFileInfoList list = LogDir->entryInfoList();
// if(list.size() == 0)
// {
// delete LogDir;
// return RET_OK;
// }
// //First, delete the older files if there are too many.
// if(list.size() > MaxNbLogs)
// {
// for(qint32 i = 0; i < (list.size() - MaxNbLogs); i++)
// {
// if(LogDir->remove(list.at(i).absoluteFilePath()) == false)
// {
// CZTLog::instance()->AddLogString(QString().sprintf("Impossible d'effacer le log %s",list.at(i).absoluteFilePath().toUtf8().data()),true);
// }
// else
// {
// RemovedFiles++;
// }
// }
// //refresh list
// delete LogDir;
// QDir *LogDir = new QDir("./Trains/");
// LogDir->setFilter(QDir::Files | QDir::NoDotAndDotDot);
// LogDir->setNameFilters(LogFilters);
// LogDir->setSorting(QDir::Name);
// list = LogDir->entryInfoList();
// }
// delete LogDir;
// qint64 DirSize = 0;
// for(qint32 i = 0; i < list.size(); i++)
// {
// DirSize += list.at(i).size();
// }
// if(DirSize > MaxSize)
// {
// int i = 0;
// while(DirSize > MaxSize)
// {
// if(LogDir->remove(list.at(i).absoluteFilePath()) == true)
// {
// DirSize -= list.at(i).size();
// RemovedFiles++;
// }
// else
// {
// CZTLog::instance()->AddLogString(QString().sprintf("Impossible d'effacer le log %s",list.at(i).absoluteFilePath().toUtf8().data()),true);
// }
// i++;
// }
// }
// if(RemovedFiles > 0)
// {
// CZTLog::instance()->AddLogString(QString().sprintf("%d fichiers de passage on été effacés",RemovedFiles),true);
// }
// return RET_OK;
//}
//This function loads the raw data from a log element for which
//the data has not yet been loaded. Data will be loaded directly in the
//passed element pointer.
//Returns a pointer to the new log Element
CLogElement* CLogMgr::LoadLogData(CLogElement *Element)
{
if(Element->mZTLogType == ZT1_LOG_TYPE)
{
CZT1LogElement *TargetElement = (CZT1LogElement*)Element;
QString FilePath = TargetElement->mLogFileName;
unsigned int ret;
//Make shure that the lists are empty in the target element
for(int i = 0; i < TargetElement->mZTLogData.size(); i++)
{
delete TargetElement->mZTLogData.at(i);
}
for(int i = 0; i < TargetElement->mZTDetections.size(); i++)
{
delete TargetElement->mZTDetections.at(i);
}
TargetElement->mZTLogData.clear();
TargetElement->mZTDetections.clear();
//Passing the TargetElement to the OpenTrainLog function will fill it with data
CTrainLogFileMgr::instance()->OpenTrainLog(FilePath,ret,TargetElement,true);
return (CLogElement*)TargetElement;
}
else if(Element->mZTLogType == ZT2_LOG_TYPE)
{
CZT2LogElement *TargetElement = (CZT2LogElement*)Element;
QString FilePath = TargetElement->mLogFileName;
unsigned int ret;
//Make shure that the lists are empty in the target element
for(int i = 0; i < TargetElement->mZTLogData.size(); i++)
{
delete TargetElement->mZTLogData.at(i);
}
for(int i = 0; i < TargetElement->mZTDetections.size(); i++)
{
delete TargetElement->mZTDetections.at(i);
}
TargetElement->mZTLogData.clear();
TargetElement->mZTDetections.clear();
//Passing TargetElement to the OpenTrainLog function will fill it with data
CTrainLogFileMgr::instance()->OpenTrainLog(FilePath,ret,TargetElement,true);
return (CLogElement*)TargetElement;
}
return 0;
}
unsigned int CLogMgr::FreeLogData(CLogElement *Element)
{
if(Element->mZTLogType == ZT1_LOG_TYPE)
{
CZT1LogElement *temp = (CZT1LogElement*)Element;
for(int i = 0; i < temp->mZTLogData.size(); i++)
delete temp->mZTLogData.at(i);
temp->mZTLogData.clear();
}
if(Element->mZTLogType == ZT2_LOG_TYPE)
{
CZT2LogElement *temp = (CZT2LogElement*)Element;
for(int i = 0; i < temp->mZTLogData.size(); i++)
delete temp->mZTLogData.at(i);
temp->mZTLogData.clear();
}
return RET_OK;
}
//Resets the logs list and checks for log files.
//Thereafter, ParseNextLog() shall be called periodically for all of files in the list
//returns the number of detected files
unsigned int CLogMgr::InitSteppedLogParsing()
{
DestroyLogList();
mLogsFileIndex = 0;
QStringList LogFilters;
LogFilters << "*.bin";
QDir LogDir("./Trains/");
LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
LogDir.setNameFilters(LogFilters);
LogDir.setSorting(QDir::Name);
mLogsFilelist.clear();
mLogsFilelist = LogDir.entryInfoList();
return mLogsFilelist.size();
}
//returns true if the parsed log is valid.
//otherwise returns false
bool CLogMgr::ParseNextLog()
{
if((int)mLogsFileIndex >= mLogsFilelist.size())
return false;
//Extract data
if(ParseNewLog(mLogsFilelist.at(mLogsFileIndex).filePath()) == RET_ERROR)
return false;
mLogsFileIndex++;
return true;
}
unsigned int CLogMgr::ParseNewLog(QString FileName, bool KeepData,bool CleanupLogs)
{
Q_UNUSED(KeepData)
unsigned int ret;
CLogElement *NewLog = CTrainLogFileMgr::instance()->OpenTrainLog(FileName,ret);
if(ret == RET_ERROR)
{
return RET_ERROR;
}
mPassagesList.append(NewLog);
if(CleanupLogs == true)
{
CleanUpLogs();
}
return RET_OK;
}
//This function makes shure that we keep only a certain cout of standard passage files
//but we keep all the passage files that contains detections.
unsigned int CLogMgr::CleanUpLogs()
{
int NbZT1Logs = 0, NbZT2Logs = 0;
//First, check if we have more logs than supposed...
for(int i = 0; i < mPassagesList.size(); i++)
{
CLogElement *Log = mPassagesList.at(i);
if(Log->mZTLogType == ZT1_LOG_TYPE)
{
CZT1LogElement *ZT1Log = (CZT1LogElement*)Log;
if(ZT1Log->mZTDetections.size() == 0 && ZT1Log->mFlags.mIsProblematicPassage == 0)
{
NbZT1Logs++;
}
}
else
{
CZT2LogElement *ZT2Log = (CZT2LogElement*)Log;
if(ZT2Log->mZTDetections.size() == 0 && ZT2Log->mFlags.mIsProblematicPassage == 0)
{
NbZT2Logs++;
}
}
}
//Now check if we need to delete some logs
bool CleanZT1Logs = false;
if(mKeepZT1Logs == false)
{
CleanZT1Logs = (NbZT1Logs > mMaxFileCount);
}
bool CleanZT2Logs = false;
if(mKeepZT2Logs == false)
{
CleanZT2Logs = (NbZT2Logs > mMaxFileCount);
}
//Logs are sorted in ascending order, we want to delete the older
//logs so start from the top of the list.
int i = 0;
while(CleanZT1Logs == true || CleanZT2Logs == true)
{
CLogElement *Log = mPassagesList.at(i);
if(Log->mZTLogType == ZT1_LOG_TYPE)
{
if(CleanZT1Logs == true)
{
CZT1LogElement *ZT1Log = (CZT1LogElement*)Log;
if(ZT1Log->mZTDetections.size() == 0 &&
!(ZT1Log->mTrainType == TRAIN_TYPE_MPM10 && mKeepMPM10Logs == true) &&
ZT1Log->mFlags.mIsProblematicPassage == 0)
{
//Remove this log.
QDir().remove(ZT1Log->mLogFileName);
delete mPassagesList.at(i);
mPassagesList.removeAt(i);
NbZT1Logs--;
if(NbZT1Logs <= mMaxFileCount)
{
CleanZT1Logs = false;
}
}
else
{
i++;
}
}
else
{
i++;
}
}
else
{
if(CleanZT2Logs == true)
{
CZT2LogElement *ZT2Log = (CZT2LogElement*)Log;
if(ZT2Log->mZTDetections.size() == 0 &&
ZT2Log->mFlags.mIsProblematicPassage == 0)
{
QDir().remove(ZT2Log->mLogFileName);
delete mPassagesList.at(i);
mPassagesList.removeAt(i);
NbZT2Logs--;
if(NbZT2Logs <= mMaxFileCount)
{
CleanZT2Logs = false;
}
}
else
{
i++;
}
}
else
{
i++;
}
}
}
return RET_OK;
}
unsigned int CLogMgr::GetLogsCount()
{
return mPassagesList.size();
}
QList<CLogElement*> * CLogMgr::GetLogsList()
{
return &mPassagesList;
}
int CLogMgr::DeleteErrorLogs(bool ZT1, bool ZT2)
{
int count = 0;
int i=0;
while(i < mPassagesList.size())
{
CLogElement *Log = mPassagesList.at(i);
if(Log->mZTLogType == ZT1_LOG_TYPE)
{
if(ZT1 == true)
{
CZT1LogElement *ZT1Log = (CZT1LogElement*)Log;
if(ZT1Log->mZTDetections.size() != 0 ||
ZT1Log->mFlags.mIsProblematicPassage == 1)
{
QDir().remove(ZT1Log->mLogFileName);
count++;
delete mPassagesList.at(i);
mPassagesList.removeAt(i);
}
else
{
i++;
}
}
}
else
{
if(ZT2 == true)
{
CZT2LogElement *ZT2Log = (CZT2LogElement*)Log;
if(ZT2Log->mZTDetections.size() != 0 ||
ZT2Log->mFlags.mIsProblematicPassage == 1)
{
QDir().remove(ZT2Log->mLogFileName);
count++;
delete mPassagesList.at(i);
mPassagesList.removeAt(i);
}
else
{
i++;
}
}
}
}
CEngLog::instance()->AddLogString(QString().sprintf("%d fichiers d'erreurs effacés",count));
return count;
}
//QDataStream &operator<<(QDataStream &out, const CLogElement &source)
//{
// return out;
//}
//QDataStream &operator>>(QDataStream &in, CLogElement &dest)
//{
// return in;
//}
CLogElement::~CLogElement()
{
}
CZT1LogElement::~CZT1LogElement()
{
// for(int i = 0; i < mZTLogData.size(); i++)
// delete mZTLogData.at(i);
qDeleteAll(mZTLogData);
mZTLogData.clear();
// for(int i = 0; i < mZTDetections.size(); i++)
// delete mZTDetections.at(i);
qDeleteAll(mZTDetections);
mZTDetections.clear();
}
//QDataStream &operator<<(QDataStream &out, const CZT1LogElement &source)
//{
// quint32 NbLogEntry = source.mZTLogData.size();
// quint32 NbDetections = source.mZTDetections.size();
// quint32 LogType = source.mZTLogType;
// out << LogType << NbLogEntry << NbDetections;
// for(unsigned int i = 0; i < NbLogEntry; i++)
// {
// out << *source.mZTLogData.at(i);
// }
// //write detections
// for(unsigned int i =0; i < NbDetections; i++)
// {
// out << *source.mZTDetections.at(i);
// }
// return out;
//}
//QDataStream &operator>>(QDataStream &in, CZT1LogElement &dest)
//{
// return in;
//}
CZT2LogElement::~CZT2LogElement()
{
for(int i = 0; i < mZTLogData.size(); i++)
delete mZTLogData.at(i);
mZTLogData.clear();
for(int i = 0; i < mZTDetections.size(); i++)
delete mZTDetections.at(i);
mZTDetections.clear();
}
//QDataStream &operator<<(QDataStream &out, const CZT2LogElement &source)
//{
// quint32 NbLogEntry = source.mZTLogData.size();
// quint32 NbDetections = source.mZTDetections.size();
// quint32 LogType = source.mZTLogType;
// out << LogType << NbLogEntry << NbDetections;
// for(unsigned int i = 0; i < NbLogEntry; i++)
// {
// out << *source.mZTLogData.at(i);
// }
// //write detections
// for(unsigned int i =0; i < NbDetections; i++)
// {
// out << *source.mZTDetections.at(i);
// }
// return out;
//}
////QDataStream &operator>>(QDataStream &in, CZT2LogElement &dest)
////{
////// quint32 NbLogEntry = source.mZTLogData.size();
////// quint32 NbDetections = source.mZTDetections.size();
////// quint32 LogType = source.mZTLogType;
////// dest >> MagicNbr >> LogType >> NbLogEntry >> NbDetections;
////// for(unsigned int i = 0; i < NbLogEntry; i++)
////// {
////// out << *source.mZTLogData->at(i);
////// }
////// //write detections
////// for(unsigned int i =0; i < NbDetections; i++)
////// {
////// out << *source.mZTDetections->at(i);
////// }
//// return in;
////}