/*
 * This file is part of the Owl Positioning System (OwlPS) project.
 * It is subject to the copyright notice and license terms in the
 * COPYRIGHT.t2t file found in the top-level directory of this
 * distribution and at
 *   https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
 * No part of the OwlPS Project, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms
 * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
 * distributed along with this file, either separately or by replacing
 * this notice by the COPYRIGHT.t2t file's contents.
 */


#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(nullptr), current_field_nb(0) {}

  CSVStringReader(const std::string &_str, const char _separator = ';') ;

  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_
