libfilezilla
reader.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_AIO_READER_HEADER
2 #define LIBFILEZILLA_AIO_READER_HEADER
3 
10 #include "aio.hpp"
11 #include "../file.hpp"
12 #include "../thread_pool.hpp"
13 
14 #include <list>
15 
16 namespace fz {
17 
26 class FZ_PUBLIC_SYMBOL reader_base : public aio_base, public aio_waitable, public event_handler
27 {
28 public:
29  reader_base(reader_base const&) = delete;
30  reader_base& operator=(reader_base const&) = delete;
31 
32  void close();
33 
34  virtual bool seekable() const { return false; }
35 
37  bool seek(uint64_t offset, uint64_t size = nosize);
38 
40  bool rewind();
41 
42  std::wstring const& name() const { return name_; }
43 
45  virtual uint64_t size() const { return size_; }
46 
48  virtual datetime mtime() const { return {}; }
49 
60  std::pair<aio_result, buffer_lease> get_buffer(event_handler & h);
61 
62  bool error() const;
63 
64 protected:
74  reader_base(std::wstring && name, aio_buffer_pool & pool, size_t max_buffers) noexcept
75  : event_handler(pool.loop())
76  , buffer_pool_(pool)
77  , logger_(pool.logger())
78  , name_(name)
79  , max_buffers_(max_buffers ? max_buffers : 1)
80  {}
81 
82  reader_base(std::wstring_view name, aio_buffer_pool & pool, size_t max_buffers) noexcept
83  : event_handler(pool.loop())
84  , buffer_pool_(pool)
85  , logger_(pool.logger())
86  , name_(name)
87  , max_buffers_(max_buffers ? max_buffers : 1)
88  {}
89 
90  virtual std::pair<aio_result, buffer_lease> do_get_buffer(scoped_lock & l) = 0;
91 
94  virtual bool do_seek(scoped_lock &) {
95  return false;
96  }
97 
98  virtual void do_close(scoped_lock &) {}
99 
100  virtual void operator()(event_base const&) override;
101  void on_buffer_availability(aio_waitable const* w);
102  virtual void do_on_buffer_availability(fz::scoped_lock & l, aio_waitable const* w) = 0;
103 
104  mutable mutex mtx_;
105  aio_buffer_pool & buffer_pool_;
106  logger_interface & logger_;
107 
108  std::wstring const name_;
109 
110  size_t const max_buffers_{};
111  std::list<buffer_lease> buffers_;
112 
113  uint64_t size_{nosize};
114  uint64_t max_size_{nosize};
115  uint64_t start_offset_{nosize};
116  uint64_t remaining_{nosize};
117 
118  bool get_buffer_called_{};
119  bool error_{};
120  bool eof_{};
121  bool waiting_{};
122 };
123 
125 class FZ_PUBLIC_SYMBOL reader_factory
126 {
127 public:
128  explicit reader_factory(std::wstring const& name)
129  : name_(name)
130  {}
131  explicit reader_factory(std::wstring && name)
132  : name_(std::move(name))
133  {}
134 
135  virtual ~reader_factory() noexcept = default;
136 
138  virtual std::unique_ptr<reader_factory> clone() const = 0;
139 
151  virtual std::unique_ptr<reader_base> open(aio_buffer_pool & pool, uint64_t offset = 0, uint64_t size = reader_base::nosize, size_t max_buffers = 0) = 0;
152 
153  virtual bool seekable() const { return false; }
154 
155  std::wstring name() const { return name_; }
156 
157  virtual uint64_t size() const { return reader_base::nosize; }
158  virtual datetime mtime() const { return datetime(); }
159 
166  virtual size_t min_buffer_usage() const { return 1; }
167 
173  virtual bool multiple_buffer_usage() const { return false; }
174 
175  virtual size_t preferred_buffer_count() const { return 1; }
176 
177 protected:
178  reader_factory() = default;
179  reader_factory(reader_factory const&) = default;
180 
181  std::wstring const name_;
182 };
183 
185 class FZ_PUBLIC_SYMBOL reader_factory_holder final
186 {
187 public:
188  reader_factory_holder() = default;
189  reader_factory_holder(std::unique_ptr<reader_factory> && factory);
190  reader_factory_holder(std::unique_ptr<reader_factory> const& factory);
191  reader_factory_holder(reader_factory const& factory);
192 
194  reader_factory_holder& operator=(reader_factory_holder const& op);
195 
197  reader_factory_holder& operator=(reader_factory_holder && op) noexcept;
198  reader_factory_holder& operator=(std::unique_ptr<reader_factory> && factory);
199 
200  reader_factory const* operator->() const { return impl_.get(); }
201  reader_factory* operator->() { return impl_.get(); }
202  reader_factory const& operator*() const { return *impl_; }
203  reader_factory & operator*() { return *impl_; }
204 
205  explicit operator bool() const { return impl_.operator bool(); }
206 
207  std::wstring name() const { return impl_ ? impl_->name() : std::wstring(); }
208  datetime mtime() const { return impl_ ? impl_->mtime() : datetime(); }
209  uint64_t size() const { return impl_ ? impl_->size() : aio_base::nosize; }
210 
211 private:
212  std::unique_ptr<reader_factory> impl_;
213 };
214 
215 class thread_pool;
216 
218 class FZ_PUBLIC_SYMBOL threaded_reader : public reader_base
219 {
220 public:
221  using reader_base::reader_base;
222 
223 protected:
224  virtual std::pair<aio_result, buffer_lease> do_get_buffer(scoped_lock & l) override;
225 
226  void wakeup(scoped_lock & l) {
227  cond_.signal(l);
228  }
229 
230  condition cond_;
231  async_task task_;
232 
233  bool quit_{};
234 };
235 
237 class FZ_PUBLIC_SYMBOL file_reader final : public threaded_reader
238 {
239 public:
244  file_reader(std::wstring && name, aio_buffer_pool & pool, file && f, thread_pool & tpool, uint64_t offset = 0, uint64_t size = nosize, size_t max_buffers = 4) noexcept;
245  file_reader(std::wstring_view name, aio_buffer_pool & pool, file && f, thread_pool & tpool, uint64_t offset = 0, uint64_t size = nosize, size_t max_buffers = 4) noexcept;
246 
247  virtual ~file_reader() noexcept;
248 
249  virtual bool seekable() const override;
250 
251  virtual datetime mtime() const override;
252 
253 private:
254  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
255  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
256 
257  virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
258 
259  void FZ_PRIVATE_SYMBOL entry();
260 
261  file file_;
262  thread_pool & thread_pool_;
263 };
264 
266 class FZ_PUBLIC_SYMBOL file_reader_factory final : public reader_factory
267 {
268 public:
269  file_reader_factory(std::wstring const& file, thread_pool & tpool);
270 
271  virtual std::unique_ptr<reader_base> open(aio_buffer_pool & pool, uint64_t offset = 0, uint64_t size = reader_base::nosize, size_t max_buffers = 4) override;
272  virtual std::unique_ptr<reader_factory> clone() const override;
273 
274  virtual bool seekable() const override { return true; }
275 
276  virtual uint64_t size() const override;
277  virtual datetime mtime() const override;
278 
279  virtual bool multiple_buffer_usage() const override { return true; }
280 
281  virtual size_t preferred_buffer_count() const override { return 4; }
282 private:
283  thread_pool & thread_pool_;
284 };
285 
290 class FZ_PUBLIC_SYMBOL view_reader final : public reader_base
291 {
292 public:
293  view_reader(std::wstring && name, aio_buffer_pool & pool, std::string_view data) noexcept;
294 
295  virtual ~view_reader() noexcept;
296 
297  virtual bool seekable() const override { return true; }
298 
299 private:
300  virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
301  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
302  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
303 
304  virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
305 
306  std::string_view const view_;
307 };
308 
314 class FZ_PUBLIC_SYMBOL view_reader_factory final : public reader_factory
315 {
316 public:
317  view_reader_factory(std::wstring && name, std::string_view const& view)
318  : reader_factory(std::move(name))
319  , view_(view)
320  {}
321  view_reader_factory(std::wstring const& name, std::string_view const& view)
322  : reader_factory(name)
323  , view_(view)
324  {}
325 
326  virtual std::unique_ptr<reader_base> open(aio_buffer_pool & pool, uint64_t offset = 0, uint64_t size = reader_base::nosize, size_t max_buffers = 1) override;
327  virtual std::unique_ptr<reader_factory> clone() const override;
328 
329  virtual bool seekable() const override { return true; }
330 
331  virtual uint64_t size() const override { return view_.size(); }
332 
333 private:
334  std::string_view const view_;
335 };
336 
338 class FZ_PUBLIC_SYMBOL string_reader final : public reader_base
339 {
340 public:
341  string_reader(std::wstring && name, aio_buffer_pool & pool, std::string const& data) noexcept;
342  string_reader(std::wstring && name, aio_buffer_pool & pool, std::string && data) noexcept;
343 
344  virtual ~string_reader() noexcept;
345 
346  virtual bool seekable() const override { return true; }
347 
348 private:
349  virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
350  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
351  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
352 
353  virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
354 
355  std::string const data_;
356 };
357 
359 class FZ_PUBLIC_SYMBOL string_reader_factory final : public reader_factory
360 {
361 public:
362  string_reader_factory(std::wstring const& name, std::string const& data)
363  : reader_factory(name)
364  , data_(data)
365  {}
366  string_reader_factory(std::wstring && name, std::string && data)
367  : reader_factory(std::move(name))
368  , data_(std::move(data))
369  {}
370 
371  virtual std::unique_ptr<reader_base> open(aio_buffer_pool & pool, uint64_t offset = 0, uint64_t size = reader_base::nosize, size_t max_buffers = 1) override;
372  virtual std::unique_ptr<reader_factory> clone() const override;
373 
374  virtual bool seekable() const override { return true; }
375 
376  virtual uint64_t size() const override { return data_.size(); }
377 
378 private:
379  std::string const data_;
380 };
381 
382 }
383 #endif
Factory for.
Definition: reader.hpp:266
virtual bool do_seek(scoped_lock &)
Definition: reader.hpp:94
virtual uint64_t size() const
Size of the reader. If the size is indetermined, nosize is returned.
Definition: reader.hpp:45
A simple scoped lock.
Definition: mutex.hpp:116
Definition: reader.hpp:290
Definition: event_handler.hpp:60
Base class for all readers.
Definition: reader.hpp:26
Waitable condition variable.
Definition: mutex.hpp:233
Definition: aio.hpp:202
Definition: aio.hpp:68
Handle for asynchronous tasks.
Definition: thread_pool.hpp:24
Buffer management and wait machinery for asynchronous I/O.
Represents a point of time in wallclock, tracking the timestamps accuracy/precision.
Definition: time.hpp:40
virtual size_t min_buffer_usage() const
The reader requires at least this many buffers.
Definition: reader.hpp:166
virtual bool multiple_buffer_usage() const
Whether the reader can benefit from multiple buffers.
Definition: reader.hpp:173
A buffer pool for use with async readers/writers.
Definition: aio.hpp:106
String reader, keeps a copy of the string.
Definition: reader.hpp:338
virtual bool multiple_buffer_usage() const override
Whether the reader can benefit from multiple buffers.
Definition: reader.hpp:279
virtual datetime mtime() const
Last modification time, might be indetermined.
Definition: reader.hpp:48
Factory for.
Definition: reader.hpp:359
A reader factory.
Definition: reader.hpp:125
The namespace used by libfilezilla.
Definition: apply.hpp:17
Base class for threaded readers.
Definition: reader.hpp:218
Lean class for file access.
Definition: file.hpp:28
File reader.
Definition: reader.hpp:237
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:63
Holder for reader factories.
Definition: reader.hpp:185
Definition: reader.hpp:314
reader_base(std::wstring &&name, aio_buffer_pool &pool, size_t max_buffers) noexcept
Constructs a reader.
Definition: reader.hpp:74
Operationf failed.