crocoddyl  1.8.0
Contact RObot COntrol by Differential DYnamic programming Library (Crocoddyl)
file-io.hpp
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020 LAAS-CNRS
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
8 
9 // modified from https://gist.github.com/rudolfovich/f250900f1a833e715260a66c87369d15
10 
11 #ifndef CROCODDYL_CORE_UTILS_FILE_IO_HPP_
12 #define CROCODDYL_CORE_UTILS_FILE_IO_HPP_
13 
14 #include <string>
15 #include <fstream>
16 #include <sstream>
17 
18 class CsvStream {
19  std::ofstream fs_;
20  bool is_first_;
21  const std::string separator_;
22  const std::string escape_seq_;
23  const std::string special_chars_;
24 
25  public:
26  CsvStream(const std::string filename, const std::string separator = ",")
27  : fs_(), is_first_(true), separator_(separator), escape_seq_("\""), special_chars_("\"") {
28  fs_.exceptions(std::ios::failbit | std::ios::badbit);
29  fs_.open(filename.c_str());
30  }
31 
32  ~CsvStream() {
33  flush();
34  fs_.close();
35  }
36 
37  void flush() { fs_.flush(); }
38 
39  inline static CsvStream& endl(CsvStream& file) {
40  file.endrow();
41  return file;
42  }
43 
44  void endrow() {
45  fs_ << std::endl;
46  is_first_ = true;
47  }
48 
49  CsvStream& operator<<(CsvStream& (*val)(CsvStream&)) { return val(*this); }
50 
51  CsvStream& operator<<(const char* val) { return write(escape(val)); }
52 
53  CsvStream& operator<<(const std::string& val) { return write(escape(val)); }
54 
55  template <typename T>
56  CsvStream& operator<<(const T& val) {
57  return write(val);
58  }
59 
60  private:
61  template <typename T>
62  CsvStream& write(const T& val) {
63  if (!is_first_) {
64  fs_ << separator_;
65  } else {
66  is_first_ = false;
67  }
68  fs_ << val;
69  return *this;
70  }
71 
72  std::string escape(const std::string& val) {
73  std::ostringstream result;
74  result << '"';
75  std::string::size_type to, from = 0u, len = val.length();
76  while (from < len && std::string::npos != (to = val.find_first_of(special_chars_, from))) {
77  result << val.substr(from, to - from) << escape_seq_ << val[to];
78  from = to + 1;
79  }
80  result << val.substr(from) << '"';
81  return result.str();
82  }
83 };
84 
85 #endif // CROCODDYL_CORE_UTILS_FILE_IO_HPP_