Kea  2.1.7-git
csv_file.h
Go to the documentation of this file.
1 // Copyright (C) 2014-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef CSV_FILE_H
8 #define CSV_FILE_H
9 
10 #include <exceptions/exceptions.h>
11 #include <boost/lexical_cast.hpp>
12 #include <boost/shared_ptr.hpp>
13 #include <fstream>
14 #include <ostream>
15 #include <string>
16 #include <vector>
17 
18 namespace isc {
19 namespace util {
20 
22 class CSVFileError : public Exception {
23 public:
24  CSVFileError(const char* file, size_t line, const char* what) :
25  isc::Exception(file, line, what) { };
26 };
27 
51 class CSVRow {
52 public:
53 
67  CSVRow(const size_t cols = 0, const char separator = ',');
68 
82  CSVRow(const std::string& text, const char separator = ',');
83 
85  size_t getValuesCount() const {
86  return (values_.size());
87  }
88 
98  void parse(const std::string& line);
99 
110  std::string readAt(const size_t at) const;
111 
131  std::string readAtEscaped(const size_t at) const;
132 
139  void trim(const size_t count);
140 
155  template<typename T>
156  T readAndConvertAt(const size_t at) const {
157  T cast_value;
158  try {
159  cast_value = boost::lexical_cast<T>(readAt(at).c_str());
160 
161  } catch (const boost::bad_lexical_cast& ex) {
162  isc_throw(CSVFileError, ex.what());
163  }
164  return (cast_value);
165  }
166 
176  std::string render() const;
177 
187  void writeAt(const size_t at, const char* value);
188 
198  void writeAt(const size_t at, const std::string& value) {
199  writeAt(at, value.c_str());
200  }
201 
213  void writeAtEscaped(const size_t at, const std::string& value);
214 
219  template<typename T>
220  void append(const T value) {
221  try {
222  values_.push_back(boost::lexical_cast<std::string>(value));
223  } catch (const boost::bad_lexical_cast& ex) {
224  isc_throw(CSVFileError, "unable to stringify the value to be "
225  "appended to the CSV file row.");
226  }
227  }
228 
239  template<typename T>
240  void writeAt(const size_t at, const T value) {
241  checkIndex(at);
242  try {
243  values_[at] = boost::lexical_cast<std::string>(value);
244  } catch (const boost::bad_lexical_cast& ex) {
245  isc_throw(CSVFileError, "unable to stringify the value to be"
246  " written in the CSV file row at position '"
247  << at << "'");
248  }
249  }
250 
257  bool operator==(const CSVRow& other) const {
258  return (render() == other.render());
259  }
260 
267  bool operator!=(const CSVRow& other) const {
268  return (render() != other.render());
269  }
270 
289  static std::string escapeCharacters(const std::string& orig_str,
290  const std::string& characters);
291 
300  static std::string unescapeCharacters(const std::string& escaped_str);
301 
302 private:
303 
310  void checkIndex(const size_t at) const;
311 
318  std::string separator_;
319 
321  std::vector<std::string> values_;
322 
324  static const std::string escape_tag;
325 };
326 
334 std::ostream& operator<<(std::ostream& os, const CSVRow& row);
335 
358 class CSVFile {
359 public:
360 
364  CSVFile(const std::string& filename);
365 
367  virtual ~CSVFile();
368 
378  void addColumn(const std::string& col_name);
379 
386  void append(const CSVRow& row) const;
387 
389  void close();
390 
397  bool exists() const;
398 
400  void flush() const;
401 
403  size_t getColumnCount() const {
404  return (cols_.size());
405  }
406 
408  std::string getFilename() const {
409  return (filename_);
410  }
411 
416  std::string getReadMsg() const {
417  return (read_msg_);
418  }
419 
427  size_t getColumnIndex(const std::string& col_name) const;
428 
435  std::string getColumnName(const size_t col_index) const;
436 
448  bool next(CSVRow& row, const bool skip_validation = false);
449 
466 
467  virtual void open(const bool seek_to_end = false);
468 
475  virtual void recreate();
476 
486  void setReadMsg(const std::string& read_msg) {
487  read_msg_ = read_msg;
488  }
489 
491  static CSVRow EMPTY_ROW() {
492  static CSVRow row(0);
493  return (row);
494  }
495 
496 protected:
497 
509  void addColumnInternal(const std::string& col_name);
510 
527  virtual bool validate(const CSVRow& row);
528 
529 protected:
530 
542  virtual bool validateHeader(const CSVRow& header);
543 
544 private:
554  void checkStreamStatusAndReset(const std::string& operation) const;
555 
557  std::streampos size() const;
558 
560  std::string filename_;
561 
563  boost::shared_ptr<std::fstream> fs_;
564 
566  std::vector<std::string> cols_;
567 
569  std::string read_msg_;
570 };
571 
572 } // namespace isc::util
573 } // namespace isc
574 
575 #endif // CSV_FILE_H
T readAndConvertAt(const size_t at) const
Retrieves a value from the internal container.
Definition: csv_file.h:156
size_t getColumnCount() const
Returns the number of columns in the file.
Definition: csv_file.h:403
static CSVRow EMPTY_ROW()
Represents empty row.
Definition: csv_file.h:491
std::ostream & operator<<(std::ostream &os, const CSVRow &row)
Overrides standard output stream operator for CSVRow object.
Definition: csv_file.cc:100
std::string getFilename() const
Returns the path to the CSV file.
Definition: csv_file.h:408
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
size_t getValuesCount() const
Returns number of values in a CSV row.
Definition: csv_file.h:85
void writeAt(const size_t at, const T value)
Replaces the value at specified index.
Definition: csv_file.h:240
Represents a single row of the CSV file.
Definition: csv_file.h:51
void setReadMsg(const std::string &read_msg)
Sets error message after row validation.
Definition: csv_file.h:486
bool operator!=(const CSVRow &other) const
Unequality operator.
Definition: csv_file.h:267
void writeAt(const size_t at, const std::string &value)
Replaces the value at specified index.
Definition: csv_file.h:198
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-lfc.
std::string getReadMsg() const
Returns the description of the last error returned by the CSVFile::next function. ...
Definition: csv_file.h:416
bool operator==(const CSVRow &other) const
Equality operator.
Definition: csv_file.h:257
Provides input/output access to CSV files.
Definition: csv_file.h:358
CSVFileError(const char *file, size_t line, const char *what)
Definition: csv_file.h:24
string trim(const string &instring)
Trim Leading and Trailing Spaces.
Definition: strutil.cc:53
void append(const T value)
Appends the value as a new column.
Definition: csv_file.h:220
std::string render() const
Creates a text representation of the CSV file row.
Definition: csv_file.cc:71
Exception thrown when an error occurs during CSV file processing.
Definition: csv_file.h:22