| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- #pragma once
- #include "App.h"
- #include <string>
- namespace gameplay
- {
- struct File;
- enum class FileMode
- {
- READ,
- WRITE,
- READ_WRITE,
- APPEND
- };
- enum class FileWhence
- {
- BEGIN,
- CURRENT,
- END
- };
- enum class FileStreamStatus
- {
- STREAM_OK,
- STREAM_EOF,
- STREAM_ERROR
- };
- enum class DirectoryItemType
- {
- FILE,
- DIRECTORY,
- };
- struct FileInfo
- {
- DirectoryItemType type;
- time_t createTime;
- time_t modTime;
- size_t size;
- bool symlink;
- };
- struct DirectoryInfo : public FileInfo
- {
- const char* path;
- };
- enum class VisitAction : signed char
- {
- STOP = -1,
- SKIP,
- CONTINUE
- };
- /**
- * Defines the file system.
- *
- * Any operation that takes a path can be specified in absolute
- * or relative paths are resolved from the current working directory.
- */
- class GP_API FileSystem
- {
- friend class App;
- friend class Config;
- public:
- /**
- * Changes events for files and directories on the file system.
- */
- enum class ChangeEvent
- {
- CREATED,
- MODIFIED,
- DELETED,
- RENAMED
- };
- /**
- * Gets the application executable file path.
- *
- * @return The application executable file path.
- */
- const char* get_app_executable_path() const;
- /**
- * Gets the application directory path.
- *
- * @return The application directory path.
- */
- const char* get_app_directory_path() const;
- /**
- * Sets the current directory path for the filesystem.
- *
- * @param path The current directory path for the filesystem.
- */
- bool set_current_directory_path(const char* path);
- /**
- * Gets the current directory path for the filesystem.
- *
- * @return The current directory path for the filesystem.
- */
- const char* get_current_directory_path();
- /**
- * Checks if a file or directory path exists on the file system.
- *
- * @param path The path to check.
- * @return true if the path exists, false if not.
- */
- bool exists(const char* path);
- /**
- * Checks is a path is a directory.
- *
- * @param path The path to check.
- * @return true if the path is a directory, false if not.
- */
- bool is_directory(const char* path);
- /**
- * Checks is a file is a writable.
- *
- * @param path The path to check.
- * @return true if the file is writable, false if not.
- */
- bool is_writable(const char* path);
- /**
- * Gets the time the file or directory was created.
- *
- * @param path The path to use.
- * @return The time the file or directory was created.
- */
- time_t get_create_time(const char* path);
- /**
- * Gets the last time a file or directory was modified.
- *
- * @param path The path to use.
- * @return The last time a file or directory was modified.
- */
- time_t get_mod_time(const char* path);
- /**
- * Gets an operating system specific canonical path relative to the base.
- *
- * @param path The absolute or relative path. The path must exist.
- * @param base The base path to resolve relative path against. Can be nullptr.
- * @return The operating system specific canonical path relative to the base.
- */
- std::string get_canonical_path(const char* path, const char* base = nullptr);
- /**
- * Makes a temporary directory on the file system.
- *
- * The directory is created under the system temporary directory area and will have a randomized name.
- *
- * @return The full path to the created directory or if fails and empty string and also logs an error message.
- */
- std::string make_temp_directory();
- /**
- * Makes a directory on the file system.
- *
- * @param path The path to the directory to create.
- * @param createMissingDirectories if true it will create any missing directories to make the
- *
- * @return true if the creation was successful, fails if fails.
- */
- bool make_directory(const char* path, bool createMissingDirectories = true);
- /**
- * Removes (deletes) a directory from the file system.
- *
- * This will never follow symbolic links. The symbolic link will be removed, but its target will not.
- * To remove the currect directory, you must first change to another directory and then remove it.
- *
- * @param path The path to the directory to remove.
- * @return true if the removal was successful, false is not successful.
- */
- bool remove_directory(const char* path);
- /**
- * Removes (deletes) a file from the file system.
- *
- * This can fail by either having the file still open by either the calling process or another process,
- * or by not having sufficient permission to delete the file.
- *
- * @param path The path of the file to be removed.
- * @returns true if the file was removed from the file system, false if not successful.
- */
- bool remove_file(const char* path);
- /**
- * Moves (renames) a file or directory on the file system.
- *
- * @param src The source path to a file or directory to rename.
- * @param dst The destination path.
- * @return true of the move was successful, false is not successful.
- */
- bool move(const char* src, const char* dst);
- /**
- * Copy a file on the file system to a new destination.
- *
- * @param src The source path to a file to copy.
- * @param dst The destination filename and path.
- * @return true of the copy was successful, false is not successful.
- */
- bool copy(const char* src, const char* dst);
- /**
- * Gets file information on a specified file on the file system.
- *
- * @param path The path to the file.
- * @param info The info populated about the file.
- * @return true if information was gathered. false if an error occurs.
- */
- bool get_file_info(const char* path, FileInfo* info);
- /**
- * Opens a file on the file system for binary mode with the specifed file mode access.
- *
- * The file opened must closed with close_file() when it is no longer needed.
- *
- * Any files opened with FileMode::WRITE, FileMode::READ_WRITE or FileMode::APPEND
- * that do not exist will be create if the file does not already exist.
- *
- * Files opened with FileMode::READ, FileMode::WRITE or FileMode::READ_WRITE will be initially positioned
- * to the beginning of the file. Files opened with FileMode::APPEND will be initiallly positioned to the
- * end of the file.
- *
- * @param path The path to the file to open.
- * @param The file mode for which to access the file.
- * @param The handle for the file opened if successful or nullptr if not successful.
- */
- File* open_file(const char* path, FileMode mode);
- /**
- * Closes a file on the file system.
- *
- * @param file The handle to the file to be closed.
- */
- void close_file(File* file);
- /**
- * Gets the total size of the file in bytes.
- *
- * @param file The handle to the file.
- * @param The total size of the file in bytes.
- */
- size_t get_file_size(File* file);
- /**
- * Gets the time the file was created.
- *
- * @param file The handle to the file.
- * @return The time this file was created.
- */
- time_t get_file_create_time(File* file);
- /**
- * Gets the last time the file was modified.
- *
- * @param file The handle to the file.
- * @return The time this file was created.
- */
- time_t get_file_mod_time(File* file);
- /**
- * Reads a chunk of binary data from a file.
- *
- * @param file The handle to the file to read from in binary mode.
- * @param chunk Memory to read the binary data to, at least chunkSize bytes large.
- * @param chunkSize Number of bytes to read from file into 'chunk' memory area.
- * @return The number of bytes read. This can be less than requested 'chunkSize' when reading the last bytes of
- * data. This will return 0 when all data has been read from the file.
- */
- size_t read_file_chunk(File* file, void* chunk, size_t chunkSize);
- /**
- * Writes a chunk of binary data to a file.
- *
- * @param file An handle to the file to write to in binary mode.
- * @param chunk The memory buffer to write to the file.
- * @param chunkSize Number of bytes from 'chunk' to write to the file.
- * @returns The number of bytes successfully written to the file. This can be less than the
- * requested chunkSize if an error occurs such as disk full.
- * @returns 0 bytes if no data could be written to the file.
- */
- size_t write_file_chunk(File* file, void* chunk, size_t chunkSize);
- /**
- * Reads a line of character data from a text file.
- *
- * A read line will not include any line termination characters.
- *
- * @param file The handle of the file to read.
- * @param line The string that will receive the read line.
- * @param maxLineSize The maximum number of characters that can be read into 'line', including null termination.
- * If the buffer is exhausted before end-of-line is reached the buffer will be null terminated and thus still a
- * proper string but won't necessarily contain the full line from the file.
- * @return The read string, 'line', on each successful read but nullptr when end of file is reached.
- */
- char* read_file_line(File* file, char* line, size_t maxLineSize);
- /**
- * Writes a line of characters to a text file.
- *
- * A newline will always be appended to the string in the file if it is successfully written.
- *
- * @param file The handle of the file to read.
- * @param line The null-terminated string to write.
- * @returns true if the full line is successfully written to the file, false if the full string could not be written to the file.
- */
- bool write_file_line(File* file, const char* line);
- /**
- * Flushes any unwritten data to the file.
- *
- * When a file is closed, either by calling close_file or during program termination,
- * all the associated buffers are automatically flushed.
- *
- * @param The handle of the file opened for writing or appending.
- */
- void flush_file(File* file);
- /**
- * Gets the current file cursor position for an open file.
- *
- * The file may have been opened for read, write or append. Files that were opened for
- * append will always write at the end of the file regardless of the current file position.
- * The file current position is typically unused or undefined in the append case.
- *
- * This retrieves the current location of the file in a file that has been
- * opened for read, write, or append. The offset is always returned in bytes.
- * The current file position may be beyond the end of the file if the file pointer was
- * recently placed beyond the end of the file. However, this does not actually reflect the size of the file
- * until at least one byte is written into it at the new position beyond the file's end.
- *
- * @param file The handle of the file to retrieve the current position for.
- * @return The current position in the file in bytes relative to the beginning or -1
- * if the position could not be retrieved.
- */
- int64_t get_file_pos(File* file);
- /**
- * Sets the new file cursor position for an open file.
- *
- * The file may have been opened for read, write or append. Files that were opened for
- * append will always write at the end of the file regardless of the current file position.
- * The file current position is typically unused or undefined in the append case.
- *
- * This attempts to reposition the file cursor in an open file. The new absolute position may
- * not be negative once combined with whence. If the new absolute position is beyond the current
- * end of the file, the file will not be extended until at least one byte is written into the
- * file at that new position or the file is truncated at the current position with truncate_file_at_current_pos().
- * When it is written to or truncated with a larger size than previous, the new space will be filled with zeros.
- * However, that if the file pointer is set beyond the end of the file, the get_file_pos() call will return that
- * same position even though it is larger than the file currently is.
- *
- * @param The handle of the file to set the current position for.
- * @param offsetFromWhence The new position for the file cursor relative to the location specified in whence.
- * This value may be negative only if whence is not FileWhence::BEGIN. This may specify an index beyond the
- * current end of the file when combined with whence.
- * @return true if the file position was successfully set,
- * false if the file position could not be set or was invalid.
- */
- bool set_file_pos(File* file, int64_t offsetFromWhence, FileWhence whence);
- /**
- * Sets the file position to the beginning of the open file.
- *
- * Equivalent to: set_file_pos(file, 0, FileWhence::BEGIN);
- *
- * @param file The handle of the file.
- * @return true if the file position was successfully set,
- * false if the file position could not be set or was invalid.
- */
- bool set_file_pos_begin(File* file);
- /**
- * Sets the file position to the end of the open file.
- *
- * Equivalent to: set_file_pos(file, 0, FileWhence::END);
- *
- * @param file The handle of the file.
- * @return true if the file position was successfully set,
- * false if the file position could not be set or was invalid.
- */
- bool set_file_pos_end(File* file);
- /**
- * Truncates a file at the current file position.
- *
- * The file must have been opened for write or append.
- *
- * This truncates a file at the current file pointer position. This can be used
- * to extend a file without needing to write anything to it by opening the file,
- * setting the file position to the desired size with set_file_pos(), then calling
- * this function to set the new end of the file. The new area of the file will be
- * filled with zeros if it was extended. If the file is being shortened, all data
- * in the file beyond the current file pointer will be removed.
- *
- * @param file The handle to the file to be truncated.
- * @return true if the file was successfully truncated,
- * false if the file could not be truncated for any reason.
- */
- bool truncate_file_at_current_pos(File* file);
- /**
- * Gets the current file status of a stream.
- *
- * FileStreamStatus::STREAM_OK Is the file stream is still in a valid state and more read or
- * write operation may potentially succeed.
- * FileStatus::STREAM_ERROR Is if the file stream has encountered an error of any kind.
- * This may include a partial write due to a full disk or a disk quota being reached.
- * FileStreamStatus::STREAM_OEF Is if a file stream opened for read has already read the last
- * bytes in the file. A future call to read_file_*() will simply return 0 or nullptr
- * from the same file position.
- *
- * This retrieves the current status of a file stream object. The status allows
- * the caller to differentiate an error from an end-of-file condition for the
- * last file operation. The error condition on the file will be reset after
- * each operation after being stored for later retrieval. The file stream status
- * value will remain valid until the next operation is performed on the file.
- *
- * As with all other file operations, retrieving this status is not thread safe
- * and could change if another thread performs an unprotected operation on the
- * same stream. It is the caller's responsibility to ensure operations on the
- * file stream are appropriately protected.
- *
- * The file status will not be modified by calls to get_file_size(), get_file_mod_time(),
- * flush_file(), or get_file_pos().
- *
- * @param file The handle of an open file to check the status of.
- */
- FileStreamStatus get_file_stream_status(File* file);
- /**
- * Callback function that is called for each file or directory visited when calling
- * the function for_each_directory_item(..).
- *
- * @param info The directory information for the item visited.
- * @param The user pointer specified by the call to for_each_directory_item()
- * @return The action to perform after the visited item is completed.
- */
- typedef VisitAction (*OnVisitDirectoryItemFn)(const DirectoryInfo* info, void* userPtr);
- /**
- * Iterate through each item in the directory from the specified directory path.
- *
- * @param path The path to the directory
- * @param fn The visitor function to be called for each directory item encountered.
- * @param userPtr The user pointer data passed to the callback function for each item.
- * @param recursive true to recursively traverse through each sub-directory too,
- * false for only the specified path and not sub-directories.
- */
- void for_each_directory_item(const char* path, OnVisitDirectoryItemFn fn, void* userPtr, bool recursive = false);
- /**
- * Callback function to use when listening to changes on file system.
- *
- * @param path The path for file system change.
- * @param evt The change event that occurred.
- * @param userPtr The user pointer associated with the subscription to the change event.
- * @param newPath The path for the new name of the file. Used only for RENAMED event, otherwise it's nullptr
- */
- typedef void (*OnChangeEventFn)(const char* path, ChangeEvent evt, void* userPtr, const char* newPath);
- /**
- * Subscribes to listen on change events on a path.
- *
- * @param path The path on which to subscribe to change events.
- * @param onChangeEvent The callback function to be called when the events are fired.
- * @param userData The user pointer passed to the callback function for each item.
- * @return The subscription id if the path was successfully subscribed to or nullptr otherwise.
- */
- uint32_t subscribe_to_change_events(const char* path, OnChangeEventFn fn, void* userPtr);
- /**
- * Unsubscribes from listening to change events based on subscription path.
- *
- * @param id The subscription id to unsubscribe from.
- */
- void unsubscribe_to_change_events(uint32_t id);
- private:
- FileSystem();
- ~FileSystem();
- void set_app_executable_path(const char* path);
- struct Impl;
- Impl* _impl;
- };
- }
|