19 #ifndef PSTORE_OS_FILE_HPP 20 #define PSTORE_OS_FILE_HPP 28 # define WIN32_LEAN_AND_MEAN 33 #include "pstore/support/array_elements.hpp" 39 class in_memory_mapper;
71 template <
typename RandomGenerator>
75 auto const it = std::find_if (tmpl.rbegin (), tmpl.rend (),
76 [] (
char const c) {
return c !=
'X'; });
79 path.reserve (tmpl.length ());
80 std::copy (tmpl.begin (), it.base (), std::back_inserter (path));
83 auto num_x = std::distance (it.base (), tmpl.end ());
85 static char const alphabet[] =
"abcdefghijklmnopqrstuvwxyz0123456789_";
86 static constexpr
auto length =
87 static_cast<unsigned> (array_elements (alphabet)) - 1U;
88 auto const index = rng (length);
89 PSTORE_ASSERT (index >= 0 && index < length);
90 path.push_back (alphabet[index]);
92 PSTORE_ASSERT (path.length () == tmpl.length ());
118 template <
typename W
idthType,
typename Po
inteeType,
typename Function>
119 std::size_t
split (PointeeType * buffer, std::size_t size, Function
const &
function) {
120 PSTORE_ASSERT (buffer !=
nullptr);
122 static_assert (
sizeof (PointeeType) ==
sizeof (std::uint8_t),
123 "PointeeType must be a byte wide type");
124 static_assert (
sizeof (std::size_t) >=
sizeof (WidthType),
125 "WidthType must not be wider than size_t");
126 static std::size_t
const max = std::numeric_limits<WidthType>::max ();
127 std::size_t result = 0;
129 auto const chunk_size =
static_cast<WidthType
> (std::min (max, size));
130 result +=
function (buffer, chunk_size);
131 buffer += chunk_size;
137 template <
typename W
idthType,
typename Function>
138 std::size_t
split (
void *
const buffer, std::size_t
const size,
139 Function
const &
function) {
140 return split<WidthType> (
static_cast<std::uint8_t *
> (buffer), size,
function);
142 template <
typename W
idthType,
typename Function>
143 std::size_t
split (
void const *
const buffer, std::size_t
const size,
144 Function
const &
function) {
145 return split<WidthType> (
static_cast<std::uint8_t
const *
> (buffer), size,
154 system_error (std::error_code code, std::string
const & user_message, std::string path);
155 system_error (std::error_code code, gsl::czstring user_message, std::string path);
165 std::string
const & path ()
const noexcept {
return path_; }
170 template <
typename MessageStringType>
171 std::string message (MessageStringType
const & user_message, std::string
const & path);
185 virtual bool is_open ()
const noexcept = 0;
186 virtual void close () = 0;
191 virtual bool is_writable ()
const noexcept = 0;
197 virtual std::string path ()
const = 0;
204 virtual void seek (std::uint64_t position) = 0;
207 virtual std::uint64_t tell () = 0;
209 virtual std::time_t latest_time ()
const = 0;
218 template <
typename SpanType,
typename =
typename std::enable_if<std::is_standard_layout<
219 typename SpanType::element_type>::value>::type>
221 auto const size = s.size_bytes ();
222 PSTORE_ASSERT (size >= 0);
223 using utype =
typename std::make_unsigned<decltype (size)>::type;
224 return this->read_buffer (s.data (),
static_cast<utype
> (s.size_bytes ()));
228 template <
typename T,
229 typename =
typename std::enable_if<std::is_standard_layout<T>::value>::type>
231 PSTORE_ASSERT (t !=
nullptr);
232 if (this->read_buffer (t,
sizeof (T)) !=
sizeof (T)) {
233 raise (error_code::did_not_read_number_of_bytes_requested);
240 template <
typename SpanType,
typename =
typename std::enable_if<std::is_standard_layout<
241 typename SpanType::element_type>::value>::type>
243 auto const bytes = s.size_bytes ();
244 PSTORE_ASSERT (bytes >= 0);
246 static_cast<typename std::make_unsigned<decltype (bytes)>::type
> (bytes);
247 this->write_buffer (s.data (), ubytes);
251 template <
typename T,
252 typename =
typename std::enable_if<std::is_standard_layout<T>::value>::type>
254 this->write_buffer (&t,
sizeof (T));
259 virtual std::uint64_t size () = 0;
260 virtual void truncate (std::uint64_t size) = 0;
306 virtual bool lock (std::uint64_t offset, std::size_t size,
lock_kind lt,
319 virtual void unlock (std::uint64_t offset, std::size_t size) = 0;
428 file_base * file () noexcept {
return file_; }
429 file_base const * file ()
const noexcept {
return file_; }
432 std::uint64_t
offset () const noexcept {
return offset_; }
434 std::size_t
size () const noexcept {
return size_; }
437 bool is_locked ()
const noexcept {
return locked_; }
444 std::uint64_t offset_ = 0U;
446 std::size_t size_ = 0U;
450 bool locked_ =
false;
454 #ifdef PSTORE_HAVE_IS_TRIVIALLY_COPYABLE 456 std::is_trivially_copyable<decltype (file_)>::value,
457 "file_ is not trivially copyable: use std::move() in move ctor and assign");
459 std::is_trivially_copyable<decltype (offset_)>::value,
460 "offset_ is not trivially copyable: use std::move() in move ctor and assign");
462 std::is_trivially_copyable<decltype (size_)>::value,
463 "size_ is not trivially copyable: use std::move() in move ctor and assign");
465 std::is_trivially_copyable<decltype (kind_)>::value,
466 "kind_ is not trivially copyable: use std::move() in move ctor and assign");
468 std::is_trivially_copyable<decltype (locked_)>::value,
469 "locked_ is not trivially copyable: use std::move() in move ctor and assign");
470 #endif // PSTORE_HAVE_IS_TRIVIALLY_COPYABLE 488 in_memory (std::shared_ptr<void>
const & buffer, std::uint64_t
const length,
489 std::uint64_t
const eof = 0,
bool const writable =
true) noexcept
490 : buffer_ (
std::static_pointer_cast<
std::uint8_t> (buffer))
493 , writable_ (writable) {
495 PSTORE_ASSERT (buffer !=
nullptr);
496 PSTORE_ASSERT (eof <= length);
499 void close ()
override {}
500 bool is_open ()
const noexcept
override {
return true; }
502 std::string path ()
const override;
504 void seek (std::uint64_t position)
override;
505 std::uint64_t
tell ()
override {
return pos_; }
507 std::uint64_t size ()
override {
return eof_; }
508 void truncate (std::uint64_t size)
override;
509 std::time_t latest_time ()
const override;
512 bool lock (std::uint64_t
const , std::size_t
const ,
516 void unlock (std::uint64_t
const , std::size_t
const )
override {}
519 std::shared_ptr<void>
data () {
return buffer_; }
538 std::shared_ptr<std::uint8_t> buffer_;
541 std::uint64_t
const length_;
553 std::uint64_t pos_ = UINT64_C (0);
555 void check_writable ()
const;
609 : path_{std::move (path)} {}
622 void open (
unique, std::string
const & directory);
629 void open (
temporary, std::string
const & directory);
638 static std::string get_temporary_directory ();
640 bool is_open ()
const noexcept
override {
return file_ != invalid_oshandle; }
641 bool is_writable () const noexcept
override {
return is_writable_; }
642 std::string
path ()
const override {
return path_; }
644 void close ()
override;
646 void seek (std::uint64_t position)
override;
647 std::uint64_t tell ()
override;
648 std::uint64_t size ()
override;
649 void truncate (std::uint64_t size)
override;
653 bool rename (std::string
const & new_name);
655 std::time_t latest_time ()
const override;
657 bool lock (std::uint64_t offset, std::size_t size,
lock_kind kind,
659 void unlock (std::uint64_t offset, std::size_t size)
override;
662 using oshandle = HANDLE;
665 static oshandle
const invalid_oshandle;
667 using oshandle = int;
668 static constexpr oshandle invalid_oshandle = -1;
671 oshandle raw_handle () noexcept {
return file_; }
681 static int lock_reg (
int fd,
int cmd,
short type, off_t offset,
short whence,
684 std::string path_ =
"<unknown>";
685 oshandle file_ = invalid_oshandle;
686 bool is_writable_ =
false;
688 #ifdef PSTORE_HAVE_IS_TRIVIALLY_COPYABLE 690 std::is_trivially_copyable<decltype (file_)>::value,
691 "file_ is not trivially copyable: use std::move() in rvalue ref ctor and assign");
692 static_assert (std::is_trivially_copyable<decltype (is_writable_)>::value,
693 "is_writable_ is not trivially copyable: use std::move() in rvalue ref " 695 #endif // PSTORE_HAVE_IS_TRIVIALLY_COPYABLE 700 inline void file_handle::ensure_open () {
701 if (!this->is_open ()) {
702 raise (std::errc::bad_file_descriptor);
706 std::ostream & operator<< (std::ostream & os,
file_handle const & fh);
721 using unlink_proc = std::function<void (std::string const &)>;
741 void release () noexcept { released_ =
true; }
744 explicit deleter_base (std::string path, unlink_proc unlinker);
754 unlink_proc unlinker_;
758 bool released_ =
false;
767 bool exists (std::string
const & path);
772 void unlink (std::string
const & path,
bool allow_noent =
false);
783 #endif // PSTORE_OS_FILE_HPP blocking_mode
Indicates whether the lock() method should block until the lock has been obtained.
Definition: file.hpp:279
present_mode
Controls the behavior of the file_handle constructor when passed a path which does not already exist...
Definition: file.hpp:580
Specifies a read (or shared) lock.
Windows-specific implementations of file APIs.
error_or<T> holds either an instance of T or a std:error.
void unlock(std::uint64_t const, std::size_t const) override
Unlocks the file bytes specified by 'offset' and 'size'.
Definition: file.hpp:516
void write(T const &t)
Writes 't' as a series of raw bytes to the file.
Definition: file.hpp:253
std::uint64_t offset() const noexcept
Definition: file.hpp:432
writable_mode
Controls whether the file_handle constructor produces a read-only or read/write object.
Definition: file.hpp:595
void open(temporary const t)
Creates a temporary file in the system temporary directory.
Definition: file.hpp:625
static std::string get_temporary_directory()
Returns a UTF-8 encoded string representing the temporary directory.
Definition: file_posix.cpp:474
Definition: chunked_sequence.hpp:607
memory_mapper provides an operating system independent interface for memory mapping of files...
Definition: memory_mapper.hpp:157
Definition: error_or.hpp:39
unique is an empty class type used to disambiguate the overloads of creating a file.
Definition: file.hpp:601
std::size_t size() const noexcept
Definition: file.hpp:434
file_base::lock_kind kind() const noexcept
Definition: file.hpp:436
Implements a portable file access API.
Definition: file.hpp:566
temporary is an empty class type used to disambiguate the overloads of creating a file...
Definition: file.hpp:604
void release() noexcept
Releases the file path given to the constructor so that it will not be deleted when the instance is d...
Definition: file.hpp:741
A synchronization object that can be used to protect data in a file from being simultaneously accesse...
Definition: file.hpp:382
create_mode
Definition: file.hpp:571
bool exists(std::string const &path)
Returns true if the file system contains an object at the location given by path. ...
Definition: file_posix.cpp:505
void write_span(SpanType const &s)
Writes instances of a standard-layout type to the file.
Definition: file.hpp:242
Implements an in-memory file which provides a file-like API to a chunk of pre-allocated memory...
Definition: file.hpp:483
lock_kind
Represents the type of file range lock to be obtained.
Definition: file.hpp:285
Definition: nonpod2.cpp:40
bool is_writable() const noexcept override
Return true if the object was created as writable.
Definition: file.hpp:641
bool is_writable() const noexcept override
Return true if the object was created as writable.
Definition: file.hpp:501
void unlink(std::string const &path, bool allow_noent=false)
Deletes the file system object at the location given by path.
Definition: file_posix.cpp:507
bool lock(std::uint64_t const, std::size_t const, lock_kind const, blocking_mode const) override
Obtains a shared-read or exclusive-write lock on the file range specified by the 'offset' and size' p...
Definition: file.hpp:512
std::size_t read_span(SpanType const &s)
Reads instances of a standard-layout type from the file.
Definition: file.hpp:220
Provides an pstore-specific error codes and a suitable error category for them.
std::string path() const override
Returns the name of the file originally associated with this file object.
Definition: file.hpp:642
std::shared_ptr< void > data()
Returns the underlying memory managed by the file object.
Definition: file.hpp:519
std::size_t split(PointeeType *buffer, std::size_t size, Function const &function)
Unfortunately, the Win32 ReadFile() and WriteFile() functions accept size parameters whose type is DW...
Definition: file.hpp:119
std::string name_from_template(std::string const &tmpl, RandomGenerator rng)
The name_from_template() function takes the given file name template and returns a string in which a ...
Definition: file.hpp:72
Definition: memory_mapper.hpp:177
void read(T *const t)
Reads a series of raw bytes from the file as an instance of type T.
Definition: file.hpp:230
std::uint64_t tell() override
Obtains the current value of the position indicator for the file.
Definition: file.hpp:505
A class which, on destruction, will delete a file whose name is passed to the constructor.
Definition: file.hpp:719
An abstract file class. Provides the interface for file access.
Definition: file.hpp:176
Posix-specific implementations of file APIs.