#include "FileLoaderASCII.h" #include "../TimeManager/TimeManager.h" #include "../Common/Toolbox.h" #include using namespace TREPS::Common; using namespace TREPS::TimeManager; namespace TREPS { namespace File { FileLoaderASCIIClass::FileLoaderASCIIClass(void):FileLoaderAbstractClass() , crtLine(NULL), headerChar('#') { this->crtLine = new string; this->frameTags = this->app->getConf()->getFramesTags(); this->headerChar = this->app->getConf()->getASCIIHeaderChar(); } FileLoaderASCIIClass::~FileLoaderASCIIClass(void) { delete this->crtLine; } bool FileLoaderASCIIClass::open(const char *file_path) { if (this->isOpened()) { LOG4CXX_ERROR(this->app->getLog()->getPtr(),"A file is already opened! Cannot open " << file_path); return false; } this->file.open(file_path); return this->isOpened(); } bool FileLoaderASCIIClass::close(void) { if (this->isOpened()) this->file.close(); return !this->isOpened(); } bool FileLoaderASCIIClass::isOpened(void) { return this->file.is_open(); } t_FileFormat FileLoaderASCIIClass::getFormat(void) { return FF_ASCII; } t_FieldList FileLoaderASCIIClass::getFields(long int nbRecords) { t_FieldList fields; fields.clear(); this->resetLine(); if (!this->getNextDataLine()) return fields; stringstream ss(*(this->crtLine)); string entry; t_Field crtField; int index = 0; while (ss >> entry) { //create new fields crtField.id = intToStr(index); crtField.name = "Field_"; crtField.name += crtField.id; crtField.attributes.clear(); crtField.dims.clear(); crtField.nbRecords = nbRecords; crtField.ucd = ""; crtField.unit = ""; this->getType(entry.c_str(), crtField.type, crtField.timeformat, crtField.timepattern); fields.push_back(crtField); ++index; } return fields; } long int FileLoaderASCIIClass::getNbRecords(void) { this->resetLine(); long int total = 0; while (this->getNextDataLine()) total++; return total; } void FileLoaderASCIIClass::getType(const char *value, t_FieldType &type, t_TimeFormat &timeformat, string &timepattern) { type = FT_DOUBLE; timeformat = TF_NONE; timepattern = ""; //get time manager instance TimeManagerClass *timeMgr = TimeManagerClass::getInstance(); string pattern = timeMgr->detectPattern(value); if (pattern.compare("") != 0) { //a time pattern has been detected timeformat = TF_PATTERN; timepattern = pattern; type = FT_TIME; } else { //no time pattern, try to detect a double double v; int nbLoad; if (sscanf(value,"%20lf%n",&v,&nbLoad) != 2) { if (nbLoad != (int)strlen(value)) type = FT_UNKNOWN; } } } void FileLoaderASCIIClass::addSpecificFormatVectors(const t_FieldList *fields, t_VectorList &vectors) { if ((fields->size() < 3) || (fields->size() > 4)) return; int nbFieldsNoTime = 0; for (t_FieldList::const_iterator it=fields->begin(); it != fields->end(); ++it) if ((*it).type != FT_TIME) ++nbFieldsNoTime; if (nbFieldsNoTime != 3) return; //3 fields detected => create a vector with the 3 components t_Vector vec; vec.id = "v_0"; vec.ispos = false; nbFieldsNoTime = 0; for (t_FieldList::const_iterator it=fields->begin(); it != fields->end(); ++it) if ((*it).type != FT_TIME) { vec.nbRecords = (*it).nbRecords; vec.fieldId[nbFieldsNoTime] = (*it).id; ++nbFieldsNoTime; } vectors.push_back(vec); } t_StringList FileLoaderASCIIClass::getFrames(const t_FieldList *fields) { t_StringList frames; frames.clear(); if (!this->isOpened()) return frames; if (this->frameTags.empty()) return frames; this->resetLine(); string s; while(!this->file.eof()) { getline(this->file,s); s = getTRIMStr(s.c_str()); //test only header lines if ((s.compare("") == 0) || (s[0] != this->headerChar)) continue; //remove header char and new trim s = s.substr(1,s.length()-1); s = getTRIMStr(s.c_str()); //Frame detection this->frameMgr->addDetectedFramesFromStringInList(s.c_str(), frames); } return frames; } bool FileLoaderASCIIClass::getNextDataLine(void) { this->crtLine->assign(""); if (!this->isOpened()) return false; bool eof; string s; while(!(eof = this->file.eof())) { getline(this->file,s); s = getTRIMStr(s.c_str()); //skip comment line if ((s.compare("") != 0) && (s[0] != this->headerChar)) break; } if (!eof) this->crtLine->assign(s); return !eof; } void FileLoaderASCIIClass::resetLine(void) { this->file.clear(); this->file.seekg(ios::beg); } bool FileLoaderASCIIClass::getData(int start, int limit, DataRecordListClass *data, int &total) { data->clear(); this->resetLine(); bool getall = ((start == 0) && (limit == 0)); total = 0; while (this->getNextDataLine()) { if (!getall && (total < start)) { total++; continue; } if (getall || (total < start + limit)) { stringstream ss(*this->crtLine); string entry; DataRecordClass *newRec = data->addNew(); int crtId = 0; while (ss >> entry) { newRec->setValue(intToStr(crtId).c_str(), entry.c_str()); ++crtId; } } total++; } return true; } map FileLoaderASCIIClass::getAttributes(void) { //no attributes for a ASCII file map attributes; attributes.clear(); return attributes; } } }