FileLoaderASCII.cpp 5.62 KB
#include "FileLoaderASCII.h"

#include "../TimeManager/TimeManager.h"
#include "../Common/Toolbox.h"

#include <string.h>

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<string,string> FileLoaderASCIIClass::getAttributes(void)
		{
			//no attributes for a ASCII file
			map<string,string> attributes;
			attributes.clear();
			return attributes;
		}
	}
}