/* * 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), timeSize(0) { } 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 if (line.empty()) { continue; } 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) { // set date time format if not set (on first interval) if (pTT._timeFormat == TimeTable::TIME_FORMAT::UNKNOWN) { pTT._timeFormat = getTimeFormat(pline, this->timeSize); if (pTT._timeFormat == TimeTable::TIME_FORMAT::UNKNOWN) { std::unique_ptr ti (new TimeInterval(0, 0, pcrtIndex)); } } std::string line = pline; boost::algorithm::trim(line); // read start time double startTime = readISOTime(line, pTT._timeFormat); line.erase(0, this->timeSize); boost::algorithm::trim(line); // read stop time double stopTime = readISOTime(line, pTT._timeFormat); line.erase(0, this->timeSize); boost::algorithm::trim(line); // -- create time interval std::unique_ptr ti (new TimeInterval(startTime, stopTime, pcrtIndex)); std::vector params; split(line, AsciiData::SEPARATOR.c_str()[0], params); // If parameters value found, set them for the interval if (!params.empty()) { // Starts setting parameter values with the third field of the // intervalFields vector (The first and second one are strat and stop dates) ParameterDescriptionList pdl = pTT.getParameterDescritptions(); std::vector paremeterValues; int paramPos = 0; for (auto parameterDesc : pdl) { paremeterValues.clear(); for (int paramIdx=0; paramIdx< parameterDesc.getSizeAsInt(); paramIdx++) { if (paramPos < (int)params.size()) { paremeterValues.push_back(params[paramPos]); ++paramPos; } } 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(":")); std::string value = ""; if (fields.size() > 1) { std::vector values(fields.begin()+1, fields.end()); value = boost::algorithm::join(values, ":"); } // Depending on the fiield [0] value, sets the corresponding parameter attribute if (fields [0] == AsciiData::ATTRIB_ID) { pd.setId(value); } if (fields [0] == AsciiData::ATTRIB_NAME) { pd.setName(value); } else if (fields [0] == AsciiData::ATTRIB_SIZE) { pd.setSize(value); } else if (fields [0] == AsciiData::ATTRIB_TYPE) { pd.setType(getTypeFromString(value)); } else if (fields [0] == AsciiData::ATTRIB_UNIT) { pd.setUnit(value); } else if (fields [0] == AsciiData::ATTRIB_DESCRITION) { pd.setDescription(value); } else if (fields [0] == AsciiData::ATTRIB_UCD) { pd.setUcd(value); } else if (fields [0] == AsciiData::ATTRIB_UTYPE) { pd.setUtype(value); } } ((Catalog *) &ptt)->addParameterDescription(pd); } } ParameterDescription::ParameterType AsciiReader::getTypeFromString(std::string type) { boost::algorithm::trim(type); boost::algorithm::to_lower(type); if ((type.compare("string") == 0) || (type.compare("char") == 0)) { return ParameterDescription::ParameterType::String; } else if ((type.compare("integer") == 0) || (type.compare("int") == 0)) { return ParameterDescription::ParameterType::Integer; } else if ((type.compare("float") == 0) || (type.compare("double") == 0)) { return ParameterDescription::ParameterType::Double; } else if (type.compare("date") == 0) { return ParameterDescription::ParameterType::Date; } return ParameterDescription::ParameterType::String; } } /* namespace TimeTableCatalog */