[Positioning] Add class TextFileReader
TextFileReader read lines from a text file. It is aimed to be used by all classes that read from a text file, as TextFileWriter is used by those which write to a text file. Code of TextFileReader is taken from class InputCSV. Minor fixes on the TextFileWriter unit test.
This commit is contained in:
parent
866013248f
commit
58ed434d6b
|
@ -57,6 +57,7 @@ OBJ_LIST = \
|
|||
realposition.o \
|
||||
configuration.o \
|
||||
userinterface.o \
|
||||
textfilereader.o \
|
||||
textfilewriter.o \
|
||||
output.o \
|
||||
outputterminal.o \
|
||||
|
@ -133,10 +134,13 @@ calibrationrequest.o: \
|
|||
$(OBJ_DIR)/request.o \
|
||||
$(OBJ_DIR)/referencepoint.o \
|
||||
$(OBJ_DIR)/direction.o
|
||||
textfilereader.o: \
|
||||
$(OBJ_DIR)/posexcept.o
|
||||
textfilewriter.o: \
|
||||
$(OBJ_DIR)/posexcept.o
|
||||
inputcsv.o: \
|
||||
$(OBJ_DIR)/inputmedium.o \
|
||||
$(OBJ_DIR)/textfilereader.o \
|
||||
$(OBJ_DIR)/request.o \
|
||||
$(OBJ_DIR)/calibrationrequest.o \
|
||||
$(OBJ_DIR)/stock.o
|
||||
|
|
|
@ -25,50 +25,17 @@ using namespace boost ;
|
|||
* @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)
|
||||
InputCSV::InputCSV(const string &filename):
|
||||
file(filename)
|
||||
{
|
||||
input_file_name = filename ;
|
||||
|
||||
input_file.open(input_file_name.c_str()) ;
|
||||
if (! input_file)
|
||||
throw error_opening_input_file(input_file_name) ;
|
||||
|
||||
read_next_line() ;
|
||||
}
|
||||
|
||||
|
||||
InputCSV::~InputCSV()
|
||||
{
|
||||
input_file.close() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** 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.
|
||||
|
@ -76,27 +43,21 @@ bool InputCSV::eof_close()
|
|||
*/
|
||||
void InputCSV::read_next_line()
|
||||
{
|
||||
if (eof_close())
|
||||
{
|
||||
current_line.clear() ;
|
||||
return ;
|
||||
}
|
||||
|
||||
string::size_type first_non_blank = 0 ;
|
||||
|
||||
do
|
||||
{
|
||||
if (! file.read_line(current_line))
|
||||
{
|
||||
current_line.clear() ;
|
||||
return ;
|
||||
}
|
||||
++current_line_nb ;
|
||||
getline(input_file, current_line) ;
|
||||
}
|
||||
while (! input_file.eof() &&
|
||||
(first_non_blank = current_line.find_first_not_of(" \t"))
|
||||
while ((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) ;
|
||||
current_line.erase(0, first_non_blank) ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,7 +78,7 @@ const Request& InputCSV::get_next_request()
|
|||
{
|
||||
clear_current_request() ;
|
||||
|
||||
if (eof_close()) // End of file or error
|
||||
if (current_line.empty()) // End of file or error
|
||||
return *current_request ;
|
||||
|
||||
// Split read string into fields (semicolon-separated)
|
||||
|
@ -159,7 +120,7 @@ const Request& InputCSV::get_next_request()
|
|||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line_nb << ", field « Timestamp », of input file « "
|
||||
<< input_file_name << " »!" << endl ;
|
||||
<< file.get_name() << " »!" << endl ;
|
||||
current_request->clear() ;
|
||||
return *current_request ;
|
||||
}
|
||||
|
@ -187,7 +148,7 @@ const Request& InputCSV::get_next_request()
|
|||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line_nb << ", position field #" << i
|
||||
<< ", of input file « " << input_file_name << " »!"
|
||||
<< ", of input file « " << file.get_name() << " »!"
|
||||
<< endl ;
|
||||
current_request->clear() ;
|
||||
return *current_request ;
|
||||
|
@ -217,7 +178,7 @@ const Request& InputCSV::get_next_request()
|
|||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line_nb << ", field « Direction », of input file « "
|
||||
<< input_file_name << " »!" << endl ;
|
||||
<< file.get_name() << " »!" << endl ;
|
||||
current_request->clear() ;
|
||||
return *current_request ;
|
||||
}
|
||||
|
@ -247,7 +208,7 @@ const Request& InputCSV::get_next_request()
|
|||
<< "InputCSV::get_next_request(): Bad value « "
|
||||
<< *ti << " » at line "
|
||||
<< current_line_nb
|
||||
<< " of input file « " << input_file_name << " »!"
|
||||
<< " of input file « " << file.get_name() << " »!"
|
||||
<< endl ;
|
||||
current_request->clear() ; // Blank current request
|
||||
return *current_request ;
|
||||
|
@ -270,8 +231,6 @@ const Request& InputCSV::get_next_request()
|
|||
|
||||
current_request->set_measurements(measurements) ;
|
||||
|
||||
read_next_line() ;
|
||||
|
||||
if (is_calibration_request)
|
||||
{
|
||||
current_request_to_calibration_request() ;
|
||||
|
@ -284,5 +243,7 @@ const Request& InputCSV::get_next_request()
|
|||
request->set_reference_point(&reference_point) ;
|
||||
}
|
||||
|
||||
read_next_line() ;
|
||||
|
||||
return *current_request ;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define _OWLPS_POSITIONING_INPUTCSV_HH_
|
||||
|
||||
#include "inputmedium.hh"
|
||||
#include "textfilereader.hh"
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
/// Reads \link Request requests \endlink from a CSV file
|
||||
/**
|
||||
|
@ -14,19 +14,16 @@
|
|||
class InputCSV: public InputMedium
|
||||
{
|
||||
protected:
|
||||
std::string input_file_name ;
|
||||
std::ifstream input_file ;
|
||||
TextFileReader file ;
|
||||
/// Current line contents
|
||||
std::string current_line ;
|
||||
|
||||
/// Checks if the file is readable and closes it if not
|
||||
bool eof_close(void) ;
|
||||
void read_next_line(void) ;
|
||||
|
||||
public:
|
||||
InputCSV(const std::string &filename) ;
|
||||
|
||||
~InputCSV(void) ;
|
||||
~InputCSV(void) {}
|
||||
|
||||
/** @name Read accessors */
|
||||
//@{
|
||||
|
@ -51,13 +48,9 @@ public:
|
|||
/* *** Read accessors *** */
|
||||
|
||||
|
||||
/**
|
||||
* @return \em true if the end of file is reached.
|
||||
* @return \em false if there is something more to read.
|
||||
*/
|
||||
inline bool InputCSV::eof() const
|
||||
{
|
||||
return ! input_file && input_file.eof() ;
|
||||
return file.eof() ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,13 +58,9 @@ inline bool InputCSV::eof() const
|
|||
/* *** Operators *** */
|
||||
|
||||
|
||||
/**
|
||||
* @return The bool value of #input_file.
|
||||
* @sa std::ifstream
|
||||
*/
|
||||
inline InputCSV::operator bool() const
|
||||
{
|
||||
return input_file ;
|
||||
return ! eof() ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#include "textfilereader.hh"
|
||||
#include "posexcept.hh"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
|
||||
/* *** Constructors *** */
|
||||
|
||||
|
||||
/**
|
||||
* @param _file_name The name of the file to open.
|
||||
* @throw error_opening_input_file if the file cannot be opened.
|
||||
*/
|
||||
TextFileReader::TextFileReader(const string &_file_name):
|
||||
file_name(_file_name)
|
||||
{
|
||||
file.open(file_name.c_str()) ;
|
||||
if (! file)
|
||||
throw error_opening_input_file(file_name) ;
|
||||
}
|
||||
|
||||
|
||||
TextFileReader::~TextFileReader()
|
||||
{
|
||||
file.close() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
/**
|
||||
* @return The string read, or an empty string in case of error.
|
||||
*/
|
||||
bool TextFileReader::read_line(string &text)
|
||||
{
|
||||
if (eof_close())
|
||||
return false ;
|
||||
|
||||
getline(file, text) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests if #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 TextFileReader::eof_close()
|
||||
{
|
||||
if (file)
|
||||
return false ;
|
||||
|
||||
if (file.eof())
|
||||
{
|
||||
file.close() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef _OWLPS_POSITIONING_TEXTFILEREADER_HH_
|
||||
#define _OWLPS_POSITIONING_TEXTFILEREADER_HH_
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
/// Read text from a file
|
||||
class TextFileReader
|
||||
{
|
||||
private:
|
||||
std::string file_name ;
|
||||
std::ifstream file ;
|
||||
|
||||
/// Checks if the file is readable and closes it if not
|
||||
bool eof_close(void) ;
|
||||
|
||||
public:
|
||||
TextFileReader(const std::string &_file_name) ;
|
||||
virtual ~TextFileReader(void) ;
|
||||
|
||||
/** @name Operations */
|
||||
//@{
|
||||
bool read_line(std::string &text) ;
|
||||
bool eof(void) const ;
|
||||
//@}
|
||||
|
||||
/** @name Accessors */
|
||||
//@{
|
||||
const std::string& get_name(void) const ;
|
||||
//@}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
/**
|
||||
* @return \em true if the end of file is reached.
|
||||
* @return \em false if there is something more to read.
|
||||
*/
|
||||
inline bool TextFileReader::eof() const
|
||||
{
|
||||
return ! file && file.eof() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Accessors *** */
|
||||
|
||||
|
||||
inline const std::string& TextFileReader::get_name() const
|
||||
{
|
||||
return file_name ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // _OWLPS_POSITIONING_TEXTFILEREADER_HH_
|
|
@ -65,6 +65,8 @@ public:
|
|||
// First Request //
|
||||
|
||||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT(request1) ;
|
||||
assert(request1.get_mobile()) ;
|
||||
TS_ASSERT_EQUALS(request1.get_mobile()->get_mac_addr(),
|
||||
TestUtil::mobiles[0].get_mac_addr()) ;
|
||||
TS_ASSERT_EQUALS(request1.get_time_sent(),
|
||||
|
@ -88,6 +90,8 @@ public:
|
|||
// Second Request //
|
||||
|
||||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT(request1) ;
|
||||
assert(request1.get_mobile()) ;
|
||||
TS_ASSERT_EQUALS(request1.get_mobile()->get_mac_addr(),
|
||||
TestUtil::mobiles[1].get_mac_addr()) ;
|
||||
TS_ASSERT_EQUALS(request1.get_time_sent(),
|
||||
|
@ -108,6 +112,8 @@ public:
|
|||
// Third Request //
|
||||
|
||||
TS_ASSERT(inputcsv1) ;
|
||||
TS_ASSERT(request1) ;
|
||||
assert(request1.get_mobile()) ;
|
||||
TS_ASSERT(! inputcsv1.eof()) ;
|
||||
|
||||
request1 = inputcsv1.get_next_request() ;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "inputlogcsv.hh"
|
||||
#include "inputcsv.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "textfilereader.hh"
|
||||
|
||||
class TextFileReader_test: public CxxTest::TestSuite
|
||||
{
|
||||
private:
|
||||
std::string test_file_name ;
|
||||
|
||||
public:
|
||||
|
||||
TextFileReader_test(void)
|
||||
{
|
||||
test_file_name = "/tmp/TextFileReader_test_file.csv" ;
|
||||
}
|
||||
|
||||
|
||||
~TextFileReader_test(void)
|
||||
{
|
||||
TestUtil::remove_file(test_file_name) ;
|
||||
}
|
||||
|
||||
|
||||
static TextFileReader_test* createSuite(void)
|
||||
{
|
||||
return new TextFileReader_test() ;
|
||||
}
|
||||
|
||||
|
||||
static void destroySuite(TextFileReader_test *suite)
|
||||
{
|
||||
delete suite ;
|
||||
}
|
||||
|
||||
|
||||
void test_textfilereader(void)
|
||||
{
|
||||
std::ofstream output_file(test_file_name.c_str()) ;
|
||||
assert(output_file) ;
|
||||
output_file << "Hello\nWorld\n" ;
|
||||
output_file.close() ;
|
||||
|
||||
std::string line ;
|
||||
TextFileReader *textfilereader ;
|
||||
TS_ASSERT_THROWS_NOTHING(
|
||||
textfilereader = new TextFileReader(test_file_name)) ;
|
||||
TS_ASSERT(textfilereader->read_line(line)) ;
|
||||
TS_ASSERT_EQUALS(line, "Hello") ;
|
||||
TS_ASSERT(textfilereader->read_line(line)) ;
|
||||
TS_ASSERT_EQUALS(line, "World") ;
|
||||
|
||||
delete textfilereader ;
|
||||
}
|
||||
|
||||
} ;
|
|
@ -11,7 +11,6 @@ public:
|
|||
|
||||
TextFileWriter_test(void)
|
||||
{
|
||||
Stock::clear() ;
|
||||
test_file_name = "/tmp/TextFileWriter_test_file.csv" ;
|
||||
}
|
||||
|
||||
|
@ -36,8 +35,9 @@ public:
|
|||
|
||||
void test_textfilewriter(void)
|
||||
{
|
||||
TextFileWriter *textfilewriter =
|
||||
new TextFileWriter(test_file_name) ;
|
||||
TextFileWriter *textfilewriter ;
|
||||
TS_ASSERT_THROWS_NOTHING(
|
||||
textfilewriter = new TextFileWriter(test_file_name)) ;
|
||||
TS_ASSERT(textfilewriter->write_text("Hello\nWorld\n")) ;
|
||||
delete textfilewriter ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue