TimePattern.cpp 8.54 KB
#include "TimePattern.h"

#include <cstring>
#include <cstdio>

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

using namespace TREPS::Common;

namespace TREPS
{
	namespace TimeManager
	{
		TimePatternClass::TimePatternClass(void) : app(NULL), pattern("")
		{
			this->app = ApplicationClass::getInstance();
		}

		bool TimePatternClass::init(const char *pattern)
		{
			if (this->pattern.compare(pattern) == 0)
				return true;

			this->partList.clear();
			this->pattern = "";

			string patStr = getTRIMStr(pattern);

			//LOG4CXX_INFO(this->app->getLog()->getPtr(),"Set time pattern : " << patStr);

			while (patStr.compare("") != 0)
			{
				t_TimePatternPart part;

				size_t p = patStr.find("[");

				if (p == string::npos)
				{
					//if cannot find [ char => patStr considerate as a fixed string
					part.type   = TPPT_STRING;
					part.length = patStr.length();
					part.strVal = patStr;
					this->partList.push_back(part);
					patStr = "";
					continue;
				}
				else if (p != 0)
				{
					//if [ not at the first position => content before [ considerate as a fixed string
					string s    = patStr.substr(0,p);
					part.type   = TPPT_STRING;
					part.length = s.length();
					part.strVal = s;
					this->partList.push_back(part);
				}

				patStr  = patStr.substr(p+1,patStr.length()-p-1);

				//the pattern part must be closed by ]
				p = patStr.find("]");

				if (p == string::npos)
				{
					LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Missing ] in time pattern");
					this->partList.clear();
					return false;
				}

				//get pattern part type
				string s = patStr.substr(0,p);
				patStr   = patStr.substr(p+1,patStr.length()-p-1);

				if (s.compare("YYYY") == 0)
				{
					//full year - 4 digits
					part.type   = TPPT_YEAR_4D;
					part.length = 4;
				}
				else if (s.compare("YY") == 0)
				{
					//two last digits of the year
					part.type   = TPPT_YEAR_2D;
					part.length = 2;
				}
				else if (s.compare("MM") == 0)
				{
					//month of the year - 2 digits
					part.type   = TPPT_MONTH;
					part.length = 2;
				}
				else if (s.compare("DD") == 0)
				{
					//day of month - 2 digits
					part.type   = TPPT_DAY;
					part.length = 2;
				}
				else if (s.compare("DOY") == 0)
				{
					//day of year - 3 digits
					part.type   = TPPT_DOY;
					part.length = 3;
				}
				else if (s.compare("hh") == 0)
				{
					//hour - 2 digits
					part.type   = TPPT_HOUR;
					part.length = 2;
				}
				else if (s.compare("mm") == 0)
				{
					//minutes - 2 digits
					part.type   = TPPT_MIN;
					part.length = 2;
				}
				else if (s.compare("ss") == 0)
				{
					//seconds - 2 digits
					part.type   = TPPT_SEC;
					part.length = 2;
				}
				else if (s.compare("mls") == 0)
				{
					//milliseconds - 3 digits
					part.type   = TPPT_MLS;
					part.length = 3;
				}
				else
				{
					//unknown pattern part type
					LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Unknown pattern arg : " << s);
					this->partList.clear();
					return false;
				}

				this->partList.push_back(part);
			}


			this->pattern = pattern;

			return true;
		}

		bool TimePatternClass::load(const char *time, t_Time &t, bool verbose)
		{
			if (this->pattern.compare("") == 0)
			{
				if (verbose)
					LOG4CXX_ERROR(this->app->getLog()->getPtr(),"No time pattern defined");
				return false;
			}

			int crtPos = 0;

			int timeLength = strlen(time);

			//set DOY at the end, to be sure to have year loaded before
			bool addDOY = false;
			long int doy = 0;


			for (t_TimePatternPartList::iterator part = this->partList.begin(); part != this->partList.end(); ++part)
			{
				if (crtPos >= timeLength)
				{
					if (verbose)
						LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Cannot load time : " << time);
					return false;
				}

				const char *p = time;
				p += crtPos;

				switch ((*part).type)
				{
					case TPPT_STRING :
						//nothing to do
						break;
					case TPPT_YEAR_4D :
						//get year in 4 digits
						if (sscanf(p,"%04ld",&t.ye) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract 4-digits year in " << time);
							return false;
						}
						break;
					case TPPT_YEAR_2D :
						//get year in 2 digits
						if (sscanf(p,"%02ld",&t.ye) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract 2-digits year in " << time);
							return false;
						}
						t.ye += 2000;
						break;
					case TPPT_MONTH :
						//get month in 2 digits
						if (sscanf(p,"%02ld",&t.mo) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract month in " << time);
							return false;
						}
						break;
					case TPPT_DAY :
						//get day in 2 digits
						if (sscanf(p,"%02ld",&t.da) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract day in " << p);
							return false;
						}
						break;
					case TPPT_DOY :
					{
						//get day of year in 3 digits
						if ((p[0] > 9) || (p[1] > 9) || (p[2] > 9) || (sscanf(p,"%03ld",&doy) != 1))
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract day of year in " << time);
							return false;
						}
						addDOY = true;
						break;
					}
					case TPPT_HOUR :
						//get hour in 2 digits
						if (sscanf(p,"%02ld",&t.ho) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract hour in " << time);
							return false;
						}
						break;
					case TPPT_MIN :
						//get minutes in 2 digits
						if (sscanf(p,"%02ld",&t.mi) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract minute in " << time);
							return false;
						}
						break;
					case TPPT_SEC :
						//get seconds in 2 digits
						if (sscanf(p,"%02ld",&t.se) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract second in " << time);
							return false;
						}
						break;
					case TPPT_MLS :
						//get milliseconds in 3 digits
						if (sscanf(p,"%03ld",&t.ml) != 1)
						{
							if (verbose)
								LOG4CXX_ERROR(this->app->getLog()->getPtr(),"Error to extract milli second in " << time);
							return false;
						}
						break;
				}

				crtPos += (*part).length;
			}

			if (addDOY)
				setDOY(t,doy);

			return true;
		}

		bool TimePatternClass::write(t_Time &t, string &time)
		{
			time = "";

			if (this->pattern.compare("") == 0)
			{
				LOG4CXX_ERROR(this->app->getLog()->getPtr(),"No time pattern defined");
				return false;
			}

			char tmp[26];

			for (t_TimePatternPartList::iterator part = this->partList.begin(); part != this->partList.end(); ++part)
			{
				switch ((*part).type)
				{
					case TPPT_STRING  :
						//write a string (ie separator)
						time += (*part).strVal;
						break;
					case TPPT_YEAR_4D :
						//write year in 4 digits
						sprintf(tmp,"%04ld",t.ye);
						tmp[4] = '\0';
						time += tmp;
						break;
					case TPPT_YEAR_2D :
					{
						//write year in 2 digits
						long int y = (t.ye%100);
						sprintf(tmp,"%02ld",y);
						tmp[2] = '\0';
						time += tmp;
						break;
					}
					case TPPT_MONTH   :
						//write month in 2 digits
						sprintf(tmp,"%02ld",t.mo);
						tmp[2] = '\0';
						time += tmp;
						break;
					case TPPT_DAY     :
						//write day in 2 digits
						sprintf(tmp,"%02ld",t.da);
						tmp[2] = '\0';
						time += tmp;
						break;
					case TPPT_DOY     :
					{
						//write day of year in 3 digits
						long int doy = getDOY(t);
						sprintf(tmp,"%03ld",doy);
						tmp[3] = '\0';
						time += tmp;
						break;
					}
					case TPPT_HOUR    :
						//write hour in 2 digits
						sprintf(tmp,"%02ld",t.ho);
						tmp[2] = '\0';
						time += tmp;
						break;
					case TPPT_MIN     :
						//write minutes in 2 digits
						sprintf(tmp,"%02ld",t.mi);
						tmp[2] = '\0';
						time += tmp;
						break;
					case TPPT_SEC     :
						//write seconds in 2 digits
						sprintf(tmp,"%02ld",t.se);
						tmp[2] = '\0';
						time += tmp;
						break;
					case TPPT_MLS     :
						//write milliseconds in 3 digits
						sprintf(tmp,"%03ld",t.ml);
						tmp[3] = '\0';
						time += tmp;
						break;
				}
			}

			return true;
		}

		int TimePatternClass::getSize(void)
		{
			//get size of the generated string by a pattern
			if (this->pattern.compare("") == 0)
			{
				LOG4CXX_ERROR(this->app->getLog()->getPtr(),"No time pattern defined");
				return false;
			}

			int size = 0;
			for (t_TimePatternPartList::iterator part = this->partList.begin(); part != this->partList.end(); ++part)
				size += (*part).length;

			return size;
		}
	}
}