FatFile.h 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. /**
  2. * Copyright (c) 20011-2017 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef FatFile_h
  26. #define FatFile_h
  27. /**
  28. * \file
  29. * \brief FatFile class
  30. */
  31. // #include <ctype.h>
  32. #include <string.h>
  33. #include <stddef.h>
  34. #include <limits.h>
  35. #include "FatLibConfig.h"
  36. #include "FatApiConstants.h"
  37. #include "FatStructs.h"
  38. #include "FatVolume.h"
  39. class FatFileSystem;
  40. //------------------------------------------------------------------------------
  41. // Stuff to store strings in AVR flash.
  42. #ifdef __AVR__
  43. #include <avr/pgmspace.h>
  44. #else // __AVR__
  45. #ifndef PSTR
  46. /** store literal string in flash for ARM */
  47. #define PSTR(x) (x)
  48. #endif // PSTR
  49. #ifndef pgm_read_byte
  50. /** read 8-bits from flash for ARM */
  51. #define pgm_read_byte(addr) (*(const unsigned char*)(addr))
  52. #endif // pgm_read_byte
  53. #ifndef pgm_read_word
  54. /** read 16-bits from flash for ARM */
  55. #define pgm_read_word(addr) (*(const uint16_t*)(addr))
  56. #endif // pgm_read_word
  57. #ifndef PROGMEM
  58. /** store in flash for ARM */
  59. #define PROGMEM
  60. #endif // PROGMEM
  61. #endif // __AVR__
  62. //------------------------------------------------------------------------------
  63. /**
  64. * \struct FatPos_t
  65. * \brief Internal type for file position - do not use in user apps.
  66. */
  67. struct FatPos_t {
  68. /** stream position */
  69. uint32_t position;
  70. /** cluster for position */
  71. uint32_t cluster;
  72. FatPos_t() : position(0), cluster(0) {}
  73. };
  74. //------------------------------------------------------------------------------
  75. /** Expression for path name separator. */
  76. #define isDirSeparator(c) ((c) == '/')
  77. //------------------------------------------------------------------------------
  78. /**
  79. * \struct fname_t
  80. * \brief Internal type for Short File Name - do not use in user apps.
  81. */
  82. struct fname_t {
  83. /** Flags for base and extension character case and LFN. */
  84. uint8_t flags;
  85. /** length of Long File Name */
  86. size_t len;
  87. /** Long File Name start. */
  88. const char* lfn;
  89. /** position for sequence number */
  90. uint8_t seqPos;
  91. /** Short File Name */
  92. uint8_t sfn[11];
  93. };
  94. /** Derived from a LFN with loss or conversion of characters. */
  95. const uint8_t FNAME_FLAG_LOST_CHARS = 0X01;
  96. /** Base-name or extension has mixed case. */
  97. const uint8_t FNAME_FLAG_MIXED_CASE = 0X02;
  98. /** LFN entries are required for file name. */
  99. const uint8_t FNAME_FLAG_NEED_LFN =
  100. FNAME_FLAG_LOST_CHARS | FNAME_FLAG_MIXED_CASE;
  101. /** Filename base-name is all lower case */
  102. const uint8_t FNAME_FLAG_LC_BASE = DIR_NT_LC_BASE;
  103. /** Filename extension is all lower case. */
  104. const uint8_t FNAME_FLAG_LC_EXT = DIR_NT_LC_EXT;
  105. //==============================================================================
  106. /**
  107. * \class FatFile
  108. * \brief Basic file class.
  109. */
  110. class FatFile {
  111. public:
  112. /** Create an instance. */
  113. FatFile() : m_attr(FILE_ATTR_CLOSED), m_error(0) {}
  114. /** Create a file object and open it in the current working directory.
  115. *
  116. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  117. *
  118. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  119. * OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
  120. */
  121. FatFile(const char* path, uint8_t oflag) {
  122. m_attr = FILE_ATTR_CLOSED;
  123. m_error = 0;
  124. open(path, oflag);
  125. }
  126. #if DESTRUCTOR_CLOSES_FILE
  127. ~FatFile() {
  128. if (isOpen()) {
  129. close();
  130. }
  131. }
  132. #endif // DESTRUCTOR_CLOSES_FILE
  133. #if ENABLE_ARDUINO_FEATURES
  134. /** List directory contents.
  135. *
  136. * \param[in] flags The inclusive OR of
  137. *
  138. * LS_DATE - %Print file modification date
  139. *
  140. * LS_SIZE - %Print file size.
  141. *
  142. * LS_R - Recursive list of subdirectories.
  143. */
  144. void ls(uint8_t flags = 0) {
  145. ls(&Serial, flags);
  146. }
  147. /** %Print a directory date field.
  148. *
  149. * Format is yyyy-mm-dd.
  150. *
  151. * \param[in] fatDate The date field from a directory entry.
  152. */
  153. static void printFatDate(uint16_t fatDate) {
  154. printFatDate(&Serial, fatDate);
  155. }
  156. /** %Print a directory time field.
  157. *
  158. * Format is hh:mm:ss.
  159. *
  160. * \param[in] fatTime The time field from a directory entry.
  161. */
  162. static void printFatTime(uint16_t fatTime) {
  163. printFatTime(&Serial, fatTime);
  164. }
  165. /** Print a file's name.
  166. *
  167. * \return The value true is returned for success and
  168. * the value false is returned for failure.
  169. */
  170. size_t printName() {
  171. return FatFile::printName(&Serial);
  172. }
  173. #endif // ENABLE_ARDUINO_FEATURES
  174. /** \return value of writeError */
  175. bool getWriteError() {
  176. return m_error & WRITE_ERROR;
  177. }
  178. /** Set writeError to zero */
  179. void clearWriteError() {
  180. m_error &= ~WRITE_ERROR;
  181. }
  182. /** Clear all error bits. */
  183. void clearError() {
  184. m_error = 0;
  185. }
  186. /** \return All error bits. */
  187. uint8_t getError() {
  188. return m_error;
  189. }
  190. /** get position for streams
  191. * \param[out] pos struct to receive position
  192. */
  193. void getpos(FatPos_t* pos);
  194. /** set position for streams
  195. * \param[out] pos struct with value for new position
  196. */
  197. void setpos(FatPos_t* pos);
  198. /** \return The number of bytes available from the current position
  199. * to EOF for normal files. Zero is returned for directory files.
  200. */
  201. uint32_t available() {
  202. return isFile() ? fileSize() - curPosition() : 0;
  203. }
  204. /** Close a file and force cached data and directory information
  205. * to be written to the storage device.
  206. *
  207. * \return The value true is returned for success and
  208. * the value false is returned for failure.
  209. */
  210. bool close();
  211. /** Check for contiguous file and return its raw block range.
  212. *
  213. * \param[out] bgnBlock the first block address for the file.
  214. * \param[out] endBlock the last block address for the file.
  215. *
  216. * \return The value true is returned for success and
  217. * the value false is returned for failure.
  218. */
  219. bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
  220. /** Create and open a new contiguous file of a specified size.
  221. *
  222. * \param[in] dirFile The directory where the file will be created.
  223. * \param[in] path A path with a validfile name.
  224. * \param[in] size The desired file size.
  225. *
  226. * \return The value true is returned for success and
  227. * the value false, is returned for failure.
  228. */
  229. bool createContiguous(FatFile* dirFile,
  230. const char* path, uint32_t size);
  231. /** Create and open a new contiguous file of a specified size.
  232. *
  233. * \param[in] path A path with a validfile name.
  234. * \param[in] size The desired file size.
  235. *
  236. * \return The value true is returned for success and
  237. * the value false, is returned for failure.
  238. */
  239. bool createContiguous(const char* path, uint32_t size) {
  240. return createContiguous(m_cwd, path, size);
  241. }
  242. /** \return The current cluster number for a file or directory. */
  243. uint32_t curCluster() const {
  244. return m_curCluster;
  245. }
  246. /** \return The current position for a file or directory. */
  247. uint32_t curPosition() const {
  248. return m_curPosition;
  249. }
  250. /** \return Current working directory */
  251. static FatFile* cwd() {
  252. return m_cwd;
  253. }
  254. /** Set the date/time callback function
  255. *
  256. * \param[in] dateTime The user's call back function. The callback
  257. * function is of the form:
  258. *
  259. * \code
  260. * void dateTime(uint16_t* date, uint16_t* time) {
  261. * uint16_t year;
  262. * uint8_t month, day, hour, minute, second;
  263. *
  264. * // User gets date and time from GPS or real-time clock here
  265. *
  266. * // return date using FAT_DATE macro to format fields
  267. * *date = FAT_DATE(year, month, day);
  268. *
  269. * // return time using FAT_TIME macro to format fields
  270. * *time = FAT_TIME(hour, minute, second);
  271. * }
  272. * \endcode
  273. *
  274. * Sets the function that is called when a file is created or when
  275. * a file's directory entry is modified by sync(). All timestamps,
  276. * access, creation, and modify, are set when a file is created.
  277. * sync() maintains the last access date and last modify date/time.
  278. *
  279. * See the timestamp() function.
  280. */
  281. static void dateTimeCallback(
  282. void (*dateTime)(uint16_t* date, uint16_t* time)) {
  283. m_dateTime = dateTime;
  284. }
  285. /** Cancel the date/time callback function. */
  286. static void dateTimeCallbackCancel() {
  287. m_dateTime = 0;
  288. }
  289. /** Return a file's directory entry.
  290. *
  291. * \param[out] dir Location for return of the file's directory entry.
  292. *
  293. * \return The value true is returned for success and
  294. * the value false is returned for failure.
  295. */
  296. bool dirEntry(dir_t* dir);
  297. /**
  298. * \return The index of this file in it's directory.
  299. */
  300. uint16_t dirIndex() {
  301. return m_dirIndex;
  302. }
  303. /** Format the name field of \a dir into the 13 byte array
  304. * \a name in standard 8.3 short name format.
  305. *
  306. * \param[in] dir The directory structure containing the name.
  307. * \param[out] name A 13 byte char array for the formatted name.
  308. * \return length of the name.
  309. */
  310. static uint8_t dirName(const dir_t* dir, char* name);
  311. /** \return The number of bytes allocated to a directory or zero
  312. * if an error occurs.
  313. */
  314. uint32_t dirSize();
  315. /** Dump file in Hex
  316. * \param[in] pr Print stream for list.
  317. * \param[in] pos Start position in file.
  318. * \param[in] n number of locations to dump.
  319. */
  320. void dmpFile(print_t* pr, uint32_t pos, size_t n);
  321. /** Test for the existence of a file in a directory
  322. *
  323. * \param[in] path Path of the file to be tested for.
  324. *
  325. * The calling instance must be an open directory file.
  326. *
  327. * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory
  328. * dirFile.
  329. *
  330. * \return true if the file exists else false.
  331. */
  332. bool exists(const char* path) {
  333. FatFile file;
  334. return file.open(this, path, O_READ);
  335. }
  336. /**
  337. * Get a string from a file.
  338. *
  339. * fgets() reads bytes from a file into the array pointed to by \a str, until
  340. * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str,
  341. * or end-of-file is encountered. The string is then terminated
  342. * with a null byte.
  343. *
  344. * fgets() deletes CR, '\\r', from the string. This insures only a '\\n'
  345. * terminates the string for Windows text files which use CRLF for newline.
  346. *
  347. * \param[out] str Pointer to the array where the string is stored.
  348. * \param[in] num Maximum number of characters to be read
  349. * (including the final null byte). Usually the length
  350. * of the array \a str is used.
  351. * \param[in] delim Optional set of delimiters. The default is "\n".
  352. *
  353. * \return For success fgets() returns the length of the string in \a str.
  354. * If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
  355. */
  356. int16_t fgets(char* str, int16_t num, char* delim = 0);
  357. /** \return The total number of bytes in a file. */
  358. uint32_t fileSize() const {
  359. return m_fileSize;
  360. }
  361. /** \return The first cluster number for a file or directory. */
  362. uint32_t firstCluster() const {
  363. return m_firstCluster;
  364. }
  365. /**
  366. * Get a file's name followed by a zero byte.
  367. *
  368. * \param[out] name An array of characters for the file's name.
  369. * \param[in] size The size of the array in bytes. The array
  370. * must be at least 13 bytes long. The file's name will be
  371. * truncated if the file's name is too long.
  372. * \return The value true, is returned for success and
  373. * the value false, is returned for failure.
  374. */
  375. bool getName(char* name, size_t size);
  376. /**
  377. * Get a file's Short File Name followed by a zero byte.
  378. *
  379. * \param[out] name An array of characters for the file's name.
  380. * The array must be at least 13 bytes long.
  381. * \return The value true, is returned for success and
  382. * the value false, is returned for failure.
  383. */
  384. bool getSFN(char* name);
  385. /** \return True if this is a directory else false. */
  386. bool isDir() const {
  387. return m_attr & FILE_ATTR_DIR;
  388. }
  389. /** \return True if this is a normal file else false. */
  390. bool isFile() const {
  391. return m_attr & FILE_ATTR_FILE;
  392. }
  393. /** \return True if this is a hidden file else false. */
  394. bool isHidden() const {
  395. return m_attr & FILE_ATTR_HIDDEN;
  396. }
  397. /** \return true if this file has a Long File Name. */
  398. bool isLFN() const {
  399. return m_lfnOrd;
  400. }
  401. /** \return True if this is an open file/directory else false. */
  402. bool isOpen() const {
  403. return m_attr;
  404. }
  405. /** \return True if this is the root directory. */
  406. bool isRoot() const {
  407. return m_attr & FILE_ATTR_ROOT;
  408. }
  409. /** \return True if this is the FAT32 root directory. */
  410. bool isRoot32() const {
  411. return m_attr & FILE_ATTR_ROOT32;
  412. }
  413. /** \return True if this is the FAT12 of FAT16 root directory. */
  414. bool isRootFixed() const {
  415. return m_attr & FILE_ATTR_ROOT_FIXED;
  416. }
  417. /** \return True if file is read-only */
  418. bool isReadOnly() const {
  419. return m_attr & FILE_ATTR_READ_ONLY;
  420. }
  421. /** \return True if this is a subdirectory else false. */
  422. bool isSubDir() const {
  423. return m_attr & FILE_ATTR_SUBDIR;
  424. }
  425. /** \return True if this is a system file else false. */
  426. bool isSystem() const {
  427. return m_attr & FILE_ATTR_SYSTEM;
  428. }
  429. /** Check for a legal 8.3 character.
  430. * \param[in] c Character to be checked.
  431. * \return true for a legal 8.3 character else false.
  432. */
  433. static bool legal83Char(uint8_t c) {
  434. if (c == '"' || c == '|') {
  435. return false;
  436. }
  437. // *+,./
  438. if (0X2A <= c && c <= 0X2F && c != 0X2D) {
  439. return false;
  440. }
  441. // :;<=>?
  442. if (0X3A <= c && c <= 0X3F) {
  443. return false;
  444. }
  445. // [\]
  446. if (0X5B <= c && c <= 0X5D) {
  447. return false;
  448. }
  449. return 0X20 < c && c < 0X7F;
  450. }
  451. /** List directory contents.
  452. *
  453. * \param[in] pr Print stream for list.
  454. *
  455. * \param[in] flags The inclusive OR of
  456. *
  457. * LS_DATE - %Print file modification date
  458. *
  459. * LS_SIZE - %Print file size.
  460. *
  461. * LS_R - Recursive list of subdirectories.
  462. *
  463. * \param[in] indent Amount of space before file name. Used for recursive
  464. * list to indicate subdirectory level.
  465. */
  466. void ls(print_t* pr, uint8_t flags = 0, uint8_t indent = 0);
  467. /** Make a new directory.
  468. *
  469. * \param[in] dir An open FatFile instance for the directory that will
  470. * contain the new directory.
  471. *
  472. * \param[in] path A path with a valid 8.3 DOS name for the new directory.
  473. *
  474. * \param[in] pFlag Create missing parent directories if true.
  475. *
  476. * \return The value true is returned for success and
  477. * the value false is returned for failure.
  478. */
  479. bool mkdir(FatFile* dir, const char* path, bool pFlag = true);
  480. /** Open a file in the volume working directory of a FatFileSystem.
  481. *
  482. * \param[in] fs File System where the file is located.
  483. *
  484. * \param[in] path with a valid 8.3 DOS name for a file to be opened.
  485. *
  486. * \param[in] oflag bitwise-inclusive OR of open mode flags.
  487. * See see FatFile::open(FatFile*, const char*, uint8_t).
  488. *
  489. * \return The value true is returned for success and
  490. * the value false is returned for failure.
  491. */
  492. bool open(FatFileSystem* fs, const char* path, uint8_t oflag);
  493. /** Open a file by index.
  494. *
  495. * \param[in] dirFile An open FatFile instance for the directory.
  496. *
  497. * \param[in] index The \a index of the directory entry for the file to be
  498. * opened. The value for \a index is (directory file position)/32.
  499. *
  500. * \param[in] oflag bitwise-inclusive OR of open mode flags.
  501. * See see FatFile::open(FatFile*, const char*, uint8_t).
  502. *
  503. * See open() by path for definition of flags.
  504. * \return true for success or false for failure.
  505. */
  506. bool open(FatFile* dirFile, uint16_t index, uint8_t oflag);
  507. /** Open a file or directory by name.
  508. *
  509. * \param[in] dirFile An open FatFile instance for the directory containing
  510. * the file to be opened.
  511. *
  512. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  513. *
  514. * \param[in] oflag Values for \a oflag are constructed by a
  515. * bitwise-inclusive OR of flags from the following list
  516. *
  517. * O_READ - Open for reading.
  518. *
  519. * O_RDONLY - Same as O_READ.
  520. *
  521. * O_WRITE - Open for writing.
  522. *
  523. * O_WRONLY - Same as O_WRITE.
  524. *
  525. * O_RDWR - Open for reading and writing.
  526. *
  527. * O_APPEND - If set, the file offset shall be set to the end of the
  528. * file prior to each write.
  529. *
  530. * O_AT_END - Set the initial position at the end of the file.
  531. *
  532. * O_CREAT - If the file exists, this flag has no effect except as noted
  533. * under O_EXCL below. Otherwise, the file shall be created
  534. *
  535. * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
  536. *
  537. * O_SYNC - Call sync() after each write. This flag should not be used with
  538. * write(uint8_t) or any functions do character at a time writes since sync()
  539. * will be called after each byte.
  540. *
  541. * O_TRUNC - If the file exists and is a regular file, and the file is
  542. * successfully opened and is not read only, its length shall be truncated to 0.
  543. *
  544. * WARNING: A given file must not be opened by more than one FatFile object
  545. * or file corruption may occur.
  546. *
  547. * \note Directory files must be opened read only. Write and truncation is
  548. * not allowed for directory files.
  549. *
  550. * \return The value true is returned for success and
  551. * the value false is returned for failure.
  552. */
  553. bool open(FatFile* dirFile, const char* path, uint8_t oflag);
  554. /** Open a file in the current working directory.
  555. *
  556. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  557. *
  558. * \param[in] oflag bitwise-inclusive OR of open mode flags.
  559. * See see FatFile::open(FatFile*, const char*, uint8_t).
  560. *
  561. * \return The value true is returned for success and
  562. * the value false is returned for failure.
  563. */
  564. bool open(const char* path, uint8_t oflag = O_READ) {
  565. return open(m_cwd, path, oflag);
  566. }
  567. /** Open the next file or subdirectory in a directory.
  568. *
  569. * \param[in] dirFile An open FatFile instance for the directory
  570. * containing the file to be opened.
  571. *
  572. * \param[in] oflag bitwise-inclusive OR of open mode flags.
  573. * See see FatFile::open(FatFile*, const char*, uint8_t).
  574. *
  575. * \return true for success or false for failure.
  576. */
  577. bool openNext(FatFile* dirFile, uint8_t oflag = O_READ);
  578. /** Open a volume's root directory.
  579. *
  580. * \param[in] vol The FAT volume containing the root directory to be opened.
  581. *
  582. * \return The value true is returned for success and
  583. * the value false is returned for failure.
  584. */
  585. bool openRoot(FatVolume* vol);
  586. /** Return the next available byte without consuming it.
  587. *
  588. * \return The byte if no error and not at eof else -1;
  589. */
  590. int peek();
  591. /** Print a file's creation date and time
  592. *
  593. * \param[in] pr Print stream for output.
  594. *
  595. * \return The value true is returned for success and
  596. * the value false is returned for failure.
  597. */
  598. bool printCreateDateTime(print_t* pr);
  599. /** %Print a directory date field.
  600. *
  601. * Format is yyyy-mm-dd.
  602. *
  603. * \param[in] pr Print stream for output.
  604. * \param[in] fatDate The date field from a directory entry.
  605. */
  606. static void printFatDate(print_t* pr, uint16_t fatDate);
  607. /** %Print a directory time field.
  608. *
  609. * Format is hh:mm:ss.
  610. *
  611. * \param[in] pr Print stream for output.
  612. * \param[in] fatTime The time field from a directory entry.
  613. */
  614. static void printFatTime(print_t* pr, uint16_t fatTime);
  615. /** Print a number followed by a field terminator.
  616. * \param[in] value The number to be printed.
  617. * \param[in] term The field terminator. Use '\\n' for CR LF.
  618. * \param[in] prec Number of digits after decimal point.
  619. * \return The number of bytes written or -1 if an error occurs.
  620. */
  621. int printField(float value, char term, uint8_t prec = 2);
  622. /** Print a number followed by a field terminator.
  623. * \param[in] value The number to be printed.
  624. * \param[in] term The field terminator. Use '\\n' for CR LF.
  625. * \return The number of bytes written or -1 if an error occurs.
  626. */
  627. int printField(int16_t value, char term);
  628. /** Print a number followed by a field terminator.
  629. * \param[in] value The number to be printed.
  630. * \param[in] term The field terminator. Use '\\n' for CR LF.
  631. * \return The number of bytes written or -1 if an error occurs.
  632. */
  633. int printField(uint16_t value, char term);
  634. /** Print a number followed by a field terminator.
  635. * \param[in] value The number to be printed.
  636. * \param[in] term The field terminator. Use '\\n' for CR LF.
  637. * \return The number of bytes written or -1 if an error occurs.
  638. */
  639. int printField(int32_t value, char term);
  640. /** Print a number followed by a field terminator.
  641. * \param[in] value The number to be printed.
  642. * \param[in] term The field terminator. Use '\\n' for CR LF.
  643. * \return The number of bytes written or -1 if an error occurs.
  644. */
  645. int printField(uint32_t value, char term);
  646. /** Print a file's modify date and time
  647. *
  648. * \param[in] pr Print stream for output.
  649. *
  650. * \return The value true is returned for success and
  651. * the value false is returned for failure.
  652. */
  653. bool printModifyDateTime(print_t* pr);
  654. /** Print a file's name
  655. *
  656. * \param[in] pr Print stream for output.
  657. *
  658. * \return The value true is returned for success and
  659. * the value false is returned for failure.
  660. */
  661. size_t printName(print_t* pr);
  662. /** Print a file's size.
  663. *
  664. * \param[in] pr Print stream for output.
  665. *
  666. * \return The number of characters printed is returned
  667. * for success and zero is returned for failure.
  668. */
  669. size_t printFileSize(print_t* pr);
  670. /** Print a file's Short File Name.
  671. *
  672. * \param[in] pr Print stream for output.
  673. *
  674. * \return The number of characters printed is returned
  675. * for success and zero is returned for failure.
  676. */
  677. size_t printSFN(print_t* pr);
  678. /** Read the next byte from a file.
  679. *
  680. * \return For success read returns the next byte in the file as an int.
  681. * If an error occurs or end of file is reached -1 is returned.
  682. */
  683. int read() {
  684. uint8_t b;
  685. return read(&b, 1) == 1 ? b : -1;
  686. }
  687. /** Read data from a file starting at the current position.
  688. *
  689. * \param[out] buf Pointer to the location that will receive the data.
  690. *
  691. * \param[in] nbyte Maximum number of bytes to read.
  692. *
  693. * \return For success read() returns the number of bytes read.
  694. * A value less than \a nbyte, including zero, will be returned
  695. * if end of file is reached.
  696. * If an error occurs, read() returns -1. Possible errors include
  697. * read() called before a file has been opened, corrupt file system
  698. * or an I/O error occurred.
  699. */
  700. int read(void* buf, size_t nbyte);
  701. /** Read the next directory entry from a directory file.
  702. *
  703. * \param[out] dir The dir_t struct that will receive the data.
  704. *
  705. * \return For success readDir() returns the number of bytes read.
  706. * A value of zero will be returned if end of file is reached.
  707. * If an error occurs, readDir() returns -1. Possible errors include
  708. * readDir() called before a directory has been opened, this is not
  709. * a directory file or an I/O error occurred.
  710. */
  711. int8_t readDir(dir_t* dir);
  712. /** Remove a file.
  713. *
  714. * The directory entry and all data for the file are deleted.
  715. *
  716. * \note This function should not be used to delete the 8.3 version of a
  717. * file that has a long name. For example if a file has the long name
  718. * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
  719. *
  720. * \return The value true is returned for success and
  721. * the value false is returned for failure.
  722. */
  723. bool remove();
  724. /** Remove a file.
  725. *
  726. * The directory entry and all data for the file are deleted.
  727. *
  728. * \param[in] dirFile The directory that contains the file.
  729. * \param[in] path Path for the file to be removed.
  730. *
  731. * \note This function should not be used to delete the 8.3 version of a
  732. * file that has a long name. For example if a file has the long name
  733. * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
  734. *
  735. * \return The value true is returned for success and
  736. * the value false is returned for failure.
  737. */
  738. static bool remove(FatFile* dirFile, const char* path);
  739. /** Set the file's current position to zero. */
  740. void rewind() {
  741. seekSet(0);
  742. }
  743. /** Rename a file or subdirectory.
  744. *
  745. * \param[in] dirFile Directory for the new path.
  746. * \param[in] newPath New path name for the file/directory.
  747. *
  748. * \return The value true is returned for success and
  749. * the value false is returned for failure.
  750. */
  751. bool rename(FatFile* dirFile, const char* newPath);
  752. /** Remove a directory file.
  753. *
  754. * The directory file will be removed only if it is empty and is not the
  755. * root directory. rmdir() follows DOS and Windows and ignores the
  756. * read-only attribute for the directory.
  757. *
  758. * \note This function should not be used to delete the 8.3 version of a
  759. * directory that has a long name. For example if a directory has the
  760. * long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
  761. *
  762. * \return The value true is returned for success and
  763. * the value false is returned for failure.
  764. */
  765. bool rmdir();
  766. /** Recursively delete a directory and all contained files.
  767. *
  768. * This is like the Unix/Linux 'rm -rf *' if called with the root directory
  769. * hence the name.
  770. *
  771. * Warning - This will remove all contents of the directory including
  772. * subdirectories. The directory will then be removed if it is not root.
  773. * The read-only attribute for files will be ignored.
  774. *
  775. * \note This function should not be used to delete the 8.3 version of
  776. * a directory that has a long name. See remove() and rmdir().
  777. *
  778. * \return The value true is returned for success and
  779. * the value false is returned for failure.
  780. */
  781. bool rmRfStar();
  782. /** Set the files position to current position + \a pos. See seekSet().
  783. * \param[in] offset The new position in bytes from the current position.
  784. * \return true for success or false for failure.
  785. */
  786. bool seekCur(int32_t offset) {
  787. return seekSet(m_curPosition + offset);
  788. }
  789. /** Set the files position to end-of-file + \a offset. See seekSet().
  790. * Can't be used for directory files since file size is not defined.
  791. * \param[in] offset The new position in bytes from end-of-file.
  792. * \return true for success or false for failure.
  793. */
  794. bool seekEnd(int32_t offset = 0) {
  795. return isFile() ? seekSet(m_fileSize + offset) : false;
  796. }
  797. /** Sets a file's position.
  798. *
  799. * \param[in] pos The new position in bytes from the beginning of the file.
  800. *
  801. * \return The value true is returned for success and
  802. * the value false is returned for failure.
  803. */
  804. bool seekSet(uint32_t pos);
  805. /** Set the current working directory.
  806. *
  807. * \param[in] dir New current working directory.
  808. *
  809. * \return true for success else false.
  810. */
  811. static bool setCwd(FatFile* dir) {
  812. if (!dir->isDir()) {
  813. return false;
  814. }
  815. m_cwd = dir;
  816. return true;
  817. }
  818. /** \return first block of file or zero for empty file. */
  819. uint32_t firstBlock() {
  820. if (m_firstCluster) {
  821. return m_vol->clusterFirstBlock(m_firstCluster);
  822. }
  823. return 0;
  824. }
  825. /** The sync() call causes all modified data and directory fields
  826. * to be written to the storage device.
  827. *
  828. * \return The value true is returned for success and
  829. * the value false is returned for failure.
  830. */
  831. bool sync();
  832. /** Copy a file's timestamps
  833. *
  834. * \param[in] file File to copy timestamps from.
  835. *
  836. * \note
  837. * Modify and access timestamps may be overwritten if a date time callback
  838. * function has been set by dateTimeCallback().
  839. *
  840. * \return The value true is returned for success and
  841. * the value false is returned for failure.
  842. */
  843. bool timestamp(FatFile* file);
  844. /** Set a file's timestamps in its directory entry.
  845. *
  846. * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive
  847. * OR of flags from the following list
  848. *
  849. * T_ACCESS - Set the file's last access date.
  850. *
  851. * T_CREATE - Set the file's creation date and time.
  852. *
  853. * T_WRITE - Set the file's last write/modification date and time.
  854. *
  855. * \param[in] year Valid range 1980 - 2107 inclusive.
  856. *
  857. * \param[in] month Valid range 1 - 12 inclusive.
  858. *
  859. * \param[in] day Valid range 1 - 31 inclusive.
  860. *
  861. * \param[in] hour Valid range 0 - 23 inclusive.
  862. *
  863. * \param[in] minute Valid range 0 - 59 inclusive.
  864. *
  865. * \param[in] second Valid range 0 - 59 inclusive
  866. *
  867. * \note It is possible to set an invalid date since there is no check for
  868. * the number of days in a month.
  869. *
  870. * \note
  871. * Modify and access timestamps may be overwritten if a date time callback
  872. * function has been set by dateTimeCallback().
  873. *
  874. * \return The value true is returned for success and
  875. * the value false is returned for failure.
  876. */
  877. bool timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day,
  878. uint8_t hour, uint8_t minute, uint8_t second);
  879. /** Type of file. You should use isFile() or isDir() instead of fileType()
  880. * if possible.
  881. *
  882. * \return The file or directory type.
  883. */
  884. uint8_t fileAttr() const {
  885. return m_attr;
  886. }
  887. /** Truncate a file to a specified length. The current file position
  888. * will be maintained if it is less than or equal to \a length otherwise
  889. * it will be set to end of file.
  890. *
  891. * \param[in] length The desired length for the file.
  892. *
  893. * \return The value true is returned for success and
  894. * the value false is returned for failure.
  895. */
  896. bool truncate(uint32_t length);
  897. /** \return FatVolume that contains this file. */
  898. FatVolume* volume() const {
  899. return m_vol;
  900. }
  901. /** Write a string to a file. Used by the Arduino Print class.
  902. * \param[in] str Pointer to the string.
  903. * Use getWriteError to check for errors.
  904. * \return count of characters written for success or -1 for failure.
  905. */
  906. int write(const char* str) {
  907. return write(str, strlen(str));
  908. }
  909. /** Write a single byte.
  910. * \param[in] b The byte to be written.
  911. * \return +1 for success or -1 for failure.
  912. */
  913. int write(uint8_t b) {
  914. return write(&b, 1);
  915. }
  916. /** Write data to an open file.
  917. *
  918. * \note Data is moved to the cache but may not be written to the
  919. * storage device until sync() is called.
  920. *
  921. * \param[in] buf Pointer to the location of the data to be written.
  922. *
  923. * \param[in] nbyte Number of bytes to write.
  924. *
  925. * \return For success write() returns the number of bytes written, always
  926. * \a nbyte. If an error occurs, write() returns -1. Possible errors
  927. * include write() is called before a file has been opened, write is called
  928. * for a read-only file, device is full, a corrupt file system or an I/O error.
  929. *
  930. */
  931. int write(const void* buf, size_t nbyte);
  932. //------------------------------------------------------------------------------
  933. private:
  934. /** This file has not been opened. */
  935. static const uint8_t FILE_ATTR_CLOSED = 0;
  936. /** File is read-only. */
  937. static const uint8_t FILE_ATTR_READ_ONLY = DIR_ATT_READ_ONLY;
  938. /** File should be hidden in directory listings. */
  939. static const uint8_t FILE_ATTR_HIDDEN = DIR_ATT_HIDDEN;
  940. /** Entry is for a system file. */
  941. static const uint8_t FILE_ATTR_SYSTEM = DIR_ATT_SYSTEM;
  942. /** Entry for normal data file */
  943. static const uint8_t FILE_ATTR_FILE = 0X08;
  944. /** Entry is for a subdirectory */
  945. static const uint8_t FILE_ATTR_SUBDIR = DIR_ATT_DIRECTORY;
  946. /** A FAT12 or FAT16 root directory */
  947. static const uint8_t FILE_ATTR_ROOT_FIXED = 0X20;
  948. /** A FAT32 root directory */
  949. static const uint8_t FILE_ATTR_ROOT32 = 0X40;
  950. /** Entry is for root. */
  951. static const uint8_t FILE_ATTR_ROOT = FILE_ATTR_ROOT_FIXED | FILE_ATTR_ROOT32;
  952. /** Directory type bits */
  953. static const uint8_t FILE_ATTR_DIR = FILE_ATTR_SUBDIR | FILE_ATTR_ROOT;
  954. /** Attributes to copy from directory entry */
  955. static const uint8_t FILE_ATTR_COPY = DIR_ATT_READ_ONLY | DIR_ATT_HIDDEN |
  956. DIR_ATT_SYSTEM | DIR_ATT_DIRECTORY;
  957. /** experimental don't use */
  958. bool openParent(FatFile* dir);
  959. // private functions
  960. bool addCluster();
  961. bool addDirCluster();
  962. dir_t* cacheDirEntry(uint8_t action);
  963. static uint8_t lfnChecksum(uint8_t* name);
  964. bool lfnUniqueSfn(fname_t* fname);
  965. bool openCluster(FatFile* file);
  966. static bool parsePathName(const char* str, fname_t* fname, const char** ptr);
  967. bool mkdir(FatFile* parent, fname_t* fname);
  968. bool open(FatFile* dirFile, fname_t* fname, uint8_t oflag);
  969. bool openCachedEntry(FatFile* dirFile, uint16_t cacheIndex, uint8_t oflag,
  970. uint8_t lfnOrd);
  971. bool readLBN(uint32_t* lbn);
  972. dir_t* readDirCache(bool skipReadOk = false);
  973. bool setDirSize();
  974. // bits defined in m_flags
  975. // should be 0X0F
  976. static const uint8_t F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
  977. // sync of directory entry required
  978. static const uint8_t F_FILE_DIR_DIRTY = 0X80;
  979. // global pointer to cwd dir
  980. static FatFile* m_cwd;
  981. // data time callback function
  982. static void (*m_dateTime)(uint16_t* date, uint16_t* time);
  983. // private data
  984. static const uint8_t WRITE_ERROR = 0X1;
  985. static const uint8_t READ_ERROR = 0X2;
  986. uint8_t m_attr; // File attributes
  987. uint8_t m_error; // Error bits.
  988. uint8_t m_flags; // See above for definition of m_flags bits
  989. uint8_t m_lfnOrd;
  990. uint16_t m_dirIndex; // index of directory entry in dir file
  991. FatVolume* m_vol; // volume where file is located
  992. uint32_t m_dirCluster;
  993. uint32_t m_curCluster; // cluster for current file position
  994. uint32_t m_curPosition; // current file position
  995. uint32_t m_dirBlock; // block for this files directory entry
  996. uint32_t m_fileSize; // file size in bytes
  997. uint32_t m_firstCluster; // first cluster of file
  998. };
  999. #endif // FatFile_h