HiPipe  0.7.0
C++17 data pipeline with Python bindings.
csv.hpp
1 /****************************************************************************
2  * hipipe library
3  * Copyright (c) 2017, Cognexa Solutions s.r.o.
4  * Copyright (c) 2018, Iterait a.s.
5  * Author(s) Filip Matzner
6  *
7  * This file is distributed under the MIT License.
8  * See the accompanying file LICENSE.txt for the complete license agreement.
9  ****************************************************************************/
11 
12 #pragma once
13 
14 #include <hipipe/core/dataframe.hpp>
15 
16 #include <range/v3/iterator/default_sentinel.hpp>
17 
18 #include <experimental/filesystem>
19 #include <fstream>
20 #include <iostream>
21 #include <vector>
22 
23 namespace hipipe {
24 
25 
40 class csv_istream_range : public ranges::view_facade<csv_istream_range> {
41 private:
43  friend ranges::range_access;
45  using single_pass = std::true_type;
46  enum class RowPosition{Normal, Last, End};
47 
48  std::istream* in_;
49  char separator_;
50  char quote_;
51  char escape_;
52 
53  std::vector<std::string> row_;
54  RowPosition row_position_ = RowPosition::Normal;
55 
56  class cursor {
57  private:
58  csv_istream_range* rng_;
59 
60  public:
61  cursor() = default;
62  explicit cursor(csv_istream_range& rng) noexcept
63  : rng_{&rng}
64  {}
65 
66  void next()
67  {
68  rng_->next();
69  }
70 
71  std::vector<std::string>& read() const noexcept
72  {
73  return rng_->row_;
74  }
75 
76  std::vector<std::string>&& move() const noexcept
77  {
78  return std::move(rng_->row_);
79  }
80 
81  bool equal(ranges::default_sentinel_t) const noexcept
82  {
83  return rng_->row_position_ == RowPosition::End;
84  }
85  };
86 
87  // parse csv field and return whether the next separator is found
88  std::tuple<std::string, bool> parse_field();
89 
90  // parse csv row
91  void next();
92 
93  cursor begin_cursor() { return cursor{*this}; }
94 
95 public:
96  csv_istream_range() = default;
97 
98  explicit csv_istream_range(std::istream& in,
99  char separator = ',',
100  char quote = '"',
101  char escape = '\\');
102 };
103 
115 dataframe read_csv(
116  std::istream& in,
117  int drop = 0,
118  bool has_header = true,
119  char separator = ',',
120  char quote = '"',
121  char escape = '\\');
122 
123 
127 dataframe read_csv(
128  const std::experimental::filesystem::path& file,
129  int drop = 0,
130  bool header = true,
131  char separator = ',',
132  char quote = '"',
133  char escape = '\\');
134 
135 
142 std::ostream& write_csv_row(
143  std::ostream& out,
144  const std::vector<std::string>& row,
145  char separator = ',',
146  char quote = '"',
147  char escape = '\\');
148 
149 
156 std::ostream& write_csv(
157  std::ostream& out,
158  const dataframe& df,
159  char separator = ',',
160  char quote = '"',
161  char escape = '\\');
162 
163 
167 void write_csv(
168  const std::experimental::filesystem::path& file,
169  const dataframe& df,
170  char separator = ',',
171  char quote = '"',
172  char escape = '\\');
173 
174 } // namespace hipipe
hipipe::write_csv
void write_csv(const std::experimental::filesystem::path &file, const dataframe &df, char separator=',', char quote='"', char escape = '\\')
Same as write_csv(std::ostream...), but write directly to a file.
hipipe::write_csv_row
std::ostream & write_csv_row(std::ostream &out, const std::vector< std::string > &row, char separator=',', char quote='"', char escape = '\\')
Write a single csv row to an std::ostream.
hipipe::stream::drop
rgv::view< detail::drop_fn< Columns... > > drop
Drops columns from a stream.
Definition: drop.hpp:75
hipipe::read_csv
dataframe read_csv(const std::experimental::filesystem::path &file, int drop=0, bool header=true, char separator=',', char quote='"', char escape = '\\')
Same as read_csv() but read directly from a file.