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(aio_waiter & h);
61 std::pair<aio_result, buffer_lease> get_buffer(event_handler & h);
62
63 bool error() const;
64
65protected:
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
120{
121public:
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
171protected:
172 reader_factory() = default;
173 reader_factory(reader_factory const&) = default;
174
175 std::wstring const name_;
176};
177
180{
181public:
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);
186
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
205private:
206 std::unique_ptr<reader_factory> impl_;
207};
208
209class thread_pool;
210
213{
214public:
215 using reader_base::reader_base;
216
217protected:
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
232{
233public:
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
242
243 virtual bool seekable() const override;
244
245private:
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
259{
260public:
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; }
274private:
275 thread_pool & thread_pool_;
276};
277
283{
284public:
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
291private:
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
307{
308public:
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
325private:
326 std::string_view const view_;
327};
328
331{
332public:
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
340private:
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
352{
353public:
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
370private:
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
std::pair< aio_result, buffer_lease > get_buffer(aio_waiter &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.
Holder for reader factories.
Definition reader.hpp:180
A reader factory.
Definition reader.hpp:120
virtual size_t min_buffer_usage() const
The reader requires at least this many buffers.
Definition reader.hpp:160
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:167
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: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
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.