From f55672ef015f935fac8d0fb5d5718993a3034c9d Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 16 May 2013 16:59:15 -0400 Subject: [PATCH] [Positioner] Add class CSVStringReader Code separated from CSVFileReader, which now inherits from both TextFileReader and CSVStringReader. --- owlps-positioner/Makefile | 5 + owlps-positioner/src/csvfilereader.cc | 92 +------------ owlps-positioner/src/csvfilereader.hh | 51 +------ owlps-positioner/src/csvstringreader.cc | 169 ++++++++++++++++++++++++ owlps-positioner/src/csvstringreader.hh | 118 +++++++++++++++++ 5 files changed, 296 insertions(+), 139 deletions(-) create mode 100644 owlps-positioner/src/csvstringreader.cc create mode 100644 owlps-positioner/src/csvstringreader.hh diff --git a/owlps-positioner/Makefile b/owlps-positioner/Makefile index 01f34a2..8dd4642 100644 --- a/owlps-positioner/Makefile +++ b/owlps-positioner/Makefile @@ -63,6 +63,7 @@ OBJ_LIST = \ topologyreadercsv.o \ textfilereader.o \ csvfilereader.o \ + csvstringreader.o \ textfilewriter.o \ output.o \ outputterminal.o \ @@ -200,7 +201,11 @@ $(OBJ_DIR)/resultlist.o: \ $(OBJ_DIR)/textfilereader.o: \ $(OBJ_DIR)/posexcept.o $(OBJ_DIR)/csvfilereader.o: \ + $(OBJ_DIR)/csvstringreader.o \ $(OBJ_DIR)/textfilereader.o +$(OBJ_DIR)/csvstringreader.o: \ + $(OBJ_DIR)/point3d.o \ + $(OBJ_DIR)/timestamp.o $(OBJ_DIR)/textfilewriter.o: \ $(OBJ_DIR)/posexcept.o $(OBJ_DIR)/inputmedium.o: \ diff --git a/owlps-positioner/src/csvfilereader.cc b/owlps-positioner/src/csvfilereader.cc index b29a0e7..7aea5e0 100644 --- a/owlps-positioner/src/csvfilereader.cc +++ b/owlps-positioner/src/csvfilereader.cc @@ -49,16 +49,6 @@ using namespace boost ; -/* *** Constructors *** */ - - -CSVFileReader::~CSVFileReader() -{ - delete current_token ; -} - - - /* *** Operations *** */ @@ -69,91 +59,11 @@ CSVFileReader::~CSVFileReader() */ bool CSVFileReader::next_line() { - 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 >( - current_line, escaped_list_separator('\\', separator, '\"')) ; + set_str(current_line) ; - token_iterator = current_token->begin() ; - current_field_nb = 0 ; - - return true ; -} - - -bool CSVFileReader::read_timestamp(Timestamp &t) -{ - string timestamp_str ; - uint_fast32_t time_s, time_ns ; - - if (! read_field(timestamp_str)) - return false ; - - tokenizer > tok( - timestamp_str, escaped_list_separator('\\', '.', '\"')) ; - tokenizer >::const_iterator tok_iter = - tok.begin() ; - - if (tok_iter == tok.end()) - return false ; - try - { - time_s = lexical_cast(*tok_iter) ; - } - catch (bad_lexical_cast &e) - { - print_error_cast() ; - return false ; - } - ++tok_iter ; - - if (tok_iter == tok.end()) - return false ; - try - { - time_ns = lexical_cast(*tok_iter) ; - } - catch (bad_lexical_cast &e) - { - print_error_cast() ; - return false ; - } - - t = Timestamp(time_s, time_ns) ; - - return true ; -} - - -bool CSVFileReader::read_point3d(Point3D &p) -{ - float coord[3] ; - - for (unsigned int i = 0 ; i < 3 ; ++i) - { - if (token_iterator == current_token->end()) - return false ; - ++current_field_nb ; - - try - { - coord[i] = lexical_cast(*token_iterator) ; - } - catch (bad_lexical_cast &e) - { - print_error_cast() ; - return false ; - } - - ++token_iterator ; - } - - p.set_coordinates(coord) ; return true ; } diff --git a/owlps-positioner/src/csvfilereader.hh b/owlps-positioner/src/csvfilereader.hh index 442ea79..73f3927 100644 --- a/owlps-positioner/src/csvfilereader.hh +++ b/owlps-positioner/src/csvfilereader.hh @@ -42,75 +42,30 @@ #ifndef _OWLPS_POSITIONING_CSVFILEREADER_HH_ #define _OWLPS_POSITIONING_CSVFILEREADER_HH_ -class Point3D ; - #include "textfilereader.hh" -#include "timestamp.hh" - -#include -#include +#include "csvstringreader.hh" /// Reads a CSV file, line by line, field by field -class CSVFileReader: public TextFileReader +class CSVFileReader: public TextFileReader, public CSVStringReader { protected: - const char separator ; - std::string current_line ; - boost::tokenizer > *current_token ; - boost::tokenizer >::const_iterator - token_iterator ; - unsigned int current_field_nb ; void print_error_cast(void) const ; public: CSVFileReader(const std::string &filename, const char _separator = ';'): - TextFileReader(filename), separator(_separator), - current_token(NULL), current_field_nb(0) {} + TextFileReader(filename), CSVStringReader(_separator) {} - virtual ~CSVFileReader(void) ; /** @name Operations */ //@{ /// Loads the first next non-blank line bool next_line(void) ; - /// Reads the next field of the current line - template bool read_field(T &field) ; - /// Reads the next field that should be a Timestamp - bool read_timestamp(Timestamp &t) ; - /// Reads the next 3 fields that should form a Point3D - bool read_point3d(Point3D &p) ; //@} } ; -/* *** Operations *** */ - - -template -inline bool CSVFileReader::read_field(T &field) -{ - if (token_iterator == current_token->end()) - return false ; - ++current_field_nb ; - - try - { - field = boost::lexical_cast(*token_iterator) ; - } - catch (boost::bad_lexical_cast &e) - { - print_error_cast() ; - return false ; - } - - ++token_iterator ; - return true ; -} - - - #endif // _OWLPS_POSITIONING_CSVFILEREADER_HH_ diff --git a/owlps-positioner/src/csvstringreader.cc b/owlps-positioner/src/csvstringreader.cc new file mode 100644 index 0000000..b4377ae --- /dev/null +++ b/owlps-positioner/src/csvstringreader.cc @@ -0,0 +1,169 @@ +/* + * This file is part of the Owl Positioning System (OwlPS). + * OwlPS is a project of the University of Franche-Comte + * (Université de Franche-Comté), France. + * + * Copyright © Université de Franche-Comté 2007-2012. + * + * Corresponding author: Matteo Cypriani + * + *********************************************************************** + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL: + * http://www.cecill.info + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided + * only with a limited warranty and the software's authors, the holder + * of the economic rights, and the successive licensors have only + * limited liability. + * + * In this respect, the user's attention is drawn to the risks + * associated with loading, using, modifying and/or developing or + * reproducing the software by the user in light of its specific status + * of free software, that may mean that it is complicated to manipulate, + * and that also therefore means that it is reserved for developers and + * experienced professionals having in-depth computer knowledge. Users + * are therefore encouraged to load and test the software's suitability + * as regards their requirements in conditions enabling the security of + * their systems and/or data to be ensured and, more generally, to use + * and operate it in the same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + *********************************************************************** + */ + + +#include "csvstringreader.hh" +#include "point3d.hh" + +#include + +using namespace std ; +using namespace boost ; + + + +/* *** Constructors *** */ + + +CSVStringReader::~CSVStringReader() +{ + delete current_token ; +} + + + +/* *** Accessors *** */ + + +/** + * Note that this function is not called by the constructor, so you + * must manually call it to set a string to process prior to use + * read_field(). + * @return \em false in case of error (EOF, etc.), \em true else. + */ +void CSVStringReader::set_str(const string &_str) +{ + str = _str ; + + delete current_token ; + current_token = NULL ; + + // Split read string into fields (semicolon-separated) + current_token = new tokenizer >( + str, escaped_list_separator('\\', separator, '\"')) ; + + token_iterator = current_token->begin() ; + current_field_nb = 0 ; +} + + + +/* *** Operations *** */ + + +bool CSVStringReader::read_timestamp(Timestamp &t) +{ + string timestamp_str ; + uint_fast32_t time_s, time_ns ; + + if (! read_field(timestamp_str)) + return false ; + + tokenizer > tok( + timestamp_str, escaped_list_separator('\\', '.', '\"')) ; + tokenizer >::const_iterator tok_iter = + tok.begin() ; + + if (tok_iter == tok.end()) + return false ; + try + { + time_s = lexical_cast(*tok_iter) ; + } + catch (bad_lexical_cast &e) + { + print_error_cast() ; + return false ; + } + ++tok_iter ; + + if (tok_iter == tok.end()) + return false ; + try + { + time_ns = lexical_cast(*tok_iter) ; + } + catch (bad_lexical_cast &e) + { + print_error_cast() ; + return false ; + } + + t = Timestamp(time_s, time_ns) ; + + return true ; +} + + +bool CSVStringReader::read_point3d(Point3D &p) +{ + float coord[3] ; + + for (unsigned int i = 0 ; i < 3 ; ++i) + { + if (token_iterator == current_token->end()) + return false ; + ++current_field_nb ; + + try + { + coord[i] = lexical_cast(*token_iterator) ; + } + catch (bad_lexical_cast &e) + { + print_error_cast() ; + return false ; + } + + ++token_iterator ; + } + + p.set_coordinates(coord) ; + return true ; +} + + +void CSVStringReader::print_error_cast() const +{ + cerr + << "Bad value \"" << *token_iterator + << "\" at field #" << current_field_nb + << ", of CSV string \"" << str << "\"!" << endl ; +} diff --git a/owlps-positioner/src/csvstringreader.hh b/owlps-positioner/src/csvstringreader.hh new file mode 100644 index 0000000..ab35f3f --- /dev/null +++ b/owlps-positioner/src/csvstringreader.hh @@ -0,0 +1,118 @@ +/* + * This file is part of the Owl Positioning System (OwlPS). + * OwlPS is a project of the University of Franche-Comte + * (Université de Franche-Comté), France. + * + * Copyright © Université de Franche-Comté 2007-2012. + * + * Corresponding author: Matteo Cypriani + * + *********************************************************************** + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL: + * http://www.cecill.info + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided + * only with a limited warranty and the software's authors, the holder + * of the economic rights, and the successive licensors have only + * limited liability. + * + * In this respect, the user's attention is drawn to the risks + * associated with loading, using, modifying and/or developing or + * reproducing the software by the user in light of its specific status + * of free software, that may mean that it is complicated to manipulate, + * and that also therefore means that it is reserved for developers and + * experienced professionals having in-depth computer knowledge. Users + * are therefore encouraged to load and test the software's suitability + * as regards their requirements in conditions enabling the security of + * their systems and/or data to be ensured and, more generally, to use + * and operate it in the same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + *********************************************************************** + */ + + +#ifndef _OWLPS_POSITIONING_CSVREADER_HH_ +#define _OWLPS_POSITIONING_CSVREADER_HH_ + +class Point3D ; + +#include "timestamp.hh" + +#include +#include + + +/// Processes CSV strings, allowing to read them field by field +class CSVStringReader +{ +protected: + const char separator ; + + std::string str ; + boost::tokenizer > *current_token ; + boost::tokenizer >::const_iterator + token_iterator ; + unsigned int current_field_nb ; + + void print_error_cast(void) const ; + +public: + CSVStringReader(const char _separator = ';'): + separator(_separator), current_token(NULL), current_field_nb(0) {} + + virtual ~CSVStringReader(void) ; + + /** @name Accessors */ + //@{ + /// Set a new string to process + void set_str(const std::string &_str) ; + //@} + + /** @name Operations */ + //@{ + /// Reads the next field of the current line + template bool read_field(T &field) ; + /// Reads the next field that should be a Timestamp + bool read_timestamp(Timestamp &t) ; + /// Reads the next 3 fields that should form a Point3D + bool read_point3d(Point3D &p) ; + //@} +} ; + + + +/* *** Operations *** */ + + +template +inline bool CSVStringReader::read_field(T &field) +{ + if (token_iterator == current_token->end()) + return false ; + ++current_field_nb ; + + try + { + field = boost::lexical_cast(*token_iterator) ; + } + catch (boost::bad_lexical_cast &e) + { + print_error_cast() ; + return false ; + } + + ++token_iterator ; + return true ; +} + + + +#endif // _OWLPS_POSITIONING_CSVREADER_HH_