C++20 Port #5
							
								
								
									
										137
									
								
								source/core/files.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								source/core/files.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | ||||
| export module core.files; | ||||
| 
 | ||||
| import core; | ||||
| 
 | ||||
| export namespace core { | ||||
| 	/**
 | ||||
| 	 * Platform-generalized identifier for a resource in a [file_store]. | ||||
| 	 */ | ||||
| 	struct path { | ||||
| 		/**
 | ||||
| 		 * Maximum path length. | ||||
| 		 */ | ||||
| 		static usize const max = u8_max; | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Common path component separator. | ||||
| 		 */ | ||||
| 		static char const seperator = '/'; | ||||
| 
 | ||||
| 		constexpr path() : buffer{0} { | ||||
| 			this->buffer[max] = max; | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Returns the base pointer of the path name. | ||||
| 		 */ | ||||
| 		char const * begin() const { | ||||
| 			return reinterpret_cast<char const *>(this->buffer); | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Returns the number of bytes composing the path. | ||||
| 		 */ | ||||
| 		constexpr usize byte_size() const { | ||||
| 			return max - this->buffer[max]; | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Compares the path to `that`, returning the difference between the two paths or `0` if | ||||
| 		 * they are identical. | ||||
| 		 */ | ||||
| 		constexpr size compare(path const & that) const { | ||||
| 			return core::compare(slice{this->begin(), this->end()}.as_bytes(), | ||||
| 				slice{that.begin(), that.end()}.as_bytes()); | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Returns the tail pointer of the path name. | ||||
| 		 */ | ||||
| 		char const * end() const { | ||||
| 			return reinterpret_cast<char const *>(this->buffer) + this->byte_size(); | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Tests the path against `that` for equality, returning `true` if they are identical, | ||||
| 		 * otherwise `false`. | ||||
| 		 */ | ||||
| 		constexpr bool equals(path const & that) const { | ||||
| 			return core::equals(slice{this->begin(), this->end()}.as_bytes(), | ||||
| 				slice{that.begin(), that.end()}.as_bytes()); | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Returns the path hash code. | ||||
| 		 * | ||||
| 		 * *Note:* the returned hash code is not guaranteed to be unique. | ||||
| 		 */ | ||||
| 		constexpr u64 hash() const { | ||||
| 			return core::hash(slice{this->begin(), this->end()}.as_bytes()); | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Returns a new [path] composed of the current path joined with `text`. | ||||
| 		 * | ||||
| 		 * *Note:* should the new path exceed [max] bytes in size, an empty [path] is returned instead. | ||||
| 		 */ | ||||
| 		constexpr path joined(slice<char const> const & text) const { | ||||
| 			if (text.length > this->buffer[max]) return path{}; | ||||
| 
 | ||||
| 			path joined_path = *this; | ||||
| 
 | ||||
| 			for (char const c : text) { | ||||
| 				joined_path.buffer[joined_path.byte_size()] = c; | ||||
| 				joined_path.buffer[max] -= 1; | ||||
| 			} | ||||
| 
 | ||||
| 			return joined_path; | ||||
| 		} | ||||
| 
 | ||||
| 		private: | ||||
| 		u8 buffer[max + 1]; | ||||
| 	}; | ||||
| 
 | ||||
| 	/**
 | ||||
| 	 * Platform-generalized file system interface. | ||||
| 	 */ | ||||
| 	struct fs { | ||||
| 		/**
 | ||||
| 		 * The result from a file access operation. | ||||
| 		 * | ||||
| 		 * [file_result::ok] indicates a successful file access operation. | ||||
| 		 * | ||||
| 		 * [file_result::not_found] signals that the file was not found. | ||||
| 		 * | ||||
| 		 * [file_result::access_denied] warns that the file was found but cannot be opened through | ||||
| 		 * the file system interface. The most common scenario for this error is a lack of required | ||||
| 		 * file permissions. | ||||
| 		 */ | ||||
| 		enum class [[nodiscard]] access_result { | ||||
| 			ok, | ||||
| 			not_found, | ||||
| 			access_denied, | ||||
| 		}; | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Attempts to read the file in the file system located at `file_path` relative, calling | ||||
| 		 * `then` if it was successfully opened for reading. | ||||
| 		 * | ||||
| 		 * The returned [access_result] indicates whether the operation was successful or not. | ||||
| 		 * | ||||
| 		 * Once `then` returns, access to the file is closed automatically. | ||||
| 		 */ | ||||
| 		virtual access_result read_file(path const & file_path, | ||||
| 			callable<void(readable const &)> const & then) = 0; | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * Attempts to write the file in the file system located at `file_path` relative, calling | ||||
| 		 * `then` if it was successfully opened for writing. | ||||
| 		 * | ||||
| 		 * The returned [access_result] indicates whether the operation was successful or not. | ||||
| 		 * | ||||
| 		 * Once `then` returns, access to the file is closed automatically. | ||||
| 		 */ | ||||
| 		virtual access_result write_file(path const & file_path, | ||||
| 			callable<void(writable const &)> const & then) = 0; | ||||
| 	}; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user