[Positioning] InputCSV: handle auto EOF & closing
InputCSV: - Add eof_close() to automatically close the file when EOF is reached. - Add read_next_line(), that read the next non-blank line and skips blank characters. - Add current_line, a string containing the current line data. - Update unit test. InputMedium: - Rename InputMedium::current_line to current_line_nb.
This commit is contained in:
parent
ec10ed71a1
commit
910d9a04d9
|
@ -1,2 +1,4 @@
|
|||
doc
|
||||
csv/*.csv
|
||||
tests/*.cc
|
||||
tests/tests
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
° Différencier une requête normale d'une requête de calibration, en
|
||||
utilisant les champs de direction.
|
||||
° Lire la direction en tant qu'entier plutôt que float ?
|
||||
° Fermer le fichier lorsqu'on a atteint la fin.
|
||||
° Faire en sorte que eof() soit vrai dès qu'on a lu la dernière
|
||||
ligne (skip blanks, etc.).
|
||||
|
||||
- Affichage de debug
|
||||
Garder (generaliser) ? Supprimer ?
|
||||
|
|
|
@ -33,6 +33,8 @@ InputCSV::InputCSV(const string &filename)
|
|||
if (! input_file)
|
||||
throw runtime_error("Error opening input file « " +
|
||||
input_file_name + " »!") ;
|
||||
|
||||
read_next_line() ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +42,59 @@ InputCSV::InputCSV(const string &filename)
|
|||
/* *** Operations *** */
|
||||
|
||||
|
||||
/**
|
||||
* Tests if #input_file is opened and there is something more to
|
||||
* read. If the end of file is reached, the stream is closed.
|
||||
* @return \em true if the end of file is reached or if the file is
|
||||
* already closed.
|
||||
* @return \em false if there is something more to read.
|
||||
*/
|
||||
bool InputCSV::eof_close()
|
||||
{
|
||||
if (! input_file)
|
||||
return false ;
|
||||
|
||||
if (input_file.eof())
|
||||
{
|
||||
input_file.close() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
if (eof_close())
|
||||
{
|
||||
current_line.clear() ;
|
||||
return ;
|
||||
}
|
||||
|
||||
string::size_type first_non_blank = 0 ;
|
||||
|
||||
do
|
||||
{
|
||||
++current_line_nb ;
|
||||
getline(input_file, current_line) ;
|
||||
}
|
||||
while (! input_file.eof() &&
|
||||
(first_non_blank = current_line.find_first_not_of(" \t"))
|
||||
== string::npos) ;
|
||||
|
||||
if (eof_close())
|
||||
current_line.clear() ;
|
||||
else
|
||||
current_line.erase(0, first_non_blank) ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function reads the next Request in the CSV input file. Blank
|
||||
* lines and lines containing only spaces are skipped.
|
||||
|
@ -55,33 +110,16 @@ InputCSV::InputCSV(const string &filename)
|
|||
*/
|
||||
const Request& InputCSV::get_next_request()
|
||||
{
|
||||
if (! input_file)
|
||||
if (eof_close())
|
||||
{
|
||||
current_request.clear() ;
|
||||
return current_request ;
|
||||
}
|
||||
|
||||
string line ;
|
||||
|
||||
// Skipping blank lines
|
||||
do
|
||||
{
|
||||
++current_line ;
|
||||
getline(input_file, line) ;
|
||||
}
|
||||
while (! input_file.eof()
|
||||
&& line.find_first_not_of(" \t") == string::npos) ;
|
||||
|
||||
if (input_file.eof())
|
||||
{
|
||||
// End of file reached: blank current request
|
||||
// End of file or error: blank current request
|
||||
current_request.clear() ;
|
||||
return current_request ;
|
||||
}
|
||||
|
||||
// Split read string into fields (semicolon-separated)
|
||||
tokenizer<escaped_list_separator<char> > tok(
|
||||
line, escaped_list_separator<char>('\\', ';', '\"')) ;
|
||||
current_line, escaped_list_separator<char>('\\', ';', '\"')) ;
|
||||
|
||||
tokenizer<escaped_list_separator<char> >::iterator ti(tok.begin()) ;
|
||||
|
||||
|
@ -121,7 +159,7 @@ const Request& InputCSV::get_next_request()
|
|||
cerr
|
||||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line << ", field « Timestamp », of input file « "
|
||||
<< current_line_nb << ", field « Timestamp », of input file « "
|
||||
<< input_file_name << " »!" << endl ;
|
||||
current_request.clear() ; // Blank current request
|
||||
return current_request ;
|
||||
|
@ -146,7 +184,7 @@ const Request& InputCSV::get_next_request()
|
|||
cerr
|
||||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line << ", position field #" << i
|
||||
<< current_line_nb << ", position field #" << i
|
||||
<< ", of input file « " << input_file_name << " »!"
|
||||
<< endl ;
|
||||
current_request.clear() ; // Blank current request
|
||||
|
@ -178,7 +216,7 @@ const Request& InputCSV::get_next_request()
|
|||
cerr
|
||||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line
|
||||
<< current_line_nb
|
||||
<< " of input file « " << input_file_name << " »!"
|
||||
<< endl ;
|
||||
current_request.clear() ; // Blank current request
|
||||
|
@ -202,5 +240,7 @@ const Request& InputCSV::get_next_request()
|
|||
|
||||
current_request.set_measurements(measurements) ;
|
||||
|
||||
read_next_line() ;
|
||||
|
||||
return current_request ;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,16 @@ protected:
|
|||
std::string input_file_name ;
|
||||
/// Stream corresponding to the input CSV file
|
||||
std::ifstream input_file ;
|
||||
/// Current line contents
|
||||
std::string current_line ;
|
||||
|
||||
/** @name Operations */
|
||||
//@{
|
||||
/// Checks if the file is readable and closes it if not
|
||||
bool eof_close(void) ;
|
||||
/// Reads the next line
|
||||
void read_next_line(void) ;
|
||||
//@}
|
||||
|
||||
public:
|
||||
/// Constructs an InputCSV from a CSV input file name
|
||||
|
@ -49,7 +59,7 @@ public:
|
|||
*/
|
||||
inline bool InputCSV::eof() const
|
||||
{
|
||||
return input_file.eof() ;
|
||||
return ! input_file && input_file.eof() ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ protected:
|
|||
/// The Request just read
|
||||
Request current_request ;
|
||||
/// Number of the current line proceeded
|
||||
unsigned long current_line ;
|
||||
unsigned long current_line_nb ;
|
||||
|
||||
public:
|
||||
/// Default constructor
|
||||
|
@ -28,8 +28,8 @@ public:
|
|||
/// #current_request read accessor
|
||||
const Request& get_current_request(void) const ;
|
||||
|
||||
/// #current_line read accessor
|
||||
unsigned int get_current_line(void) const ;
|
||||
/// #current_line_nb read accessor
|
||||
unsigned int get_current_line_nb(void) const ;
|
||||
|
||||
/// Checks if the last request has been reached
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ public:
|
|||
|
||||
/// Reads the next request
|
||||
/**
|
||||
* Reads a Request, increments current_line, updates #current_request
|
||||
* Reads a Request, increments current_line_nb, updates #current_request
|
||||
* and returns it.
|
||||
* @return The Request read, or an empty Request in case of error or
|
||||
* EOF (note that when casted in bool, an empty Request is false, see
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
inline InputMedium::InputMedium()
|
||||
{
|
||||
current_line = 0 ;
|
||||
current_line_nb = 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,9 +77,9 @@ inline const Request& InputMedium::get_current_request() const
|
|||
}
|
||||
|
||||
|
||||
inline unsigned int InputMedium::get_current_line() const
|
||||
inline unsigned int InputMedium::get_current_line_nb() const
|
||||
{
|
||||
return current_line ;
|
||||
return current_line_nb ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ public:
|
|||
// Filling name and contents of the CSV test file
|
||||
csv_file_name = "/tmp/InputCSV_test_csv_file.csv" ;
|
||||
csv_lines.push_back("\
|
||||
aa:bb:cc:dd:ee:ff;1265120910725;0.00;0.00;0.00;0\
|
||||
\n \n\
|
||||
aa:bb:cc:dd:ee:ff;1265120910725;0.00;0.00;0.00;0\
|
||||
;" + aps[0].get_mac_addr() + ";-58\
|
||||
;" + aps[2].get_mac_addr() + ";-50\
|
||||
;" + aps[1].get_mac_addr() + ";-42\
|
||||
|
@ -46,15 +47,18 @@ aa:bb:cc:dd:ee:77;1265120911234;0.00;0.00;0.00;0\
|
|||
;" + aps[1].get_mac_addr() + ";-70\
|
||||
;" + aps[1].get_mac_addr() + ";-21\
|
||||
;" + aps[0].get_mac_addr() + ";-19\
|
||||
\n \n\
|
||||
\n\t\n\
|
||||
\n \t \n\
|
||||
\n") ;
|
||||
csv_lines.push_back("\
|
||||
aa:bb:cc:dd:ee:ff;1265120912345;0.00;0.00;0.00;0\
|
||||
\taa:bb:cc:dd:ee:ff;1265120912345;0.00;0.00;0.00;0\
|
||||
;" + aps[2].get_mac_addr() + ";-56\
|
||||
;" + aps[1].get_mac_addr() + ";-45\
|
||||
;" + aps[0].get_mac_addr() + ";-54\
|
||||
;" + aps[1].get_mac_addr() + ";-23\
|
||||
;" + aps[0].get_mac_addr() + ";-32\
|
||||
\n") ;
|
||||
\n\n\t\n") ;
|
||||
|
||||
// Opening the file
|
||||
std::ofstream csv_file ;
|
||||
|
@ -192,9 +196,8 @@ aa:bb:cc:dd:ee:ff;1265120912345;0.00;0.00;0.00;0\
|
|||
|
||||
// End of file
|
||||
|
||||
TS_WARN("TODO: eof() should be true even before we try to read another request.") ;
|
||||
TS_ASSERT(inputcsv1) ;
|
||||
TS_ASSERT(! inputcsv1.eof()) ;
|
||||
TS_ASSERT(! inputcsv1) ;
|
||||
TS_ASSERT(inputcsv1.eof()) ;
|
||||
|
||||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT(! request1) ;
|
||||
|
|
Loading…
Reference in New Issue