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, protected aio_waiter, public aio_waitable
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(aio_waiter & h);
61  std::pair<aio_result, buffer_lease> get_buffer(event_handler & h);
62 
63  bool error() const;
64 
65 protected:
75  reader_base(std::wstring && name, aio_buffer_pool & pool, size_t max_buffers) noexcept
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  : buffer_pool_(pool)
84  , logger_(pool.logger())
85  , name_(name)
86  , max_buffers_(max_buffers ? max_buffers : 1)
87  {}
88 
89  virtual std::pair<aio_result, buffer_lease> do_get_buffer(scoped_lock & l) = 0;
90 
93  virtual bool do_seek(scoped_lock &) {
94  return false;
95  }
96 
97  virtual void do_close(scoped_lock &) {}
98 
99  mutable mutex mtx_;
100  aio_buffer_pool & buffer_pool_;
101  logger_interface & logger_;
102 
103  std::wstring const name_;
104 
105  size_t const max_buffers_{};
106  std::list<buffer_lease> buffers_;
107 
108  uint64_t size_{nosize};
109  uint64_t max_size_{nosize};
110  uint64_t start_offset_{nosize};
111  uint64_t remaining_{nosize};
112 
113  bool get_buffer_called_{};
114  bool error_{};
115  bool eof_{};
116 };
117 
119 class FZ_PUBLIC_SYMBOL reader_factory
120 {
121 public:
122  explicit reader_factory(std::wstring const& name)
123  : name_(name)
124  {}
125  explicit reader_factory(std::wstring && name)
126  : name_(std::move(name))
127  {}
128 
129  virtual ~reader_factory() noexcept = default;
130 
132  virtual std::unique_ptr<reader_factory> clone() const = 0;
133 
145  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;
146 
147  virtual bool seekable() const { return false; }
148 
149  std::wstring name() const { return name_; }
150 
151  virtual uint64_t size() const { return reader_base::nosize; }
152  virtual datetime mtime() const { return datetime(); }
153 
160  virtual size_t min_buffer_usage() const { return 1; }
161 
167  virtual bool multiple_buffer_usage() const { return false; }
168 
169  virtual size_t preferred_buffer_count() const { return 1; }
170 
171 protected:
172  reader_factory() = default;
173  reader_factory(reader_factory const&) = default;
174 
175  std::wstring const name_;
176 };
177 
179 class FZ_PUBLIC_SYMBOL reader_factory_holder final
180 {
181 public:
182  reader_factory_holder() = default;
183  reader_factory_holder(std::unique_ptr<reader_factory> && factory);
184  reader_factory_holder(std::unique_ptr<reader_factory> const& factory);
185  reader_factory_holder(reader_factory const& factory);
186 
188  reader_factory_holder& operator=(reader_factory_holder const& op);
189 
191  reader_factory_holder& operator=(reader_factory_holder && op) noexcept;
192  reader_factory_holder& operator=(std::unique_ptr<reader_factory> && factory);
193 
194  reader_factory const* operator->() const { return impl_.get(); }
195  reader_factory* operator->() { return impl_.get(); }
196  reader_factory const& operator*() const { return *impl_; }
197  reader_factory & operator*() { return *impl_; }
198 
199  explicit operator bool() const { return impl_.operator bool(); }
200 
201  std::wstring name() const { return impl_ ? impl_->name() : std::wstring(); }
202  datetime mtime() const { return impl_ ? impl_->mtime() : datetime(); }
203  uint64_t size() const { return impl_ ? impl_->size() : aio_base::nosize; }
204 
205 private:
206  std::unique_ptr<reader_factory> impl_;
207 };
208 
209 class thread_pool;
210 
212 class FZ_PUBLIC_SYMBOL threaded_reader : public reader_base
213 {
214 public:
215  using reader_base::reader_base;
216 
217 protected:
218  virtual std::pair<aio_result, buffer_lease> do_get_buffer(scoped_lock & l) override;
219 
220  void wakeup(scoped_lock & l) {
221  cond_.signal(l);
222  }
223 
224  condition cond_;
225  async_task task_;
226 
227  bool quit_{};
228 };
229 
231 class FZ_PUBLIC_SYMBOL file_reader final : public threaded_reader
232 {
233 public:
238  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;
239  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;
240 
241  virtual ~file_reader() noexcept;
242 
243  virtual bool seekable() const override;
244 
245 private:
246  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
247  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
248 
249  virtual void FZ_PRIVATE_SYMBOL on_buffer_availability(aio_waitable const* w) override;
250 
251  void FZ_PRIVATE_SYMBOL entry();
252 
253  file file_;
254  thread_pool & thread_pool_;
255 };
256 
258 class FZ_PUBLIC_SYMBOL file_reader_factory final : public reader_factory
259 {
260 public:
261  file_reader_factory(std::wstring const& file, thread_pool & tpool);
262 
263  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;
264  virtual std::unique_ptr<reader_factory> clone() const override;
265 
266  virtual bool seekable() const override { return true; }
267 
268  virtual uint64_t size() const override;
269  virtual datetime mtime() const override;
270 
271  virtual bool multiple_buffer_usage() const override { return true; }
272 
273  virtual size_t preferred_buffer_count() const override { return 4; }
274 private:
275  thread_pool & thread_pool_;
276 };
277 
282 class FZ_PUBLIC_SYMBOL view_reader final : public reader_base
283 {
284 public:
285  view_reader(std::wstring && name, aio_buffer_pool & pool, std::string_view data) noexcept;
286 
287  virtual ~view_reader() noexcept;
288 
289  virtual bool seekable() const override { return true; }
290 
291 private:
292  virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
293  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
294  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
295 
296  virtual void FZ_PRIVATE_SYMBOL on_buffer_availability(aio_waitable const* w) override;
297 
298  std::string_view const view_;
299 };
300 
306 class FZ_PUBLIC_SYMBOL view_reader_factory final : public reader_factory
307 {
308 public:
309  view_reader_factory(std::wstring && name, std::string_view const& view)
310  : reader_factory(std::move(name))
311  , view_(view)
312  {}
313  view_reader_factory(std::wstring const& name, std::string_view const& view)
314  : reader_factory(name)
315  , view_(view)
316  {}
317 
318  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;
319  virtual std::unique_ptr<reader_factory> clone() const override;
320 
321  virtual bool seekable() const override { return true; }
322 
323  virtual uint64_t size() const override { return view_.size(); }
324 
325 private:
326  std::string_view const view_;
327 };
328 
330 class FZ_PUBLIC_SYMBOL string_reader final : public reader_base
331 {
332 public:
333  string_reader(std::wstring && name, aio_buffer_pool & pool, std::string const& data) noexcept;
334  string_reader(std::wstring && name, aio_buffer_pool & pool, std::string && data) noexcept;
335 
336  virtual ~string_reader() noexcept;
337 
338  virtual bool seekable() const override { return true; }
339 
340 private:
341  virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
342  virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
343  virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
344 
345  virtual void FZ_PRIVATE_SYMBOL on_buffer_availability(aio_waitable const* w) override;
346 
347  std::string const data_;
348 };
349 
351 class FZ_PUBLIC_SYMBOL string_reader_factory final : public reader_factory
352 {
353 public:
354  string_reader_factory(std::wstring const& name, std::string const& data)
355  : reader_factory(name)
356  , data_(data)
357  {}
358  string_reader_factory(std::wstring && name, std::string && data)
359  : reader_factory(std::move(name))
360  , data_(std::move(data))
361  {}
362 
363  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;
364  virtual std::unique_ptr<reader_factory> clone() const override;
365 
366  virtual bool seekable() const override { return true; }
367 
368  virtual uint64_t size() const override { return data_.size(); }
369 
370 private:
371  std::string const data_;
372 };
373 
374 }
375 #endif
Buffer management and wait machinery for asynchronous I/O.
Definition: aio.hpp:226
A buffer pool for use with async readers/writers.
Definition: aio.hpp:132
Definition: aio.hpp:89
Definition: aio.hpp:69
Handle for asynchronous tasks.
Definition: thread_pool.hpp:24
Waitable condition variable.
Definition: mutex.hpp:196
Represents a point of time in wallclock, tracking the timestamps accuracy/precision.
Definition: time.hpp:41
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:55
Factory for.
Definition: reader.hpp:259
virtual bool multiple_buffer_usage() const override
Whether the reader can benefit from multiple buffers.
Definition: reader.hpp: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
Creates a reader.
virtual std::unique_ptr< reader_factory > clone() const override
Clones the factory.
File reader.
Definition: reader.hpp:232
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
Constructs file reader.
Lean class for file access.
Definition: file.hpp:29
Base class for all readers.
Definition: reader.hpp:27
reader_base(std::wstring &&name, aio_buffer_pool &pool, size_t max_buffers) noexcept
Constructs a reader.
Definition: reader.hpp:75
bool rewind()
Only seekable readers can be rewound.
virtual bool do_seek(scoped_lock &)
Definition: reader.hpp:93
virtual uint64_t size() const
Size of the reader. If the size is indetermined, nosize is returned.
Definition: reader.hpp:45
virtual datetime mtime() const
Last modification time, might be indetermined.
Definition: reader.hpp:48
bool seek(uint64_t offset, uint64_t size=nosize)
If seek fails, the reader is in an undefined state and must be closed.
std::pair< aio_result, buffer_lease > get_buffer(aio_waiter &h)
Gets the next buffer with data from the reader.
Holder for reader factories.
Definition: reader.hpp:180
A reader factory.
Definition: reader.hpp:120
virtual std::unique_ptr< reader_factory > clone() const =0
Clones the factory.
virtual size_t min_buffer_usage() const
The reader requires at least this many buffers.
Definition: reader.hpp:160
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
Creates a reader.
virtual bool multiple_buffer_usage() const
Whether the reader can benefit from multiple buffers.
Definition: reader.hpp:167
A simple scoped lock.
Definition: mutex.hpp:93
Factory for.
Definition: reader.hpp:352
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
Creates a reader.
virtual std::unique_ptr< reader_factory > clone() const override
Clones the factory.
String reader, keeps a copy of the string.
Definition: reader.hpp:331
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:64
Base class for threaded readers.
Definition: reader.hpp:213
Definition: reader.hpp:307
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
Creates a reader.
virtual std::unique_ptr< reader_factory > clone() const override
Clones the factory.
Definition: reader.hpp:283
The namespace used by libfilezilla.
Definition: apply.hpp:17