/******************************************************************************* * * * 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 * 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; ////}