mod_servlet
C++Servlets
 All Classes Files Functions Variables Typedefs Macros Pages
io_filter.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2016 Alexei Novakov
3 https://github.com/novalexei
4 
5 Distributed under the Boost Software License, Version 1.0.
6 http://boost.org/LICENSE_1_0.txt
7 */
8 #ifndef MOD_SERVLET_IO_FILTER_H
9 #define MOD_SERVLET_IO_FILTER_H
10 
11 #include <servlet/lib/io.h>
12 
18 namespace servlet
19 {
20 
26 template <typename CharT>
27 struct basic_sink
28 {
32  virtual ~basic_sink() noexcept = default;
40  virtual std::streamsize write(CharT* s, std::streamsize n) = 0;
44  virtual void flush() {}
45 };
51 template <typename CharT>
53 {
57  virtual ~basic_source() noexcept = default;
65  virtual std::streamsize read(CharT* s, std::streamsize n) = 0;
66 };
71 template <typename CharT>
73 {
77  virtual ~basic_out_filter() noexcept = default;
86  virtual std::streamsize write(CharT* s, std::streamsize n, basic_sink<CharT>& dst) = 0;
87 };
92 template <typename CharT>
94 {
98  virtual ~basic_in_filter() noexcept = default;
109  virtual std::streamsize read(CharT* s, std::streamsize n, basic_source<CharT>& src) = 0;
110 };
111 
120 
121 template<typename CharT>
122 class out_filter_adapter : public basic_sink<CharT>
123 {
124 public:
125  out_filter_adapter(basic_sink<CharT>& dst, basic_out_filter<CharT>* filter, bool filter_owner) :
126  _sink{dst}, _filter{filter}, _filter_owner{filter_owner} {}
127  ~out_filter_adapter() noexcept override { if (_filter_owner) delete _filter; }
128 
129  std::streamsize write(CharT* s, std::streamsize n) override { return _filter->write(s, n, _sink); }
130 private:
131  basic_sink<CharT>& _sink;
132  basic_out_filter<CharT>* _filter;
133  bool _filter_owner;
134 };
135 
143 template <typename CharT>
144 class basic_filtered_sink : public basic_sink<CharT>
145 {
146 public:
154  explicit basic_filtered_sink(basic_sink<CharT>* sink) : _sink{sink} { _front_sink = _sink; }
158  ~basic_filtered_sink() noexcept override { delete _sink; }
159 
160  std::streamsize write(CharT* s, std::streamsize n) override { return _front_sink->write(s, n); }
161  void flush() override { _sink->flush(); }
162 
169  void add_filter(basic_out_filter<CharT>* filter, bool delete_after_use = true)
170  {
171  if (_filters.empty()) _filters.emplace_back(*_sink, filter, delete_after_use);
172  else _filters.emplace_back(_filters.back(), filter, delete_after_use);
173  _front_sink = &_filters.back();
174  }
175 private:
176  basic_sink<CharT>* _sink;
177  std::vector<out_filter_adapter<CharT>> _filters;
178  basic_sink<CharT>* _front_sink;
179 };
180 
181 template<typename CharT>
182 class in_filter_adapter : public basic_source<CharT>
183 {
184 public:
185  in_filter_adapter(basic_source<CharT>& src, basic_in_filter<CharT>* filter, bool filter_owner) :
186  _source{src}, _filter{filter}, _filter_owner{filter_owner} {}
187  ~in_filter_adapter() noexcept override { if (_filter_owner) delete _filter; }
188 
189  std::streamsize read(CharT* s, std::streamsize n) override { return _filter->read(s, n, _source); }
190 private:
191  basic_source<CharT>& _source;
192  basic_in_filter<CharT>* _filter;
193  bool _filter_owner;
194 };
195 
203 template <typename CharT>
204 class basic_filtered_source : public basic_source<CharT>
205 {
206 public:
214  explicit basic_filtered_source(basic_source<CharT>* src) : _source{src} { _front_source = _source; }
215  ~basic_filtered_source() noexcept override { delete _source; }
216 
217  std::streamsize read(CharT* s, std::streamsize n) override { return _front_source->read(s, n); }
218 
225  void add_filter(basic_in_filter<CharT>* filter, bool delete_after_use = true)
226  {
227  if (_filters.empty()) _filters.emplace_back(*_source, filter, delete_after_use);
228  else _filters.emplace_back(_filters.back(), filter, delete_after_use);
229  _front_source = &_filters.back();
230  }
231 private:
232  basic_source<CharT>* _source;
233  std::vector<in_filter_adapter<CharT>> _filters;
234  basic_source<CharT>* _front_source;
235 };
236 
243 template <typename CharT>
244 class basic_stream_sink : public basic_sink<CharT>
245 {
246 public:
252  basic_stream_sink(std::basic_ostream<CharT>& out) : _out{out} {}
253  std::streamsize write(CharT* s, std::streamsize n) override
254  {
255  _out.write(s, n);
256  return _out ? n : 0;
257  }
258 private:
259  std::basic_ostream<CharT>& _out;
260 };
261 
268 template <typename CharT>
269 class basic_stream_source : public basic_source<CharT>
270 {
271 public:
277  basic_stream_source(std::basic_istream<CharT>& in) : _in{in} {}
278  std::streamsize read(CharT* s, std::streamsize n) override
279  {
280  _in.read(s, n);
281  return _in.gcount();
282  }
283 private:
284  std::basic_istream<CharT>& _in;
285 };
286 
290 using stream_sink = basic_stream_sink<char>;
294 using stream_source = basic_stream_source<char>;
295 
300 template <typename CharT, typename Buffering = buffer_1k>
301 using basic_filtered_outstream = basic_outstream<basic_filtered_sink<CharT>, Buffering, CharT>;
306 template <typename CharT, typename Buffering = buffer_1k>
307 using basic_filtered_instream = basic_instream<basic_filtered_source<CharT>, Buffering, CharT>;
308 
312 using filtered_outstream = basic_filtered_outstream<char>;
316 using filtered_instream = basic_filtered_instream<char>;
317 
318 } // end of servlet namespace
319 
320 #endif // MOD_SERVLET_IO_FILTER_H
void add_filter(basic_out_filter< CharT > *filter, bool delete_after_use=true)
Adds new filter to the end of the filter chain.
Definition: io_filter.h:169
basic_filtered_sink(basic_sink< CharT > *sink)
Constructs the object with the sink to which all filtered data will be passed.
Definition: io_filter.h:154
basic_stream_sink(std::basic_ostream< CharT > &out)
Constructs new object with a given std::basic_ostream to write data to.
Definition: io_filter.h:252
virtual ~basic_sink() noexcept=default
Virtual constructor.
virtual ~basic_in_filter() noexcept=default
Virtual destructor.
virtual ~basic_source() noexcept=default
Virtual constructor.
void add_filter(basic_in_filter< CharT > *filter, bool delete_after_use=true)
Adds new filter to the end of the filter chain.
Definition: io_filter.h:225
Definitions for custom implementation of std::istream and std::ostream objects.
Implementation of source which will acquire all the data from a std::basic_istream.
Definition: io_filter.h:269
virtual std::streamsize read(CharT *s, std::streamsize n, basic_source< CharT > &src)=0
Extracts the characters from the source, filters the input and copies at most n characters to the pro...
void flush() override
Flush sink if it can be flushed.
Definition: io_filter.h:161
Implementation of filtered source.
Definition: io_filter.h:204
virtual std::streamsize read(CharT *s, std::streamsize n)=0
Extracts at most n characters from the source into the provided s array.
basic_stream_source(std::basic_istream< CharT > &in)
Constructs new object with a given std::basic_istream to read data from.
Definition: io_filter.h:277
Implementation of filtered sink.
Definition: io_filter.h:144
Implementation of sink which will pass all the data to a std::basic_ostream.
Definition: io_filter.h:244
Abstract interface for generic sink.
Definition: io_filter.h:27
Abstract interface for output filter.
Definition: io_filter.h:72
std::streamsize write(CharT *s, std::streamsize n) override
Writes the first n characters of array s into the sink.
Definition: io_filter.h:160
virtual std::streamsize write(CharT *s, std::streamsize n)=0
Writes the first n characters of array s into the sink.
Abstract interface for generic source.
Definition: io_filter.h:52
basic_filtered_source(basic_source< CharT > *src)
Constructs the object with the source from which all the data to be filtered will be acquired...
Definition: io_filter.h:214
std::streamsize read(CharT *s, std::streamsize n) override
Extracts at most n characters from the source into the provided s array.
Definition: io_filter.h:278
std::streamsize read(CharT *s, std::streamsize n) override
Extracts at most n characters from the source into the provided s array.
Definition: io_filter.h:217
virtual void flush()
Flush sink if it can be flushed.
Definition: io_filter.h:44
virtual std::streamsize write(CharT *s, std::streamsize n, basic_sink< CharT > &dst)=0
Filters first n characters from the buffer s and passes the filtered characters to dst ...
Sink tag.
Definition: io.h:91
~basic_filtered_sink() noexceptoverride
Destroys this object.
Definition: io_filter.h:158
virtual ~basic_out_filter() noexcept=default
Virtual destructor.
std::streamsize write(CharT *s, std::streamsize n) override
Writes the first n characters of array s into the sink.
Definition: io_filter.h:253
Abstract interface for input filter.
Definition: io_filter.h:93