/* * FileReaderASCII.cc * * Created on: Nov 24, 2014 * Author: AKKA */ #include #include #include "FileReaderASCII.hh" #include "TimeUtil.hh" namespace AMDA { namespace LocalFileInterface { // 32 KB is the maximum supported line size int FileReaderASCII::MaxLineSize = 32 * 1024; std::string FileReaderASCII::ClbKey = "CALIB_INFO"; FileReaderASCII::FileReaderASCII() : _asciiStream() { } FileReaderASCII::~FileReaderASCII() { } bool FileReaderASCII::open(std::string filePath) { if (isOpened()) { return true; } // Open ascii stream _asciiStream.open (filePath, std::ios::in); return (_asciiStream.is_open()); } bool FileReaderASCII::close(void) { if (isOpened()) { _asciiStream.close(); } return (_asciiStream.is_open() == false); } bool FileReaderASCII::isOpened(void) { return (_asciiStream.is_open()); } std::string FileReaderASCII::getTimeParamId(void) { LOG4CXX_DEBUG(gLogger, "FileReaderASCII::getTimeParamId"); // Time parameter id is always at the first position in text files return std::string("0"); } /* * @brief Split line */ bool FileReaderASCII::split (const char *line, std::vector &lineFields) { std::string sLine(line); // Remove all spaces in the given string (even multiple spaces between fields) boost::algorithm::trim_all(sLine); if ((sLine.find(" ") != std::string::npos) || (sLine.find("\t") != std::string::npos)) { boost::split(lineFields,sLine,boost::is_any_of(" \t")); return true; } return (false); } bool FileReaderASCII::getParamInfo(std::string& /*paramId*/, LocalParamType& /*paramType*/, int& /*dim1Size*/, int& /*dim2Size*/) { LOG4CXX_DEBUG(gLogger, "FileReaderASCII::getParamInfo"); // Parameter types and size can't be determined by the reader return true; } int FileReaderASCII::getRecordIndex(std::string& /*timeId*/, double time) { LOG4CXX_DEBUG(gLogger, "FileReaderASCII::getRecordIndex"); char line [MaxLineSize]; int lineCount = 0; // Set current stream position at the beginning of the file _asciiStream.seekg (0, _asciiStream.beg); while(_asciiStream.eof() == false) { if (_asciiStream.getline (line, MaxLineSize)) { // Comments in the file are not considered if (line [0] != '#') { std::vector lineFields; if (split (line, lineFields)) { if (!lineFields.empty()) if (getTime(lineFields[0]) >= time) return (lineCount); } lineCount++; } } else if (_asciiStream.rdstate() == std::ios_base::failbit) { LOG4CXX_ERROR(gLogger, "FileReaderASCII::getRecordIndex - Error reading line content, maxSize is " << MaxLineSize); return -1; } } LOG4CXX_ERROR(gLogger, "FileReaderASCII::FileReaderASCII - Cannot get record index"); return -1; } FileReaderStatus FileReaderASCII::getParamPacketData(std::string& /*timeId*/, std::string& paramId, int recordIndex, double stopTime, LocalParamDataPacket *packet) { LOG4CXX_DEBUG(gLogger, "FileReaderASCII::getParamPacketData - " << recordIndex); char line [MaxLineSize]; int lineCount = 0; int colStart = std::stoi(paramId); int colStop = colStart + packet->getDimsSize(); bool packetFull; double crtTime; float *dataFloat = NULL; double *dataDouble = NULL; short *dataShort = NULL; int *dataInt = NULL; void *data; if ((packet->getType() != TYPE_FLOAT) && (packet->getType() != TYPE_DOUBLE) && (packet->getType() != TYPE_SHORT) && (packet->getType() != TYPE_INT) ) { LOG4CXX_ERROR(gLogger, "FileReaderASCII::getParamPacketData - Not supported packet type"); return FRS_ERROR; } if (packet->getType() == TYPE_FLOAT) { dataFloat = new float [packet->getDimsSize()]; data = dataFloat; } else if (packet->getType() == TYPE_DOUBLE) { dataDouble = new double [packet->getDimsSize()]; data = dataDouble; } else if (packet->getType() == TYPE_SHORT) { dataShort = new short [packet->getDimsSize()]; data = dataShort; } else if (packet->getType() == TYPE_INT) { dataInt = new int [packet->getDimsSize()]; data = dataInt; } // Set current stream position at the beginning of the file _asciiStream.seekg (0, _asciiStream.beg); while (_asciiStream.getline (line, MaxLineSize)) { // Comments in the file are not considered if (line [0] == '#') continue; lineCount++; // recordIndex reached ? if (lineCount <= recordIndex) continue; //split line std::vector lineFields; if (split (line, lineFields) && !lineFields.empty()) { crtTime = getTime(lineFields[0]); // stopTime overtaken ? if (crtTime > stopTime) { if (dataFloat != NULL) delete [] dataFloat; if (dataDouble != NULL) delete [] dataDouble; if (dataShort != NULL) delete [] dataShort; if (dataInt != NULL) delete [] dataInt; return FRS_FINISH; } // Extract values on the line depending on their type for (int col=colStart; colgetType() == TYPE_FLOAT) dataFloat [col-colStart] = std::stof (lineFields[col]); else if (packet->getType() == TYPE_DOUBLE) dataDouble [col-colStart] = std::stod (lineFields[col]); else if (packet->getType() == TYPE_SHORT) dataShort [col-colStart] = (short) std::stof (lineFields[col]); else if (packet->getType() == TYPE_INT) dataInt [col-colStart] = std::stoi (lineFields[col]); } else { LOG4CXX_ERROR(gLogger, "FileReaderASCII::getParamPacketData - Error retrieving column " << col); if (dataFloat != NULL) delete [] dataFloat; if (dataDouble != NULL) delete [] dataDouble; if (dataShort != NULL) delete [] dataShort; if (dataInt != NULL) delete [] dataInt; return FRS_ERROR; } } //add data record in the packet if (!packet->addData(crtTime, data, packetFull)) { if (dataFloat != NULL) delete [] dataFloat; if (dataDouble != NULL) delete [] dataDouble; if (dataShort != NULL) delete [] dataShort; if (dataInt != NULL) delete [] dataInt; if (packetFull) return FRS_MORE; LOG4CXX_ERROR(gLogger, "FileReaderASCII::getParamPacketData - Error to add data in packet"); return FRS_ERROR; } } else { LOG4CXX_ERROR(gLogger, "FileReaderASCII::getParamPacketData - Error retrieving time on line " << lineCount); if (dataFloat != NULL) delete [] dataFloat; if (dataDouble != NULL) delete [] dataDouble; if (dataShort != NULL) delete [] dataShort; if (dataInt != NULL) delete [] dataInt; return FRS_ERROR; } } if (dataFloat != NULL) delete [] dataFloat; if (dataDouble != NULL) delete [] dataDouble; if (dataShort != NULL) delete [] dataShort; if (dataInt != NULL) delete [] dataInt; return FRS_EOF; } /* * @brief Get an information */ bool FileReaderASCII::getInfo(const char* pInfoName, std::vector& res) { res.clear(); // Set current stream position at the beginning of the file _asciiStream.seekg (0, _asciiStream.beg); char line [MaxLineSize]; while (_asciiStream.getline (line, MaxLineSize)) { std::string lineStr = std::string(line); boost::algorithm::trim_all(lineStr); if (lineStr[0] != '#') continue; lineStr = lineStr.substr(1,lineStr.size()-1); boost::algorithm::trim_all(lineStr); if (!boost::starts_with(lineStr, FileReaderASCII::ClbKey)) continue; lineStr = lineStr.substr(FileReaderASCII::ClbKey.size(),lineStr.size()-FileReaderASCII::ClbKey.size()); std::vector lineValues; boost::split(lineValues,lineStr,boost::is_any_of(",")); if (lineValues.empty()) continue; for (auto &value : lineValues) boost::algorithm::trim_all(value); if (lineValues[0].compare(pInfoName) != 0) continue; for (int i = 1; i < (int)lineValues.size(); ++i) res.push_back(std::stof(lineValues[i])); return true; } return false; } double FileReaderASCII::getTime(std::string& timeString) { switch (_timeFormat) { case LocalTimeFormat::DOUBLE : return std::stod(timeString); case LocalTimeFormat::ISO : return TimeUtil::readTimeInIso((char*)timeString.c_str()); default: LOG4CXX_WARN(gLogger, "FileReaderASCII::getTime - Time format not implemented"); return 0.; } } } /* LocalFileInterface */ } /* AMDA */