[Positioner] Add class CSVStringReader
Code separated from CSVFileReader, which now inherits from both TextFileReader and CSVStringReader.
This commit is contained in:
parent
559c884499
commit
f55672ef01
|
@ -63,6 +63,7 @@ OBJ_LIST = \
|
||||||
topologyreadercsv.o \
|
topologyreadercsv.o \
|
||||||
textfilereader.o \
|
textfilereader.o \
|
||||||
csvfilereader.o \
|
csvfilereader.o \
|
||||||
|
csvstringreader.o \
|
||||||
textfilewriter.o \
|
textfilewriter.o \
|
||||||
output.o \
|
output.o \
|
||||||
outputterminal.o \
|
outputterminal.o \
|
||||||
|
@ -200,7 +201,11 @@ $(OBJ_DIR)/resultlist.o: \
|
||||||
$(OBJ_DIR)/textfilereader.o: \
|
$(OBJ_DIR)/textfilereader.o: \
|
||||||
$(OBJ_DIR)/posexcept.o
|
$(OBJ_DIR)/posexcept.o
|
||||||
$(OBJ_DIR)/csvfilereader.o: \
|
$(OBJ_DIR)/csvfilereader.o: \
|
||||||
|
$(OBJ_DIR)/csvstringreader.o \
|
||||||
$(OBJ_DIR)/textfilereader.o
|
$(OBJ_DIR)/textfilereader.o
|
||||||
|
$(OBJ_DIR)/csvstringreader.o: \
|
||||||
|
$(OBJ_DIR)/point3d.o \
|
||||||
|
$(OBJ_DIR)/timestamp.o
|
||||||
$(OBJ_DIR)/textfilewriter.o: \
|
$(OBJ_DIR)/textfilewriter.o: \
|
||||||
$(OBJ_DIR)/posexcept.o
|
$(OBJ_DIR)/posexcept.o
|
||||||
$(OBJ_DIR)/inputmedium.o: \
|
$(OBJ_DIR)/inputmedium.o: \
|
||||||
|
|
|
@ -49,16 +49,6 @@ using namespace boost ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Constructors *** */
|
|
||||||
|
|
||||||
|
|
||||||
CSVFileReader::~CSVFileReader()
|
|
||||||
{
|
|
||||||
delete current_token ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Operations *** */
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,91 +59,11 @@ CSVFileReader::~CSVFileReader()
|
||||||
*/
|
*/
|
||||||
bool CSVFileReader::next_line()
|
bool CSVFileReader::next_line()
|
||||||
{
|
{
|
||||||
delete current_token ;
|
|
||||||
current_token = NULL ;
|
|
||||||
|
|
||||||
if (! read_nonblank_line(current_line))
|
if (! read_nonblank_line(current_line))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// Split read string into fields (semicolon-separated)
|
set_str(current_line) ;
|
||||||
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 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CSVFileReader::read_timestamp(Timestamp &t)
|
|
||||||
{
|
|
||||||
string timestamp_str ;
|
|
||||||
uint_fast32_t time_s, time_ns ;
|
|
||||||
|
|
||||||
if (! read_field(timestamp_str))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
tokenizer<escaped_list_separator<char> > tok(
|
|
||||||
timestamp_str, escaped_list_separator<char>('\\', '.', '\"')) ;
|
|
||||||
tokenizer<escaped_list_separator<char> >::const_iterator tok_iter =
|
|
||||||
tok.begin() ;
|
|
||||||
|
|
||||||
if (tok_iter == tok.end())
|
|
||||||
return false ;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
time_s = lexical_cast<uint_fast32_t>(*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<uint_fast32_t>(*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<float>(*token_iterator) ;
|
|
||||||
}
|
|
||||||
catch (bad_lexical_cast &e)
|
|
||||||
{
|
|
||||||
print_error_cast() ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
++token_iterator ;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.set_coordinates(coord) ;
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,75 +42,30 @@
|
||||||
#ifndef _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
#ifndef _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
||||||
#define _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
#define _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
||||||
|
|
||||||
class Point3D ;
|
|
||||||
|
|
||||||
#include "textfilereader.hh"
|
#include "textfilereader.hh"
|
||||||
#include "timestamp.hh"
|
#include "csvstringreader.hh"
|
||||||
|
|
||||||
#include <boost/tokenizer.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
/// Reads a CSV file, line by line, field by field
|
/// Reads a CSV file, line by line, field by field
|
||||||
class CSVFileReader: public TextFileReader
|
class CSVFileReader: public TextFileReader, public CSVStringReader
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const char separator ;
|
|
||||||
|
|
||||||
std::string current_line ;
|
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) const ;
|
void print_error_cast(void) const ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSVFileReader(const std::string &filename,
|
CSVFileReader(const std::string &filename,
|
||||||
const char _separator = ';'):
|
const char _separator = ';'):
|
||||||
TextFileReader(filename), separator(_separator),
|
TextFileReader(filename), CSVStringReader(_separator) {}
|
||||||
current_token(NULL), current_field_nb(0) {}
|
|
||||||
|
|
||||||
virtual ~CSVFileReader(void) ;
|
|
||||||
|
|
||||||
/** @name Operations */
|
/** @name Operations */
|
||||||
//@{
|
//@{
|
||||||
/// Loads the first next non-blank line
|
/// Loads the first next non-blank line
|
||||||
bool next_line(void) ;
|
bool next_line(void) ;
|
||||||
/// Reads the next field of the current line
|
|
||||||
template<class T> 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<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_
|
#endif // _OWLPS_POSITIONING_CSVFILEREADER_HH_
|
||||||
|
|
|
@ -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 <mcy@lm7.fr>
|
||||||
|
*
|
||||||
|
***********************************************************************
|
||||||
|
*
|
||||||
|
* 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 <iostream>
|
||||||
|
|
||||||
|
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<escaped_list_separator<char> >(
|
||||||
|
str, escaped_list_separator<char>('\\', 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<escaped_list_separator<char> > tok(
|
||||||
|
timestamp_str, escaped_list_separator<char>('\\', '.', '\"')) ;
|
||||||
|
tokenizer<escaped_list_separator<char> >::const_iterator tok_iter =
|
||||||
|
tok.begin() ;
|
||||||
|
|
||||||
|
if (tok_iter == tok.end())
|
||||||
|
return false ;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
time_s = lexical_cast<uint_fast32_t>(*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<uint_fast32_t>(*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<float>(*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 ;
|
||||||
|
}
|
|
@ -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 <mcy@lm7.fr>
|
||||||
|
*
|
||||||
|
***********************************************************************
|
||||||
|
*
|
||||||
|
* 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 <boost/tokenizer.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/// Processes CSV strings, allowing to read them field by field
|
||||||
|
class CSVStringReader
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const char separator ;
|
||||||
|
|
||||||
|
std::string str ;
|
||||||
|
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) 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<class T> 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<class T>
|
||||||
|
inline bool CSVStringReader::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_CSVREADER_HH_
|
Loading…
Reference in New Issue