| 
									
										
										
										
											2016-01-17 14:20:02 -08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. | 
					
						
							| 
									
										
										
										
											2016-08-26 08:11:24 +02:00
										 |  |  |  * Copyright (C) 2016 Furrtek | 
					
						
							| 
									
										
										
										
											2016-01-17 14:20:02 -08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This file is part of PortaPack. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; either version 2, or (at your option) | 
					
						
							|  |  |  |  * any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; see the file COPYING.  If not, write to | 
					
						
							|  |  |  |  * the Free Software Foundation, Inc., 51 Franklin Street, | 
					
						
							|  |  |  |  * Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef __FILE_H__
 | 
					
						
							|  |  |  | #define __FILE_H__
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ff.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 14:01:44 -07:00
										 |  |  | #include "optional.hpp"
 | 
					
						
							| 
									
										
										
										
											2023-06-11 11:47:13 -07:00
										 |  |  | #include "result.hpp"
 | 
					
						
							| 
									
										
										
										
											2016-05-16 14:01:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 14:20:02 -08:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2016-05-11 10:58:57 -07:00
										 |  |  | #include <cstdint>
 | 
					
						
							| 
									
										
										
										
											2016-01-17 14:20:02 -08:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2016-02-18 21:34:03 -08:00
										 |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | #include <memory>
 | 
					
						
							|  |  |  | #include <iterator>
 | 
					
						
							| 
									
										
										
										
											2016-08-26 08:11:24 +02:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2016-01-17 14:20:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | namespace std { | 
					
						
							|  |  |  | namespace filesystem { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 18:19:28 -07:00
										 |  |  | struct filesystem_error { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     constexpr filesystem_error() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constexpr filesystem_error( | 
					
						
							|  |  |  |         FRESULT fatfs_error) | 
					
						
							|  |  |  |         : err{fatfs_error} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constexpr filesystem_error( | 
					
						
							|  |  |  |         unsigned int other_error) | 
					
						
							|  |  |  |         : err{other_error} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t code() const { | 
					
						
							|  |  |  |         return err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string what() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool ok() const { | 
					
						
							|  |  |  |         return err == FR_OK; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    private: | 
					
						
							|  |  |  |     uint32_t err{FR_OK}; | 
					
						
							| 
									
										
										
										
											2016-05-12 18:19:28 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-08 12:57:34 -07:00
										 |  |  | struct path { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     using string_type = std::u16string; | 
					
						
							|  |  |  |     using value_type = string_type::value_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static constexpr value_type preferred_separator = u'/'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path() | 
					
						
							|  |  |  |         : _s{} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(const path& p) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : _s{p._s} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(path&& p) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : _s{std::move(p._s)} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <class Source> | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(const Source& source) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : path{std::begin(source), std::end(source)} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <class InputIt> | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(InputIt first, | 
					
						
							|  |  |  |          InputIt last) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : _s{first, last} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(const char16_t* const s) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : _s{s} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     path(const TCHAR* const s) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |         : _s{reinterpret_cast<const std::filesystem::path::value_type*>(s)} { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& operator=(const path& p) { | 
					
						
							|  |  |  |         _s = p._s; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& operator=(path&& p) { | 
					
						
							|  |  |  |         _s = std::move(p._s); | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path parent_path() const; | 
					
						
							|  |  |  |     path extension() const; | 
					
						
							|  |  |  |     path filename() const; | 
					
						
							|  |  |  |     path stem() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool empty() const { | 
					
						
							|  |  |  |         return _s.empty(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const value_type* c_str() const { | 
					
						
							|  |  |  |         return native().c_str(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     const TCHAR* tchar() const { | 
					
						
							|  |  |  |         return reinterpret_cast<const TCHAR*>(native().c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     const string_type& native() const { | 
					
						
							|  |  |  |         return _s; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string string() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& operator+=(const path& p) { | 
					
						
							|  |  |  |         _s += p._s; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& operator+=(const string_type& str) { | 
					
						
							|  |  |  |         _s += str; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& operator/=(const path& p) { | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |         if (_s.back() != preferred_separator && p._s.front() != preferred_separator) | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |             _s += preferred_separator; | 
					
						
							|  |  |  |         _s += p._s; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path& replace_extension(const path& replacement = path()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    private: | 
					
						
							|  |  |  |     string_type _s; | 
					
						
							| 
									
										
										
										
											2016-05-12 18:19:28 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-30 22:42:28 -07:00
										 |  |  | bool operator==(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2023-05-03 13:13:15 -07:00
										 |  |  | bool operator!=(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2016-10-01 10:44:11 -07:00
										 |  |  | bool operator<(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2016-09-08 12:57:34 -07:00
										 |  |  | bool operator>(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2023-05-01 09:25:32 -07:00
										 |  |  | path operator+(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2023-04-30 22:42:28 -07:00
										 |  |  | path operator/(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2016-09-08 12:57:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-28 10:02:06 -07:00
										 |  |  | /* Case insensitive path equality on underlying "native" string. */ | 
					
						
							|  |  |  | bool path_iequal(const path& lhs, const path& rhs); | 
					
						
							| 
									
										
										
										
											2023-07-22 02:20:56 -05:00
										 |  |  | bool is_cxx_capture_file(const path& filename); | 
					
						
							|  |  |  | uint8_t capture_file_sample_size(const path& filename); | 
					
						
							| 
									
										
										
										
											2023-06-28 10:02:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | using file_status = BYTE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 18:06:39 -07:00
										 |  |  | static_assert(sizeof(path::value_type) == 2, "sizeof(std::filesystem::path::value_type) != 2"); | 
					
						
							|  |  |  | static_assert(sizeof(path::value_type) == sizeof(TCHAR), "FatFs TCHAR size != std::filesystem::path::value_type"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-11 10:58:57 -07:00
										 |  |  | struct space_info { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     static_assert(sizeof(std::uintmax_t) >= 8, "std::uintmax_t too small (<uint64_t)"); | 
					
						
							| 
									
										
										
										
											2016-05-11 10:58:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     std::uintmax_t capacity; | 
					
						
							|  |  |  |     std::uintmax_t free; | 
					
						
							|  |  |  |     std::uintmax_t available; | 
					
						
							| 
									
										
										
										
											2016-05-11 10:58:57 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | struct directory_entry : public FILINFO { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     file_status status() const { | 
					
						
							|  |  |  |         return fattrib; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     std::uintmax_t size() const { | 
					
						
							|  |  |  |         return fsize; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2016-10-01 10:44:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     const std::filesystem::path path() const noexcept { return {fname}; }; | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class directory_iterator { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     struct Impl { | 
					
						
							|  |  |  |         DIR dir; | 
					
						
							|  |  |  |         directory_entry filinfo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ~Impl() { | 
					
						
							|  |  |  |             f_closedir(&dir); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::shared_ptr<Impl> impl{}; | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     std::filesystem::path path_{}; | 
					
						
							|  |  |  |     std::filesystem::path wild_{}; | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | 
 | 
					
						
							|  |  |  |     friend bool operator!=(const directory_iterator& lhs, const directory_iterator& rhs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    public: | 
					
						
							|  |  |  |     using difference_type = std::ptrdiff_t; | 
					
						
							|  |  |  |     using value_type = directory_entry; | 
					
						
							|  |  |  |     using pointer = const directory_entry*; | 
					
						
							|  |  |  |     using reference = const directory_entry&; | 
					
						
							|  |  |  |     using iterator_category = std::input_iterator_tag; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     directory_iterator() noexcept {}; | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  |     directory_iterator(const std::filesystem::path& path, | 
					
						
							|  |  |  |                        const std::filesystem::path& wild); | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ~directory_iterator() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     directory_iterator& operator++(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reference operator*() const { | 
					
						
							|  |  |  |         // TODO: Exception or assert if impl == nullptr.
 | 
					
						
							|  |  |  |         return impl->filinfo; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | inline const directory_iterator& begin(const directory_iterator& iter) noexcept { | 
					
						
							|  |  |  |     return iter; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | inline directory_iterator end(const directory_iterator&) noexcept { | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | inline bool operator!=(const directory_iterator& lhs, const directory_iterator& rhs) { | 
					
						
							|  |  |  |     return lhs.impl != rhs.impl; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 10:44:11 -07:00
										 |  |  | bool is_directory(const file_status s); | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | bool is_regular_file(const file_status s); | 
					
						
							| 
									
										
										
										
											2023-05-03 13:13:15 -07:00
										 |  |  | bool file_exists(const path& file_path); | 
					
						
							|  |  |  | bool is_directory(const path& file_path); | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-11 10:58:57 -07:00
										 |  |  | space_info space(const path& p); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-20 09:56:35 -07:00
										 |  |  | } /* namespace filesystem */ | 
					
						
							|  |  |  | } /* namespace std */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-09 21:12:19 +00:00
										 |  |  | struct FATTimestamp { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     uint16_t FAT_date; | 
					
						
							|  |  |  |     uint16_t FAT_time; | 
					
						
							| 
									
										
										
										
											2018-01-09 21:12:19 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-11 13:46:38 -07:00
										 |  |  | std::filesystem::filesystem_error delete_file(const std::filesystem::path& file_path); | 
					
						
							|  |  |  | std::filesystem::filesystem_error rename_file(const std::filesystem::path& file_path, const std::filesystem::path& new_name); | 
					
						
							| 
									
										
										
										
											2023-05-10 09:51:09 -07:00
										 |  |  | std::filesystem::filesystem_error copy_file(const std::filesystem::path& file_path, const std::filesystem::path& dest_path); | 
					
						
							| 
									
										
										
										
											2023-06-11 11:47:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-09 21:12:19 +00:00
										 |  |  | FATTimestamp file_created_date(const std::filesystem::path& file_path); | 
					
						
							| 
									
										
										
										
											2023-05-11 13:46:38 -07:00
										 |  |  | std::filesystem::filesystem_error make_new_file(const std::filesystem::path& file_path); | 
					
						
							|  |  |  | std::filesystem::filesystem_error make_new_directory(const std::filesystem::path& dir_path); | 
					
						
							| 
									
										
										
										
											2023-05-12 11:08:07 -07:00
										 |  |  | std::filesystem::filesystem_error ensure_directory(const std::filesystem::path& dir_path); | 
					
						
							| 
									
										
										
										
											2016-08-21 18:06:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:48:36 -07:00
										 |  |  | template <typename TCallback> | 
					
						
							|  |  |  | void scan_root_files(const std::filesystem::path& directory, const std::filesystem::path& extension, const TCallback& fn) { | 
					
						
							|  |  |  |     for (const auto& entry : std::filesystem::directory_iterator(directory, extension)) { | 
					
						
							|  |  |  |         if (std::filesystem::is_regular_file(entry.status())) | 
					
						
							|  |  |  |             fn(entry.path()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-07 00:58:25 +00:00
										 |  |  | std::vector<std::filesystem::path> scan_root_files(const std::filesystem::path& directory, const std::filesystem::path& extension); | 
					
						
							|  |  |  | std::vector<std::filesystem::path> scan_root_directories(const std::filesystem::path& directory); | 
					
						
							| 
									
										
										
										
											2023-05-01 09:25:32 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 11:08:07 -07:00
										 |  |  | /* Gets an auto incrementing filename stem.
 | 
					
						
							|  |  |  |  * Pattern should be like "FOO_???.txt" where ??? will be replaced by digits. | 
					
						
							|  |  |  |  * Pattern may also contain a folder path like "LOGS/FOO_???.txt". | 
					
						
							|  |  |  |  * Pattern '?' must be contiguous (bad: "FOO?_??") | 
					
						
							|  |  |  |  * Returns empty path if a filename could not be created. */ | 
					
						
							|  |  |  | std::filesystem::path next_filename_matching_pattern(const std::filesystem::path& pattern); | 
					
						
							| 
									
										
										
										
											2017-12-07 00:58:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-06 09:34:45 -08:00
										 |  |  | /* Values added to FatFs FRESULT enum, values outside the FRESULT data type */ | 
					
						
							|  |  |  | static_assert(sizeof(FIL::err) == 1, "FatFs FIL::err size not expected."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Dangerous to expose these, as FatFs native error values are byte-sized. However,
 | 
					
						
							| 
									
										
										
										
											2017-06-23 08:40:22 +01:00
										 |  |  |  * my filesystem_error implementation is fine with it. */ | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | #define FR_DISK_FULL (0x100)
 | 
					
						
							|  |  |  | #define FR_EOF (0x101)
 | 
					
						
							|  |  |  | #define FR_BAD_SEEK (0x102)
 | 
					
						
							|  |  |  | #define FR_UNEXPECTED (0x103)
 | 
					
						
							| 
									
										
										
										
											2016-12-06 09:34:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 21:44:37 -07:00
										 |  |  | class File { | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |    public: | 
					
						
							|  |  |  |     using Size = uint64_t; | 
					
						
							|  |  |  |     using Offset = uint64_t; | 
					
						
							|  |  |  |     using Timestamp = uint32_t; | 
					
						
							|  |  |  |     using Error = std::filesystem::filesystem_error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename T> | 
					
						
							| 
									
										
										
										
											2023-06-11 11:47:13 -07:00
										 |  |  |     using Result = Result<T, Error>; | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | 
 | 
					
						
							|  |  |  |     File(){}; | 
					
						
							|  |  |  |     ~File(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 08:44:21 -07:00
										 |  |  |     File(File&& other) { | 
					
						
							|  |  |  |         std::swap(f, other.f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     File& operator=(File&& other) { | 
					
						
							|  |  |  |         std::swap(f, other.f); | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-05-22 13:08:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     /* Prevent copies */ | 
					
						
							|  |  |  |     File(const File&) = delete; | 
					
						
							|  |  |  |     File& operator=(const File&) = delete; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO: Return Result<>.
 | 
					
						
							| 
									
										
										
										
											2023-07-17 11:43:37 -07:00
										 |  |  |     Optional<Error> open(const std::filesystem::path& filename, bool read_only = true, bool create = false); | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |     Optional<Error> append(const std::filesystem::path& filename); | 
					
						
							|  |  |  |     Optional<Error> create(const std::filesystem::path& filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 08:44:21 -07:00
										 |  |  |     Result<Size> read(void* data, const Size bytes_to_read); | 
					
						
							|  |  |  |     Result<Size> write(const void* data, Size bytes_to_write); | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-03 19:26:39 -07:00
										 |  |  |     Offset tell() const; | 
					
						
							| 
									
										
										
										
											2023-05-28 08:44:21 -07:00
										 |  |  |     Result<Offset> seek(uint64_t Offset); | 
					
						
							| 
									
										
										
										
											2023-06-01 15:45:55 -07:00
										 |  |  |     Result<Offset> truncate(); | 
					
						
							| 
									
										
										
										
											2023-05-22 13:08:59 -07:00
										 |  |  |     Size size() const; | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template <size_t N> | 
					
						
							|  |  |  |     Result<Size> write(const std::array<uint8_t, N>& data) { | 
					
						
							|  |  |  |         return write(data.data(), N); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Optional<Error> write_line(const std::string& s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO: Return Result<>.
 | 
					
						
							|  |  |  |     Optional<Error> sync(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-11 11:47:13 -07:00
										 |  |  |     /* Reads the entire file contents to a string.
 | 
					
						
							|  |  |  |      * NB: This will likely fail for files larger than ~10kB. */ | 
					
						
							|  |  |  |     static Result<std::string> read_file(const std::filesystem::path& filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  |    private: | 
					
						
							|  |  |  |     FIL f{}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Optional<Error> open_fatfs(const std::filesystem::path& filename, BYTE mode); | 
					
						
							| 
									
										
										
										
											2016-05-16 14:01:44 -07:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-05-12 21:44:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 08:16:05 +12:00
										 |  |  | #endif /*__FILE_H__*/
 |