libfilezilla
Loading...
Searching...
No Matches
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
16namespace fz {
17
27{
28public:
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
64protected:
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
126{
127public:
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
177protected:
178 reader_factory() = default;
179 reader_factory(reader_factory const&) = default;
180
181 std::wstring const name_;
182};
183
186{
187public:
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);
192
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
211private:
212 std::unique_ptr<reader_factory> impl_;
213};
214
215class thread_pool;
216
219{
220public:
221 using reader_base::reader_base;
222
223protected:
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
238{
239public:
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
248
249 virtual bool seekable() const override;
250
251private:
254
255 virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
256
257 void FZ_PRIVATE_SYMBOL entry();
258
259 file file_;
260 thread_pool & thread_pool_;
261};
262
265{
266public:
267 file_reader_factory(std::wstring const& file, thread_pool & tpool);
268
269 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;
270 virtual std::unique_ptr<reader_factory> clone() const override;
271
272 virtual bool seekable() const override { return true; }
273
274 virtual uint64_t size() const override;
275 virtual datetime mtime() const override;
276
277 virtual bool multiple_buffer_usage() const override { return true; }
278
279 virtual size_t preferred_buffer_count() const override { return 4; }
280private:
281 thread_pool & thread_pool_;
282};
283
289{
290public:
291 view_reader(std::wstring && name, aio_buffer_pool & pool, std::string_view data) noexcept;
292
293 virtual ~view_reader() noexcept;
294
295 virtual bool seekable() const override { return true; }
296
297private:
298 virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
299 virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
300 virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
301
302 virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
303
304 std::string_view const view_;
305};
306
313{
314public:
315 view_reader_factory(std::wstring && name, std::string_view const& view)
316 : reader_factory(std::move(name))
317 , view_(view)
318 {}
319 view_reader_factory(std::wstring const& name, std::string_view const& view)
320 : reader_factory(name)
321 , view_(view)
322 {}
323
324 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;
325 virtual std::unique_ptr<reader_factory> clone() const override;
326
327 virtual bool seekable() const override { return true; }
328
329 virtual uint64_t size() const override { return view_.size(); }
330
331private:
332 std::string_view const view_;
333};
334
337{
338public:
339 string_reader(std::wstring && name, aio_buffer_pool & pool, std::string const& data) noexcept;
340 string_reader(std::wstring && name, aio_buffer_pool & pool, std::string && data) noexcept;
341
342 virtual ~string_reader() noexcept;
343
344 virtual bool seekable() const override { return true; }
345
346private:
347 virtual std::pair<aio_result, buffer_lease> FZ_PRIVATE_SYMBOL do_get_buffer(scoped_lock & l) override;
348 virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
349 virtual bool FZ_PRIVATE_SYMBOL do_seek(scoped_lock & l) override;
350
351 virtual void FZ_PRIVATE_SYMBOL do_on_buffer_availability(scoped_lock & l, aio_waitable const* w) override;
352
353 std::string const data_;
354};
355
358{
359public:
360 string_reader_factory(std::wstring const& name, std::string const& data)
361 : reader_factory(name)
362 , data_(data)
363 {}
364 string_reader_factory(std::wstring && name, std::string && data)
365 : reader_factory(std::move(name))
366 , data_(std::move(data))
367 {}
368
369 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;
370 virtual std::unique_ptr<reader_factory> clone() const override;
371
372 virtual bool seekable() const override { return true; }
373
374 virtual uint64_t size() const override { return data_.size(); }
375
376private:
377 std::string const data_;
378};
379
380}
381#endif
Buffer management and wait machinery for asynchronous I/O.
Definition aio.hpp:203
A buffer pool for use with async readers/writers.
Definition aio.hpp:107
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
Common base class for all events.
Definition event.hpp:23
Simple handler for asynchronous event processing.
Definition event_handler.hpp:55
Factory for.
Definition reader.hpp:265
virtual bool multiple_buffer_usage() const override
Whether the reader can benefit from multiple buffers.
Definition reader.hpp:277
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: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
Constructs file reader.
Lean class for file access.
Definition file.hpp:29
Abstract interface for logging strings.
Definition logger.hpp:51
Lean replacement for std::(recursive_)mutex.
Definition mutex.hpp:52
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:74
bool rewind()
Only seekable readers can be rewound.
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
virtual datetime mtime() const
Last modification time, might be indetermined.
Definition reader.hpp:48
std::pair< aio_result, buffer_lease > get_buffer(event_handler &h)
Gets the next buffer with data from the reader.
bool seek(uint64_t offset, uint64_t size=nosize)
If seek fails, the reader is in an undefined state and must be closed.
virtual void operator()(event_base const &) override
Called by the event loop in the worker thread with the event to process.
Holder for reader factories.
Definition reader.hpp:186
A reader factory.
Definition reader.hpp:126
virtual size_t min_buffer_usage() const
The reader requires at least this many buffers.
Definition reader.hpp:166
virtual std::unique_ptr< reader_factory > clone() const =0
Clones the factory.
virtual bool multiple_buffer_usage() const
Whether the reader can benefit from multiple buffers.
Definition reader.hpp:173
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.
A simple scoped lock.
Definition mutex.hpp:93
Factory for.
Definition reader.hpp:358
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:337
A dumb thread-pool for asynchronous tasks.
Definition thread_pool.hpp:64
Base class for threaded readers.
Definition reader.hpp:219
Definition reader.hpp:313
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:289
File handling.
The namespace used by libfilezilla.
Definition apply.hpp:17
@ error
Operationf failed.
bool dispatch(event_base const &ev, F &&f)
Dispatch for simple_event<> based events to simple functors.
Definition event_handler.hpp:199
Declares thread_pool and async_task.