$darkmode
output_serializer.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
22 #pragma once
23 
24 #include <fstream> // for ofstream
25 #include <string> // for string
26 #include <vector> // for vector<>
27 
28 #include <boost/algorithm/string/join.hpp> // for boost::algorithm::join
29 #include <boost/assign/list_of.hpp> // for list_of
30 #include <boost/bimap.hpp> // for bimap
31 #include <boost/iostreams/copy.hpp> // for copy
32 #include <boost/iostreams/filter/bzip2.hpp> // for bzip2_compressor
33 #include <boost/iostreams/filter/gzip.hpp> // for gzip_compressor
34 #include <boost/iostreams/filtering_streambuf.hpp> // for filtering_streambuf
35 #include <boost/range/adaptor/map.hpp> // for boost::adaptors::map
36 #include <boost/range/algorithm/copy.hpp> // for boost::algorithm::copy
37 
38 #include <cloe/core.hpp> // for Logger
39 
40 namespace cloe {
41 namespace utility {
42 
43 class OutputStream {
44  public:
45  using char_iterator = std::vector<char>::iterator;
46  using uint8_iterator = std::vector<uint8_t>::iterator;
47 
48  explicit OutputStream(Logger logger) : logger_(logger) {}
49  virtual ~OutputStream() = default;
50  virtual std::string make_default_filename(const std::string& default_filename) = 0;
51  virtual bool open_stream() = 0;
52  virtual void write(const char* s, std::streamsize count) = 0;
53  virtual void close_stream() = 0;
54 
55  protected:
56  Logger logger_;
57 };
58 
59 template <typename... TSerializerArgs>
60 class Serializer {
61  public:
62  Serializer(void (OutputStream::*write_function)(const char*, std::streamsize),
63  OutputStream* instance)
64  : write_function_(write_function), instance_(instance) {}
65  virtual ~Serializer() = default;
66  virtual std::string make_default_filename(const std::string& default_filename) = 0;
67  virtual void start_array() = 0;
68  virtual void serialize(TSerializerArgs... args) = 0;
69  virtual void end_array() = 0;
70 
71  protected:
72  void write(const std::string& str) { (instance_->*write_function_)(str.c_str(), str.length()); }
73  void write(const std::vector<uint8_t>& data) {
74  (instance_->*write_function_)((const char*)data.data(), data.size());
75  }
76  void (OutputStream::*write_function_)(const char*, std::streamsize);
77  OutputStream* instance_;
78 
79  template <typename TSerializer, typename TOutputStream>
80  friend class GndTruthSerializerImpl;
81 };
82 
84  public:
85  using OutputStream::OutputStream;
86  virtual ~BasicFileOutputStream() = default;
87  bool open_stream() final { return false; }
88 
89  [[nodiscard]]
90  virtual bool open_file(const std::string& filename, const std::string& default_filename);
91 
92  void write(const char* s, std::streamsize count) override { ofs_.write(s, count); }
93  void close_stream() override;
94 
95  protected:
96  std::ofstream ofs_; // output file stream
97 };
98 
100  public:
101  using BasicFileOutputStream::BasicFileOutputStream;
102  virtual ~FileOutputStream() = default;
103  std::string make_default_filename(const std::string& default_filename) override {
104  return default_filename;
105  }
106 };
107 
109  public:
110  explicit FilteringOutputStream(Logger logger)
111  : BasicFileOutputStream(logger), filter_(), out_(&filter_) {}
112  virtual ~FilteringOutputStream() = default;
113 
114  [[nodiscard]]
115  bool open_file(const std::string& filename, const std::string& default_filename) override;
116 
117  void write(const char* s, std::streamsize count) override { out_.write(s, count); }
118  void close_stream() override;
119 
120  protected:
121  virtual void configure_filter() = 0;
122 
123  protected:
124  boost::iostreams::filtering_streambuf<boost::iostreams::output> filter_;
125  std::ostream out_;
126 };
127 
129  public:
130  using FilteringOutputStream::FilteringOutputStream;
131  virtual ~ZlibOutputStream() = default;
132  std::string make_default_filename(const std::string& default_filename) override {
133  return default_filename + ".zip";
134  }
135 
136  protected:
137  void configure_filter() override {
138  filter_.push(boost::iostreams::gzip_compressor(
139  boost::iostreams::gzip_params(boost::iostreams::gzip::best_compression)));
140  }
141 };
142 
144  public:
145  using FilteringOutputStream::FilteringOutputStream;
146  virtual ~GzipOutputStream() = default;
147  std::string make_default_filename(const std::string& default_filename) override {
148  return default_filename + ".gz";
149  }
150 
151  protected:
152  void configure_filter() override {
153  filter_.push(boost::iostreams::gzip_compressor(
154  boost::iostreams::gzip_params(boost::iostreams::gzip::best_compression)));
155  }
156 };
157 
159  public:
160  using FilteringOutputStream::FilteringOutputStream;
161  virtual ~Bzip2OutputStream() = default;
162  std::string make_default_filename(const std::string& default_filename) override {
163  return default_filename + ".bz2";
164  }
165 
166  protected:
167  void configure_filter() override {
168  filter_.push(boost::iostreams::bzip2_compressor(
169  boost::iostreams::bzip2_params(boost::iostreams::bzip2::default_block_size)));
170  }
171 };
172 
174 template <typename TSerializer, typename TOutputStream, typename... TSerializerArgs>
176  public:
177  explicit FileSerializer(Logger logger)
178  : outputstream_(logger)
179  , serializer_((void (OutputStream::*)(const char*, std::streamsize)) & TOutputStream::write,
180  &outputstream_) {}
181  virtual ~FileSerializer() = default;
182 
183  [[nodiscard]]
184  virtual bool open_file(const std::string& filename, const std::string& default_filename) {
185  return outputstream_.open_file(filename, default_filename);
186  }
187 
188  virtual void serialize(TSerializerArgs... args) { serializer_.serialize(args...); }
189  virtual void close_file() { outputstream_.close_stream(); }
190 
191  protected:
192  TOutputStream outputstream_;
193  TSerializer serializer_;
194 };
195 
197 template <typename TSerializer, typename TOutputStream, typename... TSerializerArgs>
199  : public FileSerializer<TSerializer, TOutputStream, TSerializerArgs...> {
200  using base = FileSerializer<TSerializer, TOutputStream, TSerializerArgs...>;
201 
202  public:
203  using base::base;
204 
205  [[nodiscard]]
206  bool open_file(const std::string& filename, const std::string& default_filename) override {
207  bool ok = base::open_file(filename, default_filename);
208  if (ok) {
209  on_file_opened();
210  }
211  return ok;
212  }
213 
214  void close_file() override {
215  on_file_closing();
216  base::close_file();
217  }
218 
219  protected:
220  virtual void on_file_opened() = 0;
221  virtual void on_file_closing() = 0;
222 };
223 
224 } // namespace utility
225 } // namespace cloe
Definition: output_serializer.hpp:83
Definition: output_serializer.hpp:158
Definition: output_serializer.hpp:99
FileSerializer composes a TSerializer with a TOutputStream.
Definition: output_serializer.hpp:175
Definition: output_serializer.hpp:108
Definition: output_serializer.hpp:143
Definition: output_serializer.hpp:43
SequentialFileSerializer is a FileSerializer for sequences of objects of the same type.
Definition: output_serializer.hpp:199
Definition: output_serializer.hpp:60
Definition: output_serializer.hpp:128