fileAPI.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2020 to 2022 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. /*
  24. TODO:
  25. * bool file_setCurrentPath(const ReadableString& path);
  26. WINBASEAPI WINBOOL WINAPI SetCurrentDirectoryW(LPCWSTR lpPathName);
  27. chdir on Posix
  28. * bool file_createFolder(const ReadableString& path);
  29. WINBASEAPI WINBOOL WINAPI CreateDirectoryW (LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
  30. mkdir on Posix
  31. * int64_t file_getSize(const ReadableString& path);
  32. WINBASEAPI WINBOOL WINAPI GetFileSizeEx (HANDLE hFile, PLARGE_INTEGER lpFileSize);
  33. * bool file_remove(const ReadableString& path);
  34. WINBASEAPI WINBOOL WINAPI DeleteFileW (LPCWSTR lpFileName);
  35. * bool file_exists(const ReadableString& path);
  36. Can open a file without permissions and see if it works.
  37. * void file_getFolderContent(const ReadableString& folderPath, std::function<void(ReadableString, EntryType)> action)
  38. How to do this the safest way with Unicode as a minimum requirement?
  39. */
  40. #ifndef DFPSR_API_FILE
  41. #define DFPSR_API_FILE
  42. #include "../api/stringAPI.h"
  43. #include "bufferAPI.h"
  44. #if defined(WIN32) || defined(_WIN32)
  45. #define USE_MICROSOFT_WINDOWS
  46. #endif
  47. #if defined(__linux__)
  48. #define USE_LINUX
  49. #endif
  50. // A module for file access that exists to prevent cyclic dependencies between strings and buffers.
  51. // Buffers need a filename to be saved or loaded while strings use buffers to store their characters.
  52. namespace dsr {
  53. // Post-condition:
  54. // Returns the content of the file referred to by file_optimizePath(filename).
  55. // If mustExist is true, then failure to load will throw an exception.
  56. // If mustExist is false, then failure to load will return an empty handle (returning false for buffer_exists).
  57. Buffer file_loadBuffer(const ReadableString& filename, bool mustExist = true);
  58. // Side-effect: Saves buffer to file_optimizePath(filename) as a binary file.
  59. // Pre-condition: buffer exists
  60. void file_saveBuffer(const ReadableString& filename, Buffer buffer);
  61. // Get a path separator for the target operating system.
  62. // Can be used to construct a file path that works for both forward and backward slash separators.
  63. const char32_t* file_separator();
  64. // Turns / and \ into the local system's convention, so that loading and saving files can use either one of them automatically.
  65. // TODO: Remove redundant . and .. to reduce the risk of running out of buffer space.
  66. String file_optimizePath(const ReadableString &path);
  67. // TODO: Create regression tests for the file system.
  68. // Returns the local name of the file or folder after the last path separator, or the whole path if no separator was found.
  69. // Examples with / as the path separator:
  70. // file_getFolderPath(U"MyFolder/Cars.txt") == U"Cars.txt"
  71. // file_getFolderPath(U"MyFolder/") == U""
  72. // file_getFolderPath(U"MyFolder") == U"MyFolder"
  73. // file_getFolderPath(U"MyFolder/Folder2") == U"Folder2"
  74. ReadableString file_getPathlessName(const ReadableString &path);
  75. // Returns the parent folder path with anything after the last slash removed, or empty if there was no slash left.
  76. // Examples with / as the path separator:
  77. // file_getFolderPath(U"MyFolder/Documents/Cars.txt") == U"MyFolder/Documents"
  78. // file_getFolderPath(U"MyFolder/Documents/") == U"MyFolder/Documents"
  79. // file_getFolderPath(U"MyFolder/Documents") == U"MyFolder"
  80. // file_getFolderPath(U"MyFolder") == U""
  81. ReadableString file_getParentFolder(const ReadableString &path);
  82. // Combines two parts into a path and automatically adding a local separator when needed.
  83. // Can be used to get the full path of a file in a folder or add another folder to the path.
  84. // b may not begin with a separator, because only a is allowed to contain the root.
  85. // Examples with / as the path separator:
  86. // file_combinePaths(U"Folder", U"Document.txt") == U"Folder/Document.txt"
  87. // file_combinePaths(U"Folder/", U"Document.txt") == U"Folder/Document.txt"
  88. String file_combinePaths(const ReadableString &a, const ReadableString &b);
  89. // Returns true iff path contains a root, according to the local path syntax.
  90. bool file_hasRoot(const ReadableString &path);
  91. // DSR_MAIN_CALLER is a convenient wrapper for getting input arguments as a list of portable Unicode strings.
  92. // The actual main function gets placed in DSR_MAIN_CALLER, which calls the given function.
  93. // When a regular function replaces the main function, it will not return zero by default.
  94. // Returning something else than zero tells that something went wrong and it must skip cleanup in order to get out.
  95. // Then the window and other resources held as global variables might not close.
  96. // Example:
  97. // DSR_MAIN_CALLER(dsrMain)
  98. // int dsrMain(List<String> args) {
  99. // printText("Input arguments:\n");
  100. // for (int a = 0; a < args.length(); a++) {
  101. // printText(" args[", a, "] = ", args[a], "\n");
  102. // }
  103. // return 0;
  104. // }
  105. #ifdef USE_MICROSOFT_WINDOWS
  106. #define DSR_MAIN_CALLER(MAIN_NAME) \
  107. int MAIN_NAME(List<String> args); \
  108. int main() { \
  109. return MAIN_NAME(file_impl_getInputArguments()); \
  110. }
  111. #else
  112. #define DSR_MAIN_CALLER(MAIN_NAME) \
  113. int MAIN_NAME(List<String> args); \
  114. int main(int argc, char **argv) { return MAIN_NAME(file_impl_convertInputArguments(argc, (void**)argv)); }
  115. #endif
  116. // Helper functions have to be exposed for the macro handle your input arguments.
  117. // Do not call these yourself.
  118. List<String> file_impl_convertInputArguments(int argn, void **argv);
  119. List<String> file_impl_getInputArguments();
  120. // Get the current path, from where the application was called and relative paths start.
  121. String file_getCurrentPath();
  122. // Get the application's folder path, from where the application is stored.
  123. // If not implemented and allowFallback is true,
  124. // the current path is returned instead as a qualified guess instead of raising an exception.
  125. String file_getApplicationFolder(bool allowFallback = true);
  126. // Gets an absolute version of the path, quickly without removing redundancy.
  127. String file_getAbsolutePath(const ReadableString &path);
  128. // Returns true iff path refers to a valid file or folder.
  129. bool file_exists(const ReadableString& path);
  130. }
  131. #endif