[Positioning] Add class CSVFileReader
CSVFileReader is a specialisation of TextFileReader, that allow reading a CSV line field by field. TextFileReader: - Make private attributes protected to allow derivation. - Add attribute current_line_nb. - Add function read_nonblank_line(). - Delete useless accessor get_name(). Update InputCSV to use CSVFileReader. Adapt unit tests for InputCSV and InputLogCSV: EOF is not reached right after reading the last line, but after trying (and failing) to read one more line.
This commit is contained in:
parent
c82b95f8f0
commit
8e6883cfc9
|
@ -58,6 +58,7 @@ OBJ_LIST = \
|
||||||
configuration.o \
|
configuration.o \
|
||||||
userinterface.o \
|
userinterface.o \
|
||||||
textfilereader.o \
|
textfilereader.o \
|
||||||
|
csvfilereader.o \
|
||||||
textfilewriter.o \
|
textfilewriter.o \
|
||||||
output.o \
|
output.o \
|
||||||
outputterminal.o \
|
outputterminal.o \
|
||||||
|
@ -136,11 +137,13 @@ $(OBJ_DIR)/calibrationrequest.o: \
|
||||||
$(OBJ_DIR)/direction.o
|
$(OBJ_DIR)/direction.o
|
||||||
$(OBJ_DIR)/textfilereader.o: \
|
$(OBJ_DIR)/textfilereader.o: \
|
||||||
$(OBJ_DIR)/posexcept.o
|
$(OBJ_DIR)/posexcept.o
|
||||||
|
$(OBJ_DIR)/csvfilereader.o: \
|
||||||
|
$(OBJ_DIR)/textfilereader.o
|
||||||
$(OBJ_DIR)/textfilewriter.o: \
|
$(OBJ_DIR)/textfilewriter.o: \
|
||||||
$(OBJ_DIR)/posexcept.o
|
$(OBJ_DIR)/posexcept.o
|
||||||
$(OBJ_DIR)/inputcsv.o: \
|
$(OBJ_DIR)/inputcsv.o: \
|
||||||
$(OBJ_DIR)/inputmedium.o \
|
$(OBJ_DIR)/inputmedium.o \
|
||||||
$(OBJ_DIR)/textfilereader.o \
|
$(OBJ_DIR)/csvfilereader.o \
|
||||||
$(OBJ_DIR)/request.o \
|
$(OBJ_DIR)/request.o \
|
||||||
$(OBJ_DIR)/calibrationrequest.o \
|
$(OBJ_DIR)/calibrationrequest.o \
|
||||||
$(OBJ_DIR)/stock.o
|
$(OBJ_DIR)/stock.o
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "csvfilereader.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
using namespace boost ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Constructors *** */
|
||||||
|
|
||||||
|
|
||||||
|
CSVFileReader::~CSVFileReader()
|
||||||
|
{
|
||||||
|
delete current_token ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that this function is not called by the constructor, so you
|
||||||
|
* must manually call it prior to use read_field().
|
||||||
|
* @return false in case of error (EOF, etc.).
|
||||||
|
*/
|
||||||
|
bool CSVFileReader::next_line()
|
||||||
|
{
|
||||||
|
if (current_token != NULL)
|
||||||
|
{
|
||||||
|
delete current_token ;
|
||||||
|
current_token = NULL ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! read_nonblank_line(current_line))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Split read string into fields (semicolon-separated)
|
||||||
|
current_token = new tokenizer<escaped_list_separator<char> >(
|
||||||
|
current_line, escaped_list_separator<char>('\\', separator, '\"')) ;
|
||||||
|
|
||||||
|
token_iterator = current_token->begin() ;
|
||||||
|
current_field_nb = 0 ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVFileReader::print_error_cast()
|
||||||
|
{
|
||||||
|
cerr
|
||||||
|
<< "Bad value « "
|
||||||
|
<< *token_iterator << " » at line "
|
||||||
|
<< current_line_nb << ", field #"
|
||||||
|
<< current_field_nb << ", of input file « "
|
||||||
|
<< file_name << " »!" << endl ;
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
||||||
|
#define _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
||||||
|
|
||||||
|
#include "textfilereader.hh"
|
||||||
|
|
||||||
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/// Reads a CSV file, line by line, field by field
|
||||||
|
class CSVFileReader: public TextFileReader
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const char separator ;
|
||||||
|
|
||||||
|
std::string current_line ;
|
||||||
|
boost::tokenizer<boost::escaped_list_separator<char> > *current_token ;
|
||||||
|
boost::tokenizer<boost::escaped_list_separator<char> >::const_iterator
|
||||||
|
token_iterator ;
|
||||||
|
unsigned int current_field_nb ;
|
||||||
|
|
||||||
|
void print_error_cast(void) ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CSVFileReader(const std::string &filename,
|
||||||
|
const char _separator = ';'):
|
||||||
|
TextFileReader(filename), separator(_separator),
|
||||||
|
current_token(NULL) {}
|
||||||
|
|
||||||
|
virtual ~CSVFileReader(void) ;
|
||||||
|
|
||||||
|
/** @name Operations */
|
||||||
|
//@{
|
||||||
|
/// Load the first next non-blank line
|
||||||
|
bool next_line(void) ;
|
||||||
|
/// Read the next field of the current line
|
||||||
|
template<class T> bool read_field(T &field) ;
|
||||||
|
//@}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline bool CSVFileReader::read_field(T &field)
|
||||||
|
{
|
||||||
|
if (token_iterator == current_token->end())
|
||||||
|
return false ;
|
||||||
|
++current_field_nb ;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
field = boost::lexical_cast<T>(*token_iterator) ;
|
||||||
|
}
|
||||||
|
catch (boost::bad_lexical_cast &e)
|
||||||
|
{
|
||||||
|
print_error_cast() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
++token_iterator ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
|
@ -10,57 +10,11 @@
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
using std::tr1::unordered_map ;
|
using std::tr1::unordered_map ;
|
||||||
|
|
||||||
#include <boost/tokenizer.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
using namespace boost ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Constructors *** */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepares the InputCSV to read a CSV file.
|
|
||||||
* @param filename The name of the file to open.
|
|
||||||
* @throw error_opening_input_file if the file cannot be opened.
|
|
||||||
*/
|
|
||||||
InputCSV::InputCSV(const string &filename):
|
|
||||||
file(filename)
|
|
||||||
{
|
|
||||||
read_next_line() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Operations *** */
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the next non-blank line. Tabs and spaces at the begining of a
|
|
||||||
* line are skipped.
|
|
||||||
* #current_line is set to empty string in case of error.
|
|
||||||
*/
|
|
||||||
void InputCSV::read_next_line()
|
|
||||||
{
|
|
||||||
string::size_type first_non_blank = 0 ;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (! file.read_line(current_line))
|
|
||||||
{
|
|
||||||
current_line.clear() ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
++current_line_nb ;
|
|
||||||
}
|
|
||||||
while ((first_non_blank = current_line.find_first_not_of(" \t"))
|
|
||||||
== string::npos) ;
|
|
||||||
|
|
||||||
current_line.erase(0, first_non_blank) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function reads the next Request in the CSV input file. Blank
|
* This function reads the next Request in the CSV input file. Blank
|
||||||
* lines and lines containing only spaces are skipped.
|
* lines and lines containing only spaces are skipped.
|
||||||
|
@ -78,132 +32,70 @@ const Request& InputCSV::get_next_request()
|
||||||
{
|
{
|
||||||
clear_current_request() ;
|
clear_current_request() ;
|
||||||
|
|
||||||
if (current_line.empty()) // End of file or error
|
if (! file.next_line()) // End of file or error
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
|
++current_line_nb ;
|
||||||
// Split read string into fields (semicolon-separated)
|
|
||||||
tokenizer<escaped_list_separator<char> > tok(
|
|
||||||
current_line, escaped_list_separator<char>('\\', ';', '\"')) ;
|
|
||||||
|
|
||||||
tokenizer<escaped_list_separator<char> >::const_iterator ti(tok.begin()) ;
|
|
||||||
|
|
||||||
// Read Mobile MAC field
|
// Read Mobile MAC field
|
||||||
if (ti == tok.end()) // Wrong number of fields
|
string mac_mobile ;
|
||||||
|
if (! file.read_field(mac_mobile)) // Wrong number of fields
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
const Mobile &mobile = Stock::find_create_mobile(*ti) ;
|
const Mobile &mobile = Stock::find_create_mobile(mac_mobile) ;
|
||||||
current_request->set_mobile(&mobile) ;
|
current_request->set_mobile(&mobile) ;
|
||||||
|
|
||||||
// Read Timestamp field
|
// Read Timestamp field
|
||||||
if (++ti == tok.end())
|
uint64_t timestamp_ms ;
|
||||||
|
if (! file.read_field(timestamp_ms))
|
||||||
{
|
{
|
||||||
// Wrong number of fields: blank current request
|
// Wrong number of fields: blank current request
|
||||||
current_request->clear() ;
|
current_request->clear() ;
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
}
|
}
|
||||||
try
|
current_request->set_time_sent(Timestamp(timestamp_ms)) ;
|
||||||
{
|
|
||||||
current_request->set_time_sent(Timestamp
|
|
||||||
(lexical_cast<uint64_t>(*ti))) ;
|
|
||||||
}
|
|
||||||
catch (bad_lexical_cast &e)
|
|
||||||
{
|
|
||||||
cerr
|
|
||||||
<< "InputCSV::get_next_request(): Bad value « "
|
|
||||||
<< *ti << " » at line "
|
|
||||||
<< current_line_nb << ", field « Timestamp », of input file « "
|
|
||||||
<< file.get_name() << " »!" << endl ;
|
|
||||||
current_request->clear() ;
|
|
||||||
return *current_request ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read position fields
|
// Read position fields
|
||||||
bool is_calibration_request = false ;
|
bool is_calibration_request = false ;
|
||||||
float pos[3] ;
|
float pos[3] ;
|
||||||
for (int i = 0 ; i < 3 ; ++i)
|
for (int i = 0 ; i < 3 ; ++i)
|
||||||
{
|
{
|
||||||
if (++ti == tok.end())
|
if (! file.read_field(pos[i]))
|
||||||
{
|
{
|
||||||
// Wrong number of fields: blank current request
|
// Wrong number of fields: blank current request
|
||||||
current_request->clear() ;
|
current_request->clear() ;
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
}
|
}
|
||||||
try
|
if (pos[i] != 0)
|
||||||
{
|
is_calibration_request = true ;
|
||||||
pos[i] = lexical_cast<float>(*ti) ;
|
|
||||||
if (pos[i] != 0)
|
|
||||||
is_calibration_request = true ;
|
|
||||||
}
|
|
||||||
catch (bad_lexical_cast &e)
|
|
||||||
{
|
|
||||||
cerr
|
|
||||||
<< "InputCSV::get_next_request(): Bad value « "
|
|
||||||
<< *ti << " » at line "
|
|
||||||
<< current_line_nb << ", position field #" << i
|
|
||||||
<< ", of input file « " << file.get_name() << " »!"
|
|
||||||
<< endl ;
|
|
||||||
current_request->clear() ;
|
|
||||||
return *current_request ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read direction field
|
// Read direction field
|
||||||
Direction direction ;
|
Direction direction ;
|
||||||
if (++ti == tok.end())
|
int direction_int ;
|
||||||
|
if (! file.read_field(direction_int))
|
||||||
{
|
{
|
||||||
// Wrong number of fields: blank current request
|
// Wrong number of fields: blank current request
|
||||||
current_request->clear() ;
|
current_request->clear() ;
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
}
|
}
|
||||||
try
|
if (direction_int != 0)
|
||||||
{
|
{
|
||||||
int d = lexical_cast<int>(*ti) ;
|
is_calibration_request = true ;
|
||||||
if (d != 0)
|
direction = direction_int ;
|
||||||
{
|
|
||||||
is_calibration_request = true ;
|
|
||||||
direction = d ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (bad_lexical_cast &e)
|
|
||||||
{
|
|
||||||
cerr
|
|
||||||
<< "InputCSV::get_next_request(): Bad value « "
|
|
||||||
<< *ti << " » at line "
|
|
||||||
<< current_line_nb << ", field « Direction », of input file « "
|
|
||||||
<< file.get_name() << " »!" << endl ;
|
|
||||||
current_request->clear() ;
|
|
||||||
return *current_request ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading {MAC_AP;SS} couples
|
// Reading {MAC_AP;SS} couples
|
||||||
unordered_map<string, Measurement> measurements ;
|
unordered_map<string, Measurement> measurements ;
|
||||||
|
|
||||||
for (++ti ; ti != tok.end() ; ++ti)
|
string mac_ap ;
|
||||||
|
while (file.read_field(mac_ap))
|
||||||
{
|
{
|
||||||
string mac_ap(*ti) ;
|
int ss ;
|
||||||
|
if (! file.read_field(ss))
|
||||||
if (++ti == tok.end())
|
|
||||||
{
|
{
|
||||||
// Wrong number of fields: blank current request
|
// Wrong number of fields: blank current request
|
||||||
current_request->clear() ;
|
current_request->clear() ;
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ss ;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ss = lexical_cast<int>(*ti) ;
|
|
||||||
}
|
|
||||||
catch (bad_lexical_cast &e)
|
|
||||||
{
|
|
||||||
cerr
|
|
||||||
<< "InputCSV::get_next_request(): Bad value « "
|
|
||||||
<< *ti << " » at line "
|
|
||||||
<< current_line_nb
|
|
||||||
<< " of input file « " << file.get_name() << " »!"
|
|
||||||
<< endl ;
|
|
||||||
current_request->clear() ; // Blank current request
|
|
||||||
return *current_request ;
|
|
||||||
}
|
|
||||||
const AccessPoint &ap = Stock::find_create_ap(mac_ap) ;
|
const AccessPoint &ap = Stock::find_create_ap(mac_ap) ;
|
||||||
measurements[mac_ap].set_ap(&ap) ;
|
measurements[mac_ap].set_ap(&ap) ;
|
||||||
measurements[mac_ap].add_ss(ss) ;
|
measurements[mac_ap].add_ss(ss) ;
|
||||||
|
@ -223,7 +115,5 @@ const Request& InputCSV::get_next_request()
|
||||||
request->set_reference_point(&reference_point) ;
|
request->set_reference_point(&reference_point) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_next_line() ;
|
|
||||||
|
|
||||||
return *current_request ;
|
return *current_request ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define _OWLPS_POSITIONING_INPUTCSV_HH_
|
#define _OWLPS_POSITIONING_INPUTCSV_HH_
|
||||||
|
|
||||||
#include "inputmedium.hh"
|
#include "inputmedium.hh"
|
||||||
#include "textfilereader.hh"
|
#include "csvfilereader.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -14,14 +14,11 @@
|
||||||
class InputCSV: public InputMedium
|
class InputCSV: public InputMedium
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
TextFileReader file ;
|
CSVFileReader file ;
|
||||||
/// Current line contents
|
|
||||||
std::string current_line ;
|
|
||||||
|
|
||||||
void read_next_line(void) ;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputCSV(const std::string &filename) ;
|
InputCSV(const std::string &filename):
|
||||||
|
file(filename) {}
|
||||||
|
|
||||||
~InputCSV(void) {}
|
~InputCSV(void) {}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ using namespace std ;
|
||||||
* @throw error_opening_input_file if the file cannot be opened.
|
* @throw error_opening_input_file if the file cannot be opened.
|
||||||
*/
|
*/
|
||||||
TextFileReader::TextFileReader(const string &_file_name):
|
TextFileReader::TextFileReader(const string &_file_name):
|
||||||
file_name(_file_name)
|
file_name(_file_name), current_line_nb(0)
|
||||||
{
|
{
|
||||||
file.open(file_name.c_str()) ;
|
file.open(file_name.c_str()) ;
|
||||||
if (! file)
|
if (! file)
|
||||||
|
@ -31,6 +31,30 @@ TextFileReader::~TextFileReader()
|
||||||
/* *** Operations *** */
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabs and spaces at the begining of a
|
||||||
|
* line are deleted.
|
||||||
|
* \em text is unchanged in case of error.
|
||||||
|
* @return false in case of error, true else.
|
||||||
|
*/
|
||||||
|
bool TextFileReader::read_nonblank_line(string &text)
|
||||||
|
{
|
||||||
|
string line ;
|
||||||
|
string::size_type first_non_blank = 0 ;
|
||||||
|
|
||||||
|
do
|
||||||
|
if (! read_line(line))
|
||||||
|
return false ;
|
||||||
|
while ((first_non_blank = line.find_first_not_of(" \t"))
|
||||||
|
== string::npos) ;
|
||||||
|
|
||||||
|
line.erase(0, first_non_blank) ;
|
||||||
|
text = line ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The string read, or an empty string in case of error.
|
* @return The string read, or an empty string in case of error.
|
||||||
*/
|
*/
|
||||||
|
@ -40,6 +64,7 @@ bool TextFileReader::read_line(string &text)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
getline(file, text) ;
|
getline(file, text) ;
|
||||||
|
++current_line_nb ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
/// Read text from a file
|
/// Read text from a file, line by line
|
||||||
class TextFileReader
|
class TextFileReader
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
std::string file_name ;
|
std::string file_name ;
|
||||||
std::ifstream file ;
|
std::ifstream file ;
|
||||||
|
unsigned int current_line_nb ;
|
||||||
|
|
||||||
/// Checks if the file is readable and closes it if not
|
/// Checks if the file is readable and closes it if not
|
||||||
bool eof_close(void) ;
|
bool eof_close(void) ;
|
||||||
|
@ -20,14 +21,12 @@ public:
|
||||||
|
|
||||||
/** @name Operations */
|
/** @name Operations */
|
||||||
//@{
|
//@{
|
||||||
|
/// Read the next non-blank line
|
||||||
|
bool read_nonblank_line(std::string &text) ;
|
||||||
|
/// Read the next line
|
||||||
bool read_line(std::string &text) ;
|
bool read_line(std::string &text) ;
|
||||||
bool eof(void) const ;
|
bool eof(void) const ;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Accessors */
|
|
||||||
//@{
|
|
||||||
const std::string& get_name(void) const ;
|
|
||||||
//@}
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,14 +45,4 @@ inline bool TextFileReader::eof() const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Accessors *** */
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& TextFileReader::get_name() const
|
|
||||||
{
|
|
||||||
return file_name ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _OWLPS_POSITIONING_TEXTFILEREADER_HH_
|
#endif // _OWLPS_POSITIONING_TEXTFILEREADER_HH_
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
#include <cxxtest/TestSuite.h>
|
||||||
|
|
||||||
|
#include "csvfilereader.hh"
|
||||||
|
|
||||||
|
class CSVFileReader_test: public CxxTest::TestSuite
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string test_file_name ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CSVFileReader_test(void)
|
||||||
|
{
|
||||||
|
test_file_name = "/tmp/CSVFileReader_test_file.csv" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~CSVFileReader_test(void)
|
||||||
|
{
|
||||||
|
TestUtil::remove_file(test_file_name) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CSVFileReader_test* createSuite(void)
|
||||||
|
{
|
||||||
|
return new CSVFileReader_test() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void destroySuite(CSVFileReader_test *suite)
|
||||||
|
{
|
||||||
|
delete suite ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_csvfilereader(void)
|
||||||
|
{
|
||||||
|
const unsigned int nlines = 6 ;
|
||||||
|
|
||||||
|
std::ofstream output_file(test_file_name.c_str()) ;
|
||||||
|
assert(output_file) ;
|
||||||
|
for (unsigned int i = 0 ; i < nlines ; ++i)
|
||||||
|
output_file << " \n c,string,42,3.1416\n \n" ;
|
||||||
|
output_file.close() ;
|
||||||
|
|
||||||
|
CSVFileReader *csvfilereader ;
|
||||||
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
|
csvfilereader = new CSVFileReader(test_file_name, ',')) ;
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < nlines ; ++i)
|
||||||
|
{
|
||||||
|
TS_ASSERT(csvfilereader->next_line()) ;
|
||||||
|
|
||||||
|
char c ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(c)) ;
|
||||||
|
TS_ASSERT_EQUALS(c, 'c') ;
|
||||||
|
|
||||||
|
std::string s ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(s)) ;
|
||||||
|
TS_ASSERT_EQUALS(s, "string") ;
|
||||||
|
|
||||||
|
uint64_t i ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(i)) ;
|
||||||
|
TS_ASSERT_EQUALS(i, 42u) ;
|
||||||
|
|
||||||
|
double f ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(f)) ;
|
||||||
|
TS_ASSERT_EQUALS(f, 3.1416) ;
|
||||||
|
|
||||||
|
TS_ASSERT(! csvfilereader->read_field(f)) ;
|
||||||
|
TS_ASSERT(! csvfilereader->eof()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
TS_ASSERT(! csvfilereader->next_line()) ;
|
||||||
|
TS_ASSERT(csvfilereader->eof()) ;
|
||||||
|
|
||||||
|
delete csvfilereader ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_request(void)
|
||||||
|
{
|
||||||
|
const unsigned int nlines = 10 ;
|
||||||
|
|
||||||
|
std::ofstream output_file(test_file_name.c_str()) ;
|
||||||
|
assert(output_file) ;
|
||||||
|
for (unsigned int i = 0 ; i < nlines ; ++i)
|
||||||
|
output_file << "aa:bb:cc:dd:ee:ff;1265120910725;0;0;0;0;11:22:33:44:55:01;-58;11:22:33:44:55:03;-50;11:22:33:44:55:02;-42;11:22:33:44:55:01;-55;11:22:33:44:55:02;-37\n" ;
|
||||||
|
output_file.close() ;
|
||||||
|
|
||||||
|
CSVFileReader *csvfilereader ;
|
||||||
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
|
csvfilereader = new CSVFileReader(test_file_name)) ;
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < nlines ; ++i)
|
||||||
|
{
|
||||||
|
TS_ASSERT(csvfilereader->next_line()) ;
|
||||||
|
|
||||||
|
std::string mac ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "aa:bb:cc:dd:ee:ff") ;
|
||||||
|
|
||||||
|
uint64_t timestamp ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(timestamp)) ;
|
||||||
|
TS_ASSERT_EQUALS(timestamp, 1265120910725ull) ;
|
||||||
|
|
||||||
|
float position ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(position)) ;
|
||||||
|
TS_ASSERT_EQUALS(position, 0) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(position)) ;
|
||||||
|
TS_ASSERT_EQUALS(position, 0) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(position)) ;
|
||||||
|
TS_ASSERT_EQUALS(position, 0) ;
|
||||||
|
|
||||||
|
int direction ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(direction)) ;
|
||||||
|
TS_ASSERT_EQUALS(direction, 0) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "11:22:33:44:55:01") ;
|
||||||
|
|
||||||
|
int ss ;
|
||||||
|
TS_ASSERT(csvfilereader->read_field(ss)) ;
|
||||||
|
TS_ASSERT_EQUALS(ss, -58) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "11:22:33:44:55:03") ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(ss)) ;
|
||||||
|
TS_ASSERT_EQUALS(ss, -50) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "11:22:33:44:55:02") ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(ss)) ;
|
||||||
|
TS_ASSERT_EQUALS(ss, -42) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "11:22:33:44:55:01") ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(ss)) ;
|
||||||
|
TS_ASSERT_EQUALS(ss, -55) ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT_EQUALS(mac, "11:22:33:44:55:02") ;
|
||||||
|
|
||||||
|
TS_ASSERT(csvfilereader->read_field(ss)) ;
|
||||||
|
TS_ASSERT_EQUALS(ss, -37) ;
|
||||||
|
|
||||||
|
TS_ASSERT(! csvfilereader->read_field(mac)) ;
|
||||||
|
TS_ASSERT(! csvfilereader->eof()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
TS_ASSERT(! csvfilereader->next_line()) ;
|
||||||
|
TS_ASSERT(csvfilereader->eof()) ;
|
||||||
|
|
||||||
|
delete csvfilereader ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} ;
|
|
@ -136,12 +136,11 @@ public:
|
||||||
|
|
||||||
// End of file
|
// End of file
|
||||||
|
|
||||||
TS_ASSERT(! inputcsv1) ;
|
TS_ASSERT(inputcsv1) ;
|
||||||
TS_ASSERT(inputcsv1.eof()) ;
|
TS_ASSERT(! inputcsv1.eof()) ;
|
||||||
|
|
||||||
request1 = inputcsv1.get_next_request() ;
|
request1 = inputcsv1.get_next_request() ;
|
||||||
TS_ASSERT(! request1) ;
|
TS_ASSERT(! request1) ;
|
||||||
|
|
||||||
TS_ASSERT(! inputcsv1) ;
|
TS_ASSERT(! inputcsv1) ;
|
||||||
TS_ASSERT(inputcsv1.eof()) ;
|
TS_ASSERT(inputcsv1.eof()) ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,12 @@ public:
|
||||||
TS_ASSERT(TestUtil::request_equals(**i, request_log)) ;
|
TS_ASSERT(TestUtil::request_equals(**i, request_log)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TS_ASSERT(! inputcsv_csv.eof()) ;
|
||||||
|
TS_ASSERT(! inputcsv_log.eof()) ;
|
||||||
|
|
||||||
|
TS_ASSERT(! inputcsv_csv.get_next_request()) ;
|
||||||
|
TS_ASSERT(! inputcsv_log.get_next_request()) ;
|
||||||
|
|
||||||
TS_ASSERT(inputcsv_csv.eof()) ;
|
TS_ASSERT(inputcsv_csv.eof()) ;
|
||||||
TS_ASSERT(inputcsv_log.eof()) ;
|
TS_ASSERT(inputcsv_log.eof()) ;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue