/******************************************************************************* * * * Société de Transports de Montréal. * * 2012 - 2013 * * * * Projet Zones Tests * * * * * * * *******************************************************************************/ /* Description: Cette classe est responsable de la sauvegarde et de l'ouverture des fichiers log de passage des trains. */ /* ************************************************************************** */ /* Revision: ### YYYMMDD JFM Verision d'origine. ### YYYYMMDD Description du besoin ou du bug Description du changement. */ /* ************************************************************************** */ #include "TrainLogFileMgr.h" #include #include #include "LogMgr.h" CTrainLogFileMgr CTrainLogFileMgr::mSingleton; CTrainLogFileMgr::CTrainLogFileMgr() { } //unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QList *ZT1DetectionsLog,QString StationName) unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QVector *ZT1DetectionsLog,QString StationName) { QFile* BinaryLogFile = new QFile(LogFilePathName); if(BinaryLogFile) { if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false) { qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; return RET_ERROR; } } else return RET_ERROR; QDataStream * OutputStream = new QDataStream(BinaryLogFile); OutputStream->setVersion(QDataStream::Qt_4_8); quint32 MagicNbr = 0xDEADBEEF; quint32 NbLogEntry = 0,NbDetections = 0; quint32 LogType = ZT1_LOG_TYPE; NbLogEntry = ZT1Log->mZT1LogData.size(); NbDetections = ZT1DetectionsLog->size(); quint32 TrainType = 0; quint32 NbElements = 0; quint64 ThreadDataStartTime = 0, ThreadDataEndTime = 0; qreal MeanSpeed = 0; QDateTime DateTime; //Compute some stats int SpeedSampleCount = 0; bool TrainTypeFound = false; unsigned int NbBogie = 0; bool ThreadStartTimeFound = false, ThreadEndTimeFound = false; for(unsigned int i = 0; i < NbLogEntry; i++) { if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData != 0) { //get the train type if(!TrainTypeFound) { if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType != TRAIN_TYPE_UNKNOWN) { TrainType = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType; TrainTypeFound = true; } } //Get the rank count for the train if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mRank > NbBogie) NbBogie = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mBogie; //Find the time limits if(ThreadStartTimeFound == false) { ThreadStartTimeFound = true; ThreadDataStartTime = ZT1Log->mZT1LogData.at(i)->mTimestamp; } //Compute the mean speed if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed != 0) { MeanSpeed += ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed; SpeedSampleCount++; } } else { //Find the time limits if(ThreadStartTimeFound == true && ThreadEndTimeFound == false) { ThreadEndTimeFound = true; ThreadDataEndTime = ZT1Log->mZT1LogData.at(i-1)->mTimestamp; } } } MeanSpeed /= SpeedSampleCount; NbElements = NbBogie/6; DateTime = ZT1Log->mZT1LogData.first()->mDateTime; *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections; *OutputStream << StationName; *OutputStream << ZT1Log->mZT1Flags; *OutputStream << TrainType << NbElements << ThreadDataStartTime << ThreadDataEndTime << MeanSpeed << DateTime; //write detections for(unsigned int i =0; i < NbDetections; i++) { *OutputStream << *ZT1DetectionsLog->at(i); } //write train passage log for(unsigned int i = 0; i < NbLogEntry; i++) { *OutputStream << *ZT1Log->mZT1LogData.at(i); } #ifdef USE_ANALOG_ACQUISITION //write analog data if present. if(ZT1Log->mZT1Flags.mAnalogTracePresent == 1) { for(unsigned int i = 0; i < NbLogEntry; i++) { *OutputStream << ZT1Log->mZT1LogData.at(i)->mAnalogData; } } #endif BinaryLogFile->close(); delete BinaryLogFile; delete OutputStream; return RET_OK; } unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) { QFile* BinaryLogFile = new QFile(LogFilePathName); if(BinaryLogFile) { if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false) { qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; return RET_ERROR; } } else return RET_ERROR; QDataStream * OutputStream = new QDataStream(BinaryLogFile); OutputStream->setVersion(QDataStream::Qt_4_8); quint32 MagicNbr = 0xDEADBEEF; quint32 NbLogEntry,NbDetections; quint32 LogType = ZT2_LOG_TYPE; NbLogEntry = ZT2Log->size(); NbDetections = ZT2DetectionsLog->size(); quint32 NbElements = 0; QDateTime DateTime = ZT2Log->at(0)->mDateTime; //Get some stats for(int j = 0; j < ZT2Log->size(); j++) { if(ZT2Log->at(j)->mZT2ThreadData != 0) { //Get the rank count for the train if(ZT2Log->at(j)->mZT2ThreadData->mRank > NbElements) NbElements = ZT2Log->at(j)->mZT2ThreadData->mBogie; } } NbElements /= 6; //6 bogies per element *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections; *OutputStream << StationName; *OutputStream << NbElements << DateTime; //write detections for(unsigned int i =0; i < NbDetections; i++) { *OutputStream << *ZT2DetectionsLog->at(i); } //write train passage log for(unsigned int i = 0; i < NbLogEntry; i++) { *OutputStream << *ZT2Log->at(i); } BinaryLogFile->close(); delete BinaryLogFile; delete OutputStream; return RET_OK; } //It is the responsibility of the caller to make shure TargetElement is empty CLogElement* CTrainLogFileMgr::OpenTrainLog(QString LogFilePathName,unsigned int &Retvalue,CLogElement* TargetElement,bool LoadData) { // if(!ZT1Log->isEmpty() || !ZT1DetectionsLog->isEmpty()) // return RET_ERROR; int LogFileVersion; bool FileProtected = false; if(QFileInfo(LogFilePathName).suffix() != "bin") { Retvalue = RET_ERROR; return 0; } QFile* BinaryLogFile = new QFile(LogFilePathName); if(BinaryLogFile) { if(BinaryLogFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered) == false) { Retvalue = RET_ERROR; delete BinaryLogFile; return 0; } } else { Retvalue = RET_ERROR; return 0; } QDataStream * InputStream = new QDataStream(BinaryLogFile); InputStream->setVersion(QDataStream::Qt_4_8); quint32 MagicNbr,NbLogEntry,NbDetections,LogType; *InputStream >> MagicNbr; if(MagicNbr == 0xDEADBEEF) { LogFileVersion = 1; FileProtected = false; } else if(MagicNbr == 0xDEADBEEF+1) { LogFileVersion = 2; FileProtected = false; } else if(MagicNbr == 0xDEADBEEF+2) { LogFileVersion = 1; FileProtected = true; } else if(MagicNbr == 0xDEADBEEF+3) { LogFileVersion = 2; FileProtected = true; } else if(MagicNbr == 0xDEADBEEF+15 || MagicNbr == 0xDEADBEEF+16 ) { LogFileVersion = 3; qint32 OutilZTFlags[10]; for(int i = 0; i < 10; i++) { *InputStream >> OutilZTFlags[i]; } if(OutilZTFlags[OUTILZT_FILE_PROTECTED_FLAG] == 1) { FileProtected = true; } else { FileProtected = false; } } else { qDebug(qPrintable(QString().sprintf("Fichier de passage invalide (Magic number) %s",qPrintable(LogFilePathName)))); BinaryLogFile->close(); delete BinaryLogFile; delete InputStream; Retvalue = RET_ERROR; return 0; } *InputStream >> LogType; if(LogType == ZT1_LOG_TYPE) { CZT1LogElement *PassageLog; if(TargetElement == 0) { PassageLog = new CZT1LogElement(); } else { PassageLog = (CZT1LogElement*)TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty } PassageLog->mLogFileName = LogFilePathName; PassageLog->mFileProtected = FileProtected; *InputStream >> NbLogEntry; *InputStream >> NbDetections; *InputStream >> PassageLog->mStationName; if(LogFileVersion == 1) { *InputStream >> PassageLog->mFlags.mExtPGOffset >> PassageLog->mFlags.mIntPGOffset >> PassageLog->mFlags.mPGCalibrationON >> PassageLog->mFlags.mPGTresholdValue >> PassageLog->mFlags.mAnalogTracePresent; PassageLog->mFlags.mTrainCompo1 = 0; PassageLog->mFlags.mTrainCompo2 = 0; PassageLog->mFlags.mTrainCompo3 = 0; PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED; PassageLog->mFlags.mZT1ITI = ZT_PRIMARY_ITI; } else if(LogFileVersion == 2) { *InputStream >> PassageLog->mFlags.mExtPGOffset >> PassageLog->mFlags.mIntPGOffset >> PassageLog->mFlags.mPGCalibrationON >> PassageLog->mFlags.mPGTresholdValue >> PassageLog->mFlags.mAnalogTracePresent >> PassageLog->mFlags.mIsProblematicPassage; PassageLog->mFlags.mTrainCompo1 = 0; PassageLog->mFlags.mTrainCompo2 = 0; PassageLog->mFlags.mTrainCompo3 = 0; PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED; PassageLog->mFlags.mZT1ITI = ZT_PRIMARY_ITI; } else if(LogFileVersion == 3) { *InputStream >> PassageLog->mFlags; } *InputStream >> PassageLog->mTrainType; *InputStream >> PassageLog->mNbElements; *InputStream >> PassageLog->mThreadDataStartTime; *InputStream >> PassageLog->mThreadDataEndTime; *InputStream >> PassageLog->mMeanSpeed; *InputStream >> PassageLog->mPassageDateTime; for(unsigned int i = 0; i < NbDetections; i++) { CZTDetectionData *NewDetection = new CZTDetectionData(); *InputStream >> *NewDetection; PassageLog->mZTDetections.append(NewDetection); } if(LoadData == true) { for(unsigned int i = 0; i < NbLogEntry; i++) { CZT1LogData *NewLogChunk = new CZT1LogData(); *InputStream >> *NewLogChunk; PassageLog->mZTLogData.append(NewLogChunk); } #ifdef USE_ANALOG_ACQUISITION if(PassageLog->mFlags.mAnalogTracePresent == 1) { for(int i = 0; i < PassageLog->mZTLogData.size(); i++) { *InputStream >> PassageLog->mZTLogData.at(i)->mAnalogData; } } #endif } BinaryLogFile->close(); delete BinaryLogFile; delete InputStream; Retvalue = RET_OK; return (CZT1LogElement*) PassageLog; } else if(LogType == ZT2_LOG_TYPE) { quint32 NbElements; QDateTime DateTime; CZT2LogElement *PassageLog; if(TargetElement == 0) { PassageLog = new CZT2LogElement(); } else { PassageLog = (CZT2LogElement*) TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty } *InputStream >> NbLogEntry; *InputStream >> NbDetections; *InputStream >> PassageLog->mStationName; if(LogFileVersion == 2) { *InputStream >> PassageLog->mFlags.mIsProblematicPassage; PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED; PassageLog->mFlags.mTrainCompo1 = 0; PassageLog->mFlags.mTrainCompo2 = 0; PassageLog->mFlags.mTrainCompo3 = 0; } else if(LogFileVersion == 3) { *InputStream >> PassageLog->mFlags; } else { PassageLog->mFlags.mIsProblematicPassage = 2; PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED; PassageLog->mFlags.mTrainCompo1 = 0; PassageLog->mFlags.mTrainCompo2 = 0; PassageLog->mFlags.mTrainCompo3 = 0; } *InputStream >> NbElements; *InputStream >> DateTime; PassageLog->mNbElements = NbElements; PassageLog->mLogFileName = LogFilePathName; PassageLog->mPassageDateTime = DateTime; PassageLog->mFileProtected = FileProtected; for(unsigned int i = 0; i < NbDetections; i++) { CZTDetectionData *NewDetection = new CZTDetectionData(); *InputStream >> *NewDetection; PassageLog->mZTDetections.append(NewDetection); } if(LoadData == true) { for(unsigned int i = 0; i < NbLogEntry; i++) { CZT2LogData *NewLogChunk = new CZT2LogData(); *InputStream >> *NewLogChunk; PassageLog->mZTLogData.append(NewLogChunk); } } BinaryLogFile->close(); delete BinaryLogFile; delete InputStream; Retvalue = RET_OK; return PassageLog; } else { qDebug("Invalid log type in file %s",LogFilePathName.toLatin1().data()); Retvalue = RET_ERROR; return 0; } } unsigned int CTrainLogFileMgr::SetTrainLogProtected(bool IsProtected, QString LogFilePathName) { QFile* BinaryLogFile = new QFile(LogFilePathName); if(BinaryLogFile) { if(BinaryLogFile->open(QIODevice::ReadWrite | QIODevice::Unbuffered) == false) { qDebug("Could not Open log file to set protection : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; return RET_ERROR; } } else return RET_ERROR; QDataStream * Stream = new QDataStream(BinaryLogFile); Stream->setVersion(QDataStream::Qt_4_8); quint32 MagicNbr; *Stream >> MagicNbr; if(IsProtected == true) { if(MagicNbr == 0xDEADBEEF + 2 || MagicNbr == 0xDEADBEEF + 3) { //file is already protected } else if(MagicNbr == 0xDEADBEEF || MagicNbr == 0xDEADBEEF + 1) { MagicNbr += 2; BinaryLogFile->seek(0); *Stream << MagicNbr; } else if(MagicNbr == 0xDEADBEEF + 15) { //Use the reserved registers inside the file... qint32 Flags[10]; for(int i = 0; i < 10; i++) { *Stream >> Flags[i]; } Flags[OUTILZT_FILE_PROTECTED_FLAG] = 1; BinaryLogFile->seek(0); *Stream >> MagicNbr; //Dummy read; for(int i = 0; i < 10; i++) { *Stream << Flags[i]; } } else { //Log File Error BinaryLogFile->close(); qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; } } else { if(MagicNbr == 0xDEADBEEF + 2 || MagicNbr == 0xDEADBEEF + 3) { //file is already protected MagicNbr -= 2; BinaryLogFile->seek(0); *Stream << MagicNbr; } else if(MagicNbr == 0xDEADBEEF || MagicNbr == 0xDEADBEEF + 1) { //file is already unprotected } else if(MagicNbr == 0xDEADBEEF + 15) { //Use the reserved registers inside the file... qint32 Flags[10]; for(int i = 0; i < 10; i++) { *Stream >> Flags[i]; } Flags[OUTILZT_FILE_PROTECTED_FLAG] = 0; BinaryLogFile->seek(0); *Stream >> MagicNbr; //Dummy read; for(int i = 0; i < 10; i++) { *Stream << Flags[i]; } } else { //Log File Error BinaryLogFile->close(); qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; } } BinaryLogFile->close(); qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data()); delete BinaryLogFile; return RET_OK; } //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QList *ZT1DetectionsLog, QString StationName) unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QVector *ZT1DetectionsLog, QString StationName) { return SaveCSVFile(CSVFilePathName, &ZT1Log->mZT1LogData, &ZT1Log->mZT1Flags, ZT1DetectionsLog,StationName); } //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QList *ZT1Log, CZT1FlagsData *ZT1Flags, QList *ZT1DetectionsLog, QString StationName) unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector *ZT1Log, CZT1FlagsData *ZT1Flags, QVector *ZT1DetectionsLog, QString StationName) { QFile CSVFile(CSVFilePathName); if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) return RET_ERROR; QTextStream CSVStream(&CSVFile); CSVStream << "Log de passage du train dans la ZT1\n"; CSVStream << QString::fromUtf8("Station : ") << StationName << "\n"; CSVStream << QString::fromUtf8("Valeur seuil Pneu de guidage : ") << ZT1Flags->mPGTresholdValue << "\n"; CSVStream << QString::fromUtf8("Valeur zérotage PG Extérieur : ") << ZT1Flags->mExtPGOffset << "\n"; CSVStream << QString::fromUtf8("Valeur zérotage PG Intérieur : ") << ZT1Flags->mIntPGOffset << "\n"; if(ZT1Flags->mPGCalibrationON == 1) { CSVStream << "Calibration PG en cours lors du passage: OUI\n"; } else CSVStream << "Calibration PG en cours lors du passage: NON\n"; CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT1DetectionsLog->size() << "\n"; if(ZT1DetectionsLog->size() > 0) { for(int i = 0; i < ZT1DetectionsLog->size(); i++) { CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT1DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT1DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT1DetectionsLog->at(i)->mRank << "\n"; } } CSVStream << "\n"; CSVStream << "Date,Heure,Timestamp,CI,CDV Approche,CDV ZT1,S1,S2,FN,PPI,PPE,PG,Vitesse,Bogie,Rang,Laser Ext,Laser Int,Train"; if(ZT1Flags->mAnalogTracePresent == 1) { CSVStream << ",4-20mA SDF"; } CSVStream << "\n"; for(int i = 0; i < ZT1Log->size(); i++) { CSVStream << ZT1Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ","; CSVStream << ZT1Log->at(i)->mTimestamp << ","; CSVStream << ZT1Log->at(i)->mCIZT1 << ","; CSVStream << ZT1Log->at(i)->mCDVApproach_ZT1 << ","; CSVStream << ZT1Log->at(i)->mCDVARM_ZT1 << ","; if(ZT1Log->at(i)->mZT1ThreadData != 0) { CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS1 << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS2 << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mFN << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPInt << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPExt << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPG << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mTrainSpeed << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mBogie << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mRank << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGExtValue << ","; CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGIntValue << ","; CSVStream << CZTData::GetTrainTypeString(ZT1Log->at(i)->mZT1ThreadData->mTrainType); } else { CSVStream << "0,0,0,0,0,0,0,0,0,0,0,0"; //CSVStream <<"\n"; } if(ZT1Flags->mAnalogTracePresent == 1) { CSVStream << "," << ZT1Log->at(i)->mAnalogData ; } CSVStream << "\n"; } CSVFile.flush(); CSVFile.close(); return RET_OK; } unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) { QFile CSVFile(CSVFilePathName); if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) return RET_ERROR; QTextStream CSVStream(&CSVFile); CSVStream << "Log de passage du train dans la ZT2\n"; CSVStream << QString::fromUtf8("Station : ") << StationName << "\n"; CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT2DetectionsLog->size() << "\n"; if(ZT2DetectionsLog->size() > 0) { for(int i = 0; i < ZT2DetectionsLog->size(); i++) { CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT2DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT2DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT2DetectionsLog->at(i)->mRank << "\n"; } CSVStream << "\n"; } CSVStream << "Date,Heure,Timestamp,CI,CDV ZT2,S1,PPI,PPE,Bogie,Rang\n"; for(int i = 0; i < ZT2Log->size(); i++) { CSVStream << ZT2Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ","; CSVStream << ZT2Log->at(i)->mTimestamp << ","; CSVStream << ZT2Log->at(i)->mCIZT2 << ","; CSVStream << ZT2Log->at(i)->mCDVARM_ZT2 << ","; if(ZT2Log->at(i)->mZT2ThreadData != 0) { CSVStream << ZT2Log->at(i)->mZT2ThreadData->mS1 << ","; CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPInt << ","; CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPExt << ","; CSVStream << ZT2Log->at(i)->mZT2ThreadData->mBogie << ","; CSVStream << ZT2Log->at(i)->mZT2ThreadData->mRank << ","; } else { CSVStream << "0,0,0,0,0"; CSVStream <<"\n"; } } CSVFile.flush(); CSVFile.close(); return RET_OK; } //Cette fonction a été écrite pour des fins de tests et n'est PAS du tout robuste. //utiliser avec précaution. unsigned int CTrainLogFileMgr::SaveBINFromCSV(QString CSVFilePathName) { QFile CSVFile(CSVFilePathName); if(!CSVFile.open(QIODevice::ReadOnly|QIODevice::Text)) return RET_ERROR; QTextStream CSVStream(&CSVFile); bool IsZT1 = true; QString Line; QStringList LineElements; QString StationName; Line.clear(); LineElements.clear(); Line = CSVStream.readLine(); //Log de passage du train dans la ZT1 if(Line.contains("ZT1") == true) { IsZT1 = true; } else if(Line.contains("ZT2") == true) { IsZT1 = false; } else { //invalid file CSVFile.close(); return RET_ERROR; } Line = CSVStream.readLine(); //Station : Snowdon LineElements = Line.split(":"); if(LineElements.isEmpty()) { CSVFile.close(); return RET_ERROR; } StationName = LineElements.at(1); Line.clear(); if(IsZT1 == true) { CZT1Log *ZT1LOG = new CZT1Log(); Line = CSVStream.readLine(); //Valeur seuil Pneu de guidage : 15625 LineElements = Line.split(":"); if(LineElements.isEmpty()) { CSVFile.close(); return RET_ERROR; } ZT1LOG->mZT1Flags.mPGTresholdValue = LineElements.at(1).toInt(); Line.clear(); Line = CSVStream.readLine(); //Valeur zérotage PG Extérieur : 128457 LineElements = Line.split(":"); if(LineElements.isEmpty()) { CSVFile.close(); return RET_ERROR; } ZT1LOG->mZT1Flags.mExtPGOffset = LineElements.at(1).toInt(); Line.clear(); Line = CSVStream.readLine(); //Valeur zérotage PG Intérieur : 1300637 LineElements = Line.split(":"); if(LineElements.isEmpty()) { CSVFile.close(); return RET_ERROR; } ZT1LOG->mZT1Flags.mIntPGOffset = LineElements.at(1).toInt(); Line.clear(); Line = CSVStream.readLine(); //Calibration PG en cours lors du passage: NON if(Line.contains("OUI") == true) { ZT1LOG->mZT1Flags.mPGCalibrationON = true; } else if(Line.contains("NON") == true) { ZT1LOG->mZT1Flags.mPGCalibrationON = false; } else { CSVFile.close(); return RET_ERROR; } Line.clear(); int NbDetections; Line = CSVStream.readLine(); //Nombre de déclenchements : 12 LineElements = Line.split(":"); if(LineElements.isEmpty()) { CSVFile.close(); return RET_ERROR; } NbDetections = LineElements.at(1).toInt(); Line.clear(); //Ignore detections... for(int i = 0; i < NbDetections; i++) { Line = CSVStream.readLine(); Line.clear(); } //Skip the empty line after the detections. Line = CSVStream.readLine(); Line.clear(); //Skip the table header Line = CSVStream.readLine(); Line.clear(); quint32 LastS1 = 0, LastS2 = 0, LastFN = 0; quint32 S1Count = 0; quint32 S2Count = 0; quint32 FNCount = 0; while(CSVStream.atEnd() == false) { Line.clear(); LineElements.clear(); Line = CSVStream.readLine(); //Date Heure Timestamp CI CDV Approche CDV ZT1 S1 S2 FN PPI PPE PG Vitesse Bogie Rang Sonde Ext Sonde Int Train LineElements = Line.split(","); if(LineElements.count() != 18) { CSVFile.close(); return RET_ERROR; } QDate date = QDate::fromString(LineElements.at(0),"yyyy-MM-dd"); if(date.isValid() == false) { CSVFile.close(); return RET_ERROR; } QTime time = QTime::fromString(LineElements.at(1).trimmed(),"hh:mm:ss:zzz"); if(time.isValid() == false) { CSVFile.close(); return RET_ERROR; } qint64 timestamp = LineElements.at(2).toLongLong(); quint32 CIZT1 = LineElements.at(3).toUInt(); quint32 CDVApproach_ZT1 = LineElements.at(4).toUInt(); quint32 CDVARM_ZT1 = LineElements.at(5).toUInt(); CZT1LogData *LogData; CZT1ThreadData *ThreadData; if(LineElements.at(17) == "0") //Check if ThreadData is valid { //Thread data not valid... LogData = new CZT1LogData(); } else { ThreadData = new CZT1ThreadData(); LogData = new CZT1LogData(ThreadData); quint32 S1 = LineElements.at(6).toUInt(); quint32 S2 = LineElements.at(7).toUInt(); quint32 FN = LineElements.at(8).toUInt(); quint32 PInt = LineElements.at(9).toUInt(); quint32 PExt = LineElements.at(10).toUInt(); quint32 PG = LineElements.at(11).toUInt(); qreal TrainSpeed = LineElements.at(12).toFloat(); quint32 Bogie = LineElements.at(13).toUInt(); quint32 Rank = LineElements.at(14).toUInt(); qint32 PGIntValue = LineElements.at(15).toInt(); qint32 PGExtValue = LineElements.at(16).toInt(); quint32 TrainType; if(LineElements.at(17) == "Inconnu") { TrainType = TRAIN_TYPE_UNKNOWN; } else if(LineElements.at(17) == "MR63/73") { TrainType = TRAIN_TYPE_MR63_MR73; } else if(LineElements.at(17) == "MPM10") { TrainType = TRAIN_TYPE_MPM10; } else { CSVFile.close(); return RET_ERROR; } if(S1 == 1 && LastS1 == 0) S1Count++; if(S2 == 1 && LastS2 == 0) S2Count++; if(FN == 1 && LastFN == 0) FNCount++; LastS1 = S1; LastS2 = S2; LastFN = FN; ThreadData->mTimeStamp = timestamp; //nanosecs ThreadData->mDateTime.setDate(date); ThreadData->mDateTime.setTime(time); ThreadData->mS1 = S1; ThreadData->mS2 = S2; ThreadData->mFN = FN; ThreadData->mPInt = PInt; ThreadData->mPExt = PExt; ThreadData->mPG = PG; ThreadData->mTrainSpeed = TrainSpeed; ThreadData->mBogie = Bogie; ThreadData->mRank = Rank; ThreadData->mPGIntValue = PGIntValue; ThreadData->mPGExtValue = PGExtValue; ThreadData->mS1Count = S1Count; ThreadData->mS2Count = S2Count; ThreadData->mFNCount = FNCount; ThreadData->mTrainType = TrainType; } LogData->mTimestamp = timestamp; LogData->mCIZT1 = CIZT1; LogData->mCDVApproach_ZT1 = CDVApproach_ZT1; LogData->mCDVARM_ZT1 = CDVARM_ZT1; LogData->mDateTime.setDate(date); LogData->mDateTime.setTime(time); ZT1LOG->mZT1LogData.append(LogData); } // QList Dummy; //JFM QVector Dummy; Dummy.clear(); SaveTrainLog(CSVFilePathName.replace("csv","bin"),ZT1LOG,&Dummy,StationName); for(int i = 0; i < ZT1LOG->mZT1LogData.size(); i++) { delete ZT1LOG->mZT1LogData.at(i); } ZT1LOG->mZT1LogData.clear(); delete ZT1LOG; } else //ZT1 { } return RET_OK; }