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.

311 line
9.5KB

  1. /* FatLib Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the FatLib Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the FatLib Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef FatFileSystem_h
  21. #define FatFileSystem_h
  22. #include "FatVolume.h"
  23. #include "FatFile.h"
  24. #include "ArduinoFiles.h"
  25. /**
  26. * \file
  27. * \brief FatFileSystem class
  28. */
  29. //------------------------------------------------------------------------------
  30. /**
  31. * \class FatFileSystem
  32. * \brief Integration class for the FatLib library.
  33. */
  34. class FatFileSystem : public FatVolume {
  35. public:
  36. /**
  37. * Initialize an FatFileSystem object.
  38. * \param[in] part partition to initialize.
  39. * \return The value true is returned for success and
  40. * the value false is returned for failure.
  41. */
  42. bool begin(uint8_t part = 0) {
  43. vwd()->close();
  44. return (part ? init(part) : init(1) || init(0))
  45. && vwd()->openRoot(this) && FatFile::setCwd(vwd());
  46. }
  47. #if ENABLE_ARDUINO_FEATURES
  48. /** List the directory contents of the volume working directory to Serial.
  49. *
  50. * \param[in] flags The inclusive OR of
  51. *
  52. * LS_DATE - %Print file modification date
  53. *
  54. * LS_SIZE - %Print file size.
  55. *
  56. * LS_R - Recursive list of subdirectories.
  57. */
  58. void ls(uint8_t flags = 0) {
  59. ls(&Serial, flags);
  60. }
  61. /** List the directory contents of a directory to Serial.
  62. *
  63. * \param[in] path directory to list.
  64. *
  65. * \param[in] flags The inclusive OR of
  66. *
  67. * LS_DATE - %Print file modification date
  68. *
  69. * LS_SIZE - %Print file size.
  70. *
  71. * LS_R - Recursive list of subdirectories.
  72. */
  73. void ls(const char* path, uint8_t flags = 0) {
  74. ls(&Serial, path, flags);
  75. }
  76. /** open a file
  77. *
  78. * \param[in] path location of file to be opened.
  79. * \param[in] mode open mode flags.
  80. * \return a File object.
  81. */
  82. File open(const char *path, uint8_t mode = FILE_READ) {
  83. File tmpFile;
  84. tmpFile.open(vwd(), path, mode);
  85. return tmpFile;
  86. }
  87. #endif // ENABLE_ARDUINO_FEATURES
  88. /** Change a volume's working directory to root
  89. *
  90. * Changes the volume's working directory to the SD's root directory.
  91. * Optionally set the current working directory to the volume's
  92. * working directory.
  93. *
  94. * \param[in] set_cwd Set the current working directory to this volume's
  95. * working directory if true.
  96. *
  97. * \return The value true is returned for success and
  98. * the value false is returned for failure.
  99. */
  100. bool chdir(bool set_cwd = false) {
  101. vwd()->close();
  102. return vwd()->openRoot(this) && (set_cwd ? FatFile::setCwd(vwd()) : true);
  103. }
  104. /** Change a volume's working directory
  105. *
  106. * Changes the volume working directory to the \a path subdirectory.
  107. * Optionally set the current working directory to the volume's
  108. * working directory.
  109. *
  110. * Example: If the volume's working directory is "/DIR", chdir("SUB")
  111. * will change the volume's working directory from "/DIR" to "/DIR/SUB".
  112. *
  113. * If path is "/", the volume's working directory will be changed to the
  114. * root directory
  115. *
  116. * \param[in] path The name of the subdirectory.
  117. *
  118. * \param[in] set_cwd Set the current working directory to this volume's
  119. * working directory if true.
  120. *
  121. * \return The value true is returned for success and
  122. * the value false is returned for failure.
  123. */
  124. //----------------------------------------------------------------------------
  125. bool chdir(const char *path, bool set_cwd = false) {
  126. FatFile dir;
  127. if (path[0] == '/' && path[1] == '\0') {
  128. return chdir(set_cwd);
  129. }
  130. if (!dir.open(vwd(), path, O_READ)) {
  131. goto fail;
  132. }
  133. if (!dir.isDir()) {
  134. goto fail;
  135. }
  136. // *m_vwd = dir;
  137. m_vwd = dir;
  138. if (set_cwd) {
  139. FatFile::setCwd(vwd());
  140. }
  141. return true;
  142. fail:
  143. return false;
  144. }
  145. //----------------------------------------------------------------------------
  146. /** Set the current working directory to a volume's working directory.
  147. *
  148. * This is useful with multiple SD cards.
  149. *
  150. * The current working directory is changed to this
  151. * volume's working directory.
  152. *
  153. * This is like the Windows/DOS \<drive letter>: command.
  154. */
  155. void chvol() {
  156. FatFile::setCwd(vwd());
  157. }
  158. //----------------------------------------------------------------------------
  159. /**
  160. * Test for the existence of a file.
  161. *
  162. * \param[in] path Path of the file to be tested for.
  163. *
  164. * \return true if the file exists else false.
  165. */
  166. bool exists(const char* path) {
  167. return vwd()->exists(path);
  168. }
  169. //----------------------------------------------------------------------------
  170. /** List the directory contents of the volume working directory.
  171. *
  172. * \param[in] pr Print stream for list.
  173. *
  174. * \param[in] flags The inclusive OR of
  175. *
  176. * LS_DATE - %Print file modification date
  177. *
  178. * LS_SIZE - %Print file size.
  179. *
  180. * LS_R - Recursive list of subdirectories.
  181. */
  182. void ls(print_t* pr, uint8_t flags) {
  183. vwd()->ls(pr, flags);
  184. }
  185. //----------------------------------------------------------------------------
  186. /** List the directory contents of a directory.
  187. *
  188. * \param[in] pr Print stream for list.
  189. *
  190. * \param[in] path directory to list.
  191. *
  192. * \param[in] flags The inclusive OR of
  193. *
  194. * LS_DATE - %Print file modification date
  195. *
  196. * LS_SIZE - %Print file size.
  197. *
  198. * LS_R - Recursive list of subdirectories.
  199. */
  200. void ls(print_t* pr, const char* path, uint8_t flags) {
  201. FatFile dir;
  202. dir.open(vwd(), path, O_READ);
  203. dir.ls(pr, flags);
  204. }
  205. //----------------------------------------------------------------------------
  206. /** Make a subdirectory in the volume working directory.
  207. *
  208. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  209. *
  210. * \param[in] pFlag Create missing parent directories if true.
  211. *
  212. * \return The value true is returned for success and
  213. * the value false is returned for failure.
  214. */
  215. bool mkdir(const char* path, bool pFlag = true) {
  216. FatFile sub;
  217. return sub.mkdir(vwd(), path, pFlag);
  218. }
  219. //----------------------------------------------------------------------------
  220. /** Remove a file from the volume working directory.
  221. *
  222. * \param[in] path A path with a valid 8.3 DOS name for the file.
  223. *
  224. * \return The value true is returned for success and
  225. * the value false is returned for failure.
  226. */
  227. bool remove(const char* path) {
  228. return FatFile::remove(vwd(), path);
  229. }
  230. //----------------------------------------------------------------------------
  231. /** Rename a file or subdirectory.
  232. *
  233. * \param[in] oldPath Path name to the file or subdirectory to be renamed.
  234. *
  235. * \param[in] newPath New path name of the file or subdirectory.
  236. *
  237. * The \a newPath object must not exist before the rename call.
  238. *
  239. * The file to be renamed must not be open. The directory entry may be
  240. * moved and file system corruption could occur if the file is accessed by
  241. * a file object that was opened before the rename() call.
  242. *
  243. * \return The value true is returned for success and
  244. * the value false is returned for failure.
  245. */
  246. bool rename(const char *oldPath, const char *newPath) {
  247. FatFile file;
  248. if (!file.open(vwd(), oldPath, O_READ)) {
  249. return false;
  250. }
  251. return file.rename(vwd(), newPath);
  252. }
  253. //----------------------------------------------------------------------------
  254. /** Remove a subdirectory from the volume's working directory.
  255. *
  256. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  257. *
  258. * The subdirectory file will be removed only if it is empty.
  259. *
  260. * \return The value true is returned for success and
  261. * the value false is returned for failure.
  262. */
  263. bool rmdir(const char* path) {
  264. FatFile sub;
  265. if (!sub.open(vwd(), path, O_READ)) {
  266. return false;
  267. }
  268. return sub.rmdir();
  269. }
  270. //----------------------------------------------------------------------------
  271. /** Truncate a file to a specified length. The current file position
  272. * will be maintained if it is less than or equal to \a length otherwise
  273. * it will be set to end of file.
  274. *
  275. * \param[in] path A path with a valid 8.3 DOS name for the file.
  276. * \param[in] length The desired length for the file.
  277. *
  278. * \return The value true is returned for success and
  279. * the value false is returned for failure.
  280. */
  281. bool truncate(const char* path, uint32_t length) {
  282. FatFile file;
  283. if (!file.open(vwd(), path, O_WRITE)) {
  284. return false;
  285. }
  286. return file.truncate(length);
  287. }
  288. /** \return a pointer to the FatVolume object. */
  289. FatVolume* vol() {
  290. return this;
  291. }
  292. /** \return a pointer to the volume working directory. */
  293. FatFile* vwd() {
  294. return &m_vwd;
  295. }
  296. /** Wipe all data from the volume. You must reinitialize the volume before
  297. * accessing it again.
  298. * \param[in] pr print stream for status dots.
  299. * \return true for success else false.
  300. */
  301. bool wipe(print_t* pr = 0) {
  302. vwd()->close();
  303. return FatVolume::wipe(pr);
  304. }
  305. private:
  306. FatFile m_vwd;
  307. };
  308. #endif // FatFileSystem_h