/* * AsciiReader.cc * * Created on: 5 août 2013 * Author: CS */ #include "Catalog.hh" #include "AsciiData.hh" #include "AsciiReader.hh" #include #include #include #include #include "TimeTableCatalogUtil.hh" #include #include namespace TimeTableCatalog { const std::string AsciiReader::FORMAT = "ASCII"; AsciiReader::AsciiReader(const std::string& pPath) : AbstractReader(pPath) { } AsciiReader::~AsciiReader() { } // ----------------- PUBLIC -------------------------- /** * Checks the TT format to know if the reader is the good one. */ bool AsciiReader::canRead(const std::string& pPath){ std::string tmpPath(pPath); std::transform(tmpPath.begin(), tmpPath.end(), tmpPath.begin(), ::tolower); return boost::algorithm::ends_with(tmpPath, ".txt"); } void AsciiReader::read(TimeTable& ptt) { std::ifstream ttfile(getLocalPath(), std::ios::in); // -- open file if (ttfile) { std::string line; // -- read line int crtIndex = 0; while (getline(ttfile, line)) { boost::algorithm::trim(line); if (boost::starts_with(line, "#")) { // -- it is a metadata readMetadata(line, ptt); } else { // -- add it to TimeTable ptt.addInterval(*readInterval(line, ptt,crtIndex)); ++crtIndex; } } // -- close file ttfile.close(); } else { LOG4CXX_INFO(_logger, "TimeTable file Not Found or unreadable (" + getPath() + ")"); } } std::unique_ptr AsciiReader::createInstance( const std::string& pPath) { return std::unique_ptr < AbstractReader > (new AsciiReader(pPath)); } // ----------------- PRIVATE -------------------------- std::unique_ptr AsciiReader::readInterval( const std::string& pline, TimeTable& pTT, int pcrtIndex) { // -- it is an interval std::vector intervalFields; // intervalFields[0] => startDate // intervalFields[1] => endDate // intervalFields [...] => parameters values split(pline, AsciiData::SEPARATOR.c_str()[0], intervalFields); // set date time format if not set (on first interval) if (pTT._timeFormat == TimeTable::TIME_FORMAT::UNKNOWN) { pTT._timeFormat = getTimeFormat(intervalFields[0]); } // -- create time interval std::unique_ptr ti (new TimeInterval(readISOTime(intervalFields[0]), readISOTime(intervalFields[1]), pcrtIndex)); // If parameters value found, set them for the interval if (intervalFields.size () > 2) { // Starts setting parameter values with the third field of the // intervalFields vector (The first and second one are strat and stop dates) int fieldPos = 2; ParameterDescriptionList pdl = pTT.getParameterDescritptions(); std::vector paremeterValues; for (auto parameterDesc : pdl) { paremeterValues.clear(); for (int paramIdx=0; paramIdx< parameterDesc.getSizeAsInt(); paramIdx++) { paremeterValues.push_back(intervalFields [fieldPos++]); } ti->addParameterData(parameterDesc.getId(), paremeterValues); } } return ti; } void AsciiReader::readMetadata(const std::string& pline, TimeTable& ptimeTable) { // try to find string like "Prop:xxxx" and set _prop attribute to "xxxx" // -- here try to find "Name:" if (contains(pline, AsciiData::NAME_KEYWORD, "#")) { extractvalue(pline, ptimeTable._name); } // -- here try to find "Historic:" else if (contains(pline, AsciiData::HISTORIC_KEYWORD, "#")) { extractvalue(pline, ptimeTable._history); } // -- here try to find "CreationDate:" // and try to set it as unix time // if impossible, add the line to the description else if (contains(pline, AsciiData::CREATION_DATE_KEYWORD, "#")) { // convert creation date string to char* std::string creationDate; extractvalue(pline, creationDate); // try to read date try { ptimeTable._creationDate = TimeTableCatalog::readISOTime(creationDate); } catch (...) { addDescription(pline, ptimeTable); } } // -- every other lines are added to description field*/ // -- here try to find "Parameter NN :" else if (contains(pline, AsciiData::PARAMETER_KEYWORD, "#")) { addParameter(pline, ptimeTable); } // -- here try to find "CreationDate:" // and try to set it as unix time // if impossible, add the line to the description else { addDescription(pline, ptimeTable); } } void AsciiReader::addDescription(const std::string & pline, TimeTable& ptt) { // get value after "#" std::string value = pline.substr(1); // remove ; character at the end of the line boost::algorithm::replace_last(value, ";", ""); ptt._description.push_back(value); } void AsciiReader::addParameter(const std::string & pline, TimeTable& ptt) { // get value after "Parameter NN:" size_t pos = pline.find(": "); if (pos!=std::string::npos) { // Extract parameter informations (after ": ") std::string paramLine = pline.substr(pos+2); // remove ; character at the end of the line boost::algorithm::replace_last(paramLine, ";", ""); ParameterDescription pd; // Split line using coma separator std::stringstream ss(paramLine); std::string paramField; while (std::getline(ss, paramField, ',')) { boost::algorithm::trim(paramField); std::vector fields; boost::split(fields,paramField,boost::is_any_of(":")); // Depending on the fiield [0] value, sets the corresponding parameter attribute if (fields [0] == AsciiData::ATTRIB_ID) { pd.setId(fields [1]); } if (fields [0] == AsciiData::ATTRIB_NAME) { pd.setName(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_SIZE) { pd.setSize(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_TYPE) { pd.setTypeAsString(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_UNIT) { pd.setUnit(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_DESCRITION) { pd.setDescription(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_UCD) { pd.setUcd(fields [1]); } else if (fields [0] == AsciiData::ATTRIB_UTYPE) { pd.setUtype(fields [1]); } } ((Catalog *) &ptt)->addParameterDescription(pd); } } } /* namespace TimeTableCatalog */