CSVDriver
#ifndef CSVDRIVER_H
#define CSVDRIVER_H
// STL
#include <fstream>
#include <string>
#include <FileDriver.h>
/*
TIME,OPEN,LOW,HIGH,CLOSE,VOLUME
N10,N8.5,N8.5,N8.5,N8.5,N6
1105315200,1.3047,1.3047,1.3075,1.307,453
1105329600,1.307,1.3067,1.3089,1.3078,981
1105344000,1.3078,1.3058,1.3098,1.3093,1739
1105358400,1.3094,1.3083,1.3117,1.3105,1972
1105372800,1.3103,1.3071,1.3122,1.3107,2601
1105387200,1.3106,1.3078,1.3108,1.3083,1757
*/
class CSVDriver : public FileDriver
{
public:
CSVDriver();
virtual ~CSVDriver();
virtual bool open(const std::string& filename);
virtual void close(void);
virtual bool next(Bar& dp) throw(DriverException);
virtual bool eof(void);
protected:
private:
enum FIELDS_POS {DATE=0,OPEN,LOW,HIGH,CLOSE,VOLUME};
private:
std::ifstream _infile;
std::string _line;
unsigned _linenum;
};
#endif // CSVDRIVER_H
// STDLIB
#include <sstream>
#include <cstdlib>
// Boost
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/tokenizer.hpp>
#include "CSVDriver.h"
CSVDriver::CSVDriver(void): _linenum(0)
{
//ctor
}
CSVDriver::~CSVDriver()
{
if( _infile.is_open() )
_infile.close();
}
bool CSVDriver::open(const std::string& filename)
{
// Check if another file was open previously
if( _infile.is_open() ) {
_infile.close();
_linenum = 0;
}
_infile.open(filename.c_str());
if( _infile.is_open() == false )
return false;
// First line is header line
getline(_infile, _line);
_linenum = 1;
// Second line is header line
getline(_infile, _line);
_linenum = 2;
return _infile.good();
}
void CSVDriver::close(void)
{
if( _infile.is_open() )
_infile.close();
_infile.clear();
_linenum = 0;
}
bool CSVDriver::next(Bar& dp) throw(DriverException)
{
if( _infile.eof() )
return false;
typedef boost::tokenizer<boost::char_separator<char> > TokensRdr;
getline(_infile, _line);
if(!_line.empty())
{
++_linenum;
dp.close = 0;
dp.volume = 0;
dp.high = 0;
dp.low = 0;
//time_t =represents the number of seconds since the
// start of the Unix epoch: midnight UTC of
// January 1, 1970 (not counting leap seconds)
dp.key = boost::posix_time::from_time_t(std::time(0));//date(); // not_a_date_time
dp.open = 0;
// Get line fields
int i = 0;
TokensRdr tok(_line, boost::char_separator<char>(" ,\t\n\r"));
for( TokensRdr::iterator iter = tok.begin(); iter != tok.end(); ++iter, ++i )
{
std::string field = *iter; // extract line field (.csv file)
switch( i )
{
case DATE://i==0
{
//istringstream stream1;
//string string1 = "25";
//stream1.str(string1);
//int i;
//stream1 >> i;
//cout << i << endl; // displays 25
std::istringstream stream1;
stream1.str(field);
std::time_t tt1;
stream1 >> tt1;
dp.key = boost::posix_time::from_time_t(tt1);//from_uk_string(field);
if( dp.key.is_not_a_date_time() )
{
std::stringstream ss;
ss << "Invalid key at line " << _linenum;
throw DriverException(ss.str());
}
else
{
std::cout << "Date: " << dp.key << " "<< tt1 ;
}
}
break;
case OPEN://i==1
dp.open = atof(field.c_str());
break;
case LOW: //i==2
dp.low = atof(field.c_str());
break;
case HIGH: //i==3
dp.high = atof(field.c_str());
break;
case CLOSE: //i==4
dp.close = atof(field.c_str());
break;
case VOLUME: //i==5
dp.volume = atof(field.c_str());
break;
default:
{
std::stringstream ss;
ss << "Unknown field at line " << _linenum << "->" << i << "->" << field;
throw DriverException(ss.str());
}
} // token type switch
} // for each token in line
//TIME,OPEN,LOW,HIGH,CLOSE,VOLUME
std::cout << " " <<_linenum<< " " << dp.open
<< " " << dp.low
<< " " << dp.high
<< " " << dp.close
<< " " << dp.volume
<<std::endl;
}
return true;
}
bool CSVDriver::eof(void)
{
return _infile.eof();
}