diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index 6569dbf..b3f33f2 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -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 diff --git a/owlps-positioning/src/inputcsv.cc b/owlps-positioning/src/inputcsv.cc index d6ac288..e17d5ff 100644 --- a/owlps-positioning/src/inputcsv.cc +++ b/owlps-positioning/src/inputcsv.cc @@ -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 ; } diff --git a/owlps-positioning/src/inputcsv.hh b/owlps-positioning/src/inputcsv.hh index 873b9b1..84d40b9 100644 --- a/owlps-positioning/src/inputcsv.hh +++ b/owlps-positioning/src/inputcsv.hh @@ -2,9 +2,9 @@ #define _OWLPS_POSITIONING_INPUTCSV_HH_ #include "inputmedium.hh" +#include "textfilereader.hh" #include -#include /// 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() ; } diff --git a/owlps-positioning/src/textfilereader.cc b/owlps-positioning/src/textfilereader.cc new file mode 100644 index 0000000..7436324 --- /dev/null +++ b/owlps-positioning/src/textfilereader.cc @@ -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 ; +} diff --git a/owlps-positioning/src/textfilereader.hh b/owlps-positioning/src/textfilereader.hh new file mode 100644 index 0000000..a199f8e --- /dev/null +++ b/owlps-positioning/src/textfilereader.hh @@ -0,0 +1,59 @@ +#ifndef _OWLPS_POSITIONING_TEXTFILEREADER_HH_ +#define _OWLPS_POSITIONING_TEXTFILEREADER_HH_ + +#include +#include + +/// 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_ diff --git a/owlps-positioning/tests/inputcsv_test.hh b/owlps-positioning/tests/inputcsv_test.hh index 0c6025f..cb61a1c 100644 --- a/owlps-positioning/tests/inputcsv_test.hh +++ b/owlps-positioning/tests/inputcsv_test.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() ; diff --git a/owlps-positioning/tests/inputlogcsv_test.hh b/owlps-positioning/tests/inputlogcsv_test.hh index dd6c1cc..e85a361 100644 --- a/owlps-positioning/tests/inputlogcsv_test.hh +++ b/owlps-positioning/tests/inputlogcsv_test.hh @@ -1,6 +1,7 @@ #include #include "inputlogcsv.hh" +#include "inputcsv.hh" #include diff --git a/owlps-positioning/tests/textfilereader_test.hh b/owlps-positioning/tests/textfilereader_test.hh new file mode 100644 index 0000000..f291e8d --- /dev/null +++ b/owlps-positioning/tests/textfilereader_test.hh @@ -0,0 +1,55 @@ +#include + +#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 ; + } + +} ; diff --git a/owlps-positioning/tests/textfilewriter_test.hh b/owlps-positioning/tests/textfilewriter_test.hh index 1a626ae..16f368d 100644 --- a/owlps-positioning/tests/textfilewriter_test.hh +++ b/owlps-positioning/tests/textfilewriter_test.hh @@ -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 ;