You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
6.7KB

  1. #pragma once
  2. #include <vector>
  3. #include <common.hpp>
  4. namespace rack {
  5. /** Cross-platform functions for OS, file path, and filesystem routines */
  6. namespace system {
  7. // Filesystem
  8. /** Joins two paths with a directory separator.
  9. If `path2` is an empty string, returns `path1`.
  10. */
  11. std::string join(const std::string& path1, const std::string& path2 = "");
  12. /** Join an arbitrary number of paths, from left to right. */
  13. template <typename... Paths>
  14. std::string join(const std::string& path1, const std::string& path2, Paths... paths) {
  15. return join(join(path1, path2), paths...);
  16. }
  17. /** Returns all entries (directories, files, symbolic links, etc) in a directory.
  18. `depth` is the number of directories to recurse. 0 depth does not recurse. -1 depth recurses infinitely.
  19. */
  20. std::vector<std::string> getEntries(const std::string& dirPath, int depth = 0);
  21. bool exists(const std::string& path);
  22. /** Returns whether the given path is a file. */
  23. bool isFile(const std::string& path);
  24. /** Returns whether the given path is a directory. */
  25. bool isDirectory(const std::string& path);
  26. uint64_t getFileSize(const std::string& path);
  27. /** Moves a file or directory.
  28. Does not overwrite the destination. If this behavior is needed, use remove() or removeRecursively() before moving.
  29. Returns whether the rename was successful.
  30. */
  31. bool rename(const std::string& srcPath, const std::string& destPath);
  32. /** Copies a file or directory recursively.
  33. Overwrites destination if already exists.
  34. Returns whether the copy was successful.
  35. */
  36. bool copy(const std::string& srcPath, const std::string& destPath);
  37. /** Creates a directory.
  38. The parent directory must exist.
  39. Returns whether the creation was successful.
  40. */
  41. bool createDirectory(const std::string& path);
  42. /** Creates all directories up to the path.
  43. Returns whether the creation was successful.
  44. */
  45. bool createDirectories(const std::string& path);
  46. bool createSymbolicLink(const std::string& target, const std::string& link);
  47. /** Deletes a file or empty directory.
  48. Returns whether the deletion was successful.
  49. */
  50. bool remove(const std::string& path);
  51. /** Deletes a file or directory recursively.
  52. Returns the number of files and directories that were deleted.
  53. */
  54. int removeRecursively(const std::string& path);
  55. std::string getWorkingDirectory();
  56. void setWorkingDirectory(const std::string& path);
  57. std::string getTempDirectory();
  58. /** Returns the absolute path beginning with "/". */
  59. std::string getAbsolute(const std::string& path);
  60. /** Returns the canonical (unique) path, following symlinks and "." and ".." fake directories.
  61. The path must exist on the filesystem.
  62. Examples:
  63. getCanonical("/foo/./bar/.") // "/foo/bar"
  64. */
  65. std::string getCanonical(const std::string& path);
  66. /** Extracts the parent directory of the path.
  67. Examples:
  68. getDirectory("/var/tmp/example.txt") // "/var/tmp"
  69. getDirectory("/") // ""
  70. getDirectory("/var/tmp/.") // "/var/tmp"
  71. */
  72. std::string getDirectory(const std::string& path);
  73. /** Extracts the filename of the path.
  74. Examples:
  75. getFilename("/foo/bar.txt") // "bar.txt"
  76. getFilename("/foo/.bar") // ".bar"
  77. getFilename("/foo/bar/") // "."
  78. getFilename("/foo/.") // "."
  79. getFilename("/foo/..") // ".."
  80. getFilename(".") // "."
  81. getFilename("..") // ".."
  82. getFilename("/") // "/"
  83. */
  84. std::string getFilename(const std::string& path);
  85. /** Extracts the portion of a filename without the extension.
  86. Examples:
  87. getStem("/foo/bar.txt") // "bar"
  88. getStem("/foo/.bar") // ""
  89. getStem("/foo/foo.tar.ztd") // "foo.tar"
  90. */
  91. std::string getStem(const std::string& path);
  92. /** Extracts the extension of a filename, including the dot.
  93. Examples:
  94. getExtension("/foo/bar.txt") // ".txt"
  95. getExtension("/foo/bar.") // "."
  96. getExtension("/foo/bar") // ""
  97. getExtension("/foo/bar.txt/bar.cc") // ".cc"
  98. getExtension("/foo/bar.txt/bar.") // "."
  99. getExtension("/foo/bar.txt/bar") // ""
  100. getExtension("/foo/.") // ""
  101. getExtension("/foo/..") // ""
  102. getExtension("/foo/.hidden") // ".hidden"
  103. */
  104. std::string getExtension(const std::string& path);
  105. // File read/write
  106. /** Reads an entire file into a memory buffer.
  107. Throws on error.
  108. */
  109. std::vector<uint8_t> readFile(const std::string& path);
  110. uint8_t* readFile(const std::string& path, size_t* size);
  111. /** Writes a memory buffer to a file, overwriting if already exists.
  112. Throws on error.
  113. */
  114. void writeFile(const std::string& path, const std::vector<uint8_t>& data);
  115. /** Compresses the contents of a directory (recursively) to an archive.
  116. Uses the Unix Standard TAR + Zstandard format (.tar.zst).
  117. An equivalent shell command is
  118. tar -c -C dirPath . | zstd -1 -o archivePath
  119. or
  120. ZSTD_CLEVEL=1 tar -cf archivePath --zstd -C dirPath .
  121. Throws on error.
  122. */
  123. void archiveDirectory(const std::string& archivePath, const std::string& dirPath, int compressionLevel = 1);
  124. std::vector<uint8_t> archiveDirectory(const std::string& dirPath, int compressionLevel = 1);
  125. /** Extracts an archive into a directory.
  126. An equivalent shell command is
  127. zstd -d < archivePath | tar -x -C dirPath
  128. or
  129. tar -xf archivePath --zstd -C dirPath
  130. As a special case, zero-byte files in the archive cause the unarchiver to delete existing files instead of overwriting them.
  131. This is useful for removing presets in .vcvplugin packages, for example.
  132. Throws on error.
  133. */
  134. void unarchiveToDirectory(const std::string& archivePath, const std::string& dirPath);
  135. void unarchiveToDirectory(const std::vector<uint8_t>& archiveData, const std::string& dirPath);
  136. // Threading
  137. /** Returns the number of logical simultaneous multithreading (SMT) (e.g. Intel Hyperthreaded) threads on the CPU. */
  138. int getLogicalCoreCount();
  139. /** Sets a name of the current thread for debuggers and OS-specific process viewers. */
  140. void setThreadName(const std::string& name);
  141. // Querying
  142. /** Returns the caller's human-readable stack trace with "\n"-separated lines. */
  143. std::string getStackTrace();
  144. /** Returns the number of seconds since application launch.
  145. Gives the most precise (fine-grained) monotonic (non-decreasing) time differences available on the OS for benchmarking purposes, while being fast to compute.
  146. */
  147. double getTime();
  148. /** Returns time since 1970-01-01 00:00:00 UTC in seconds.
  149. */
  150. double getUnixTime();
  151. double getThreadTime();
  152. void sleep(double time);
  153. std::string getOperatingSystemInfo();
  154. // Applications
  155. /** Opens a URL in a browser.
  156. Shell injection is possible, so make sure the URL is trusted or hard coded.
  157. Does nothing if string is blank.
  158. Does not block.
  159. */
  160. void openBrowser(const std::string& url);
  161. /** Opens Windows Explorer, Finder, etc at a directory location.
  162. Does nothing if string is blank.
  163. Does not block.
  164. */
  165. void openDirectory(const std::string& path);
  166. /** Runs an executable without blocking.
  167. The launched process will continue running if the current process is closed.
  168. */
  169. void runProcessDetached(const std::string& path);
  170. PRIVATE void init();
  171. } // namespace system
  172. } // namespace rack