Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

242 lines
6.7KB

  1. /* FatLib Library
  2. * Copyright (C) 2012 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. #include <math.h>
  21. #include "FatFile.h"
  22. #include "FmtNumber.h"
  23. //------------------------------------------------------------------------------
  24. // print uint8_t with width 2
  25. static void print2u(print_t* pr, uint8_t v) {
  26. char c0 = '?';
  27. char c1 = '?';
  28. if (v < 100) {
  29. c1 = v/10;
  30. c0 = v - 10*c1 + '0';
  31. c1 += '0';
  32. }
  33. pr->write(c1);
  34. pr->write(c0);
  35. }
  36. //------------------------------------------------------------------------------
  37. static void printU32(print_t* pr, uint32_t v) {
  38. char buf[11];
  39. char* ptr = buf + sizeof(buf);
  40. *--ptr = 0;
  41. pr->write(fmtDec(v, ptr));
  42. }
  43. //------------------------------------------------------------------------------
  44. void FatFile::ls(print_t* pr, uint8_t flags, uint8_t indent) {
  45. if (!isDir()) return;
  46. rewind();
  47. int8_t status;
  48. while ((status = lsPrintNext(pr, flags, indent))) {
  49. if (status > 1 && (flags & LS_R)) {
  50. uint16_t index = curPosition()/32 - 1;
  51. FatFile s;
  52. if (s.open(this, index, O_READ)) s.ls(pr, flags, indent + 2);
  53. seekSet(32 * (index + 1));
  54. }
  55. }
  56. }
  57. //------------------------------------------------------------------------------
  58. // saves 32 bytes on stack for ls recursion
  59. // return 0 - EOF, 1 - normal file, or 2 - directory
  60. int8_t FatFile::lsPrintNext(print_t* pr, uint8_t flags, uint8_t indent) {
  61. dir_t dir;
  62. uint8_t w = 0;
  63. while (1) {
  64. if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0;
  65. if (dir.name[0] == DIR_NAME_FREE) return 0;
  66. // skip deleted entry and entries for . and ..
  67. if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.'
  68. && DIR_IS_FILE_OR_SUBDIR(&dir)) break;
  69. }
  70. // indent for dir level
  71. for (uint8_t i = 0; i < indent; i++) pr->write(' ');
  72. // print name
  73. for (uint8_t i = 0; i < 11; i++) {
  74. if (dir.name[i] == ' ')continue;
  75. if (i == 8) {
  76. pr->write('.');
  77. w++;
  78. }
  79. pr->write(dir.name[i]);
  80. w++;
  81. }
  82. if (DIR_IS_SUBDIR(&dir)) {
  83. pr->write('/');
  84. w++;
  85. }
  86. if (flags & (LS_DATE | LS_SIZE)) {
  87. while (w++ < 14) pr->write(' ');
  88. }
  89. // print modify date/time if requested
  90. if (flags & LS_DATE) {
  91. pr->write(' ');
  92. printFatDate(pr, dir.lastWriteDate);
  93. pr->write(' ');
  94. printFatTime(pr, dir.lastWriteTime);
  95. }
  96. // print size if requested
  97. if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) {
  98. pr->write(' ');
  99. printU32(pr, dir.fileSize);
  100. }
  101. pr->write('\r');
  102. pr->write('\n');
  103. return DIR_IS_FILE(&dir) ? 1 : 2;
  104. }
  105. //------------------------------------------------------------------------------
  106. bool FatFile::printCreateDateTime(print_t* pr) {
  107. dir_t dir;
  108. if (!dirEntry(&dir)) {
  109. DBG_FAIL_MACRO;
  110. goto fail;
  111. }
  112. printFatDate(pr, dir.creationDate);
  113. pr->write(' ');
  114. printFatTime(pr, dir.creationTime);
  115. return true;
  116. fail:
  117. return false;
  118. }
  119. //------------------------------------------------------------------------------
  120. void FatFile::printFatDate(print_t* pr, uint16_t fatDate) {
  121. printU32(pr, FAT_YEAR(fatDate));
  122. pr->write('-');
  123. print2u(pr, FAT_MONTH(fatDate));
  124. pr->write('-');
  125. print2u(pr, FAT_DAY(fatDate));
  126. }
  127. //------------------------------------------------------------------------------
  128. void FatFile::printFatTime(print_t* pr, uint16_t fatTime) {
  129. print2u(pr, FAT_HOUR(fatTime));
  130. pr->write(':');
  131. print2u(pr, FAT_MINUTE(fatTime));
  132. pr->write(':');
  133. print2u(pr, FAT_SECOND(fatTime));
  134. }
  135. //------------------------------------------------------------------------------
  136. /** Template for FatFile::printField() */
  137. template <typename Type>
  138. static int printFieldT(FatFile* file, char sign, Type value, char term) {
  139. char buf[3*sizeof(Type) + 3];
  140. char* str = &buf[sizeof(buf)];
  141. if (term) {
  142. *--str = term;
  143. if (term == '\n') {
  144. *--str = '\r';
  145. }
  146. }
  147. #ifdef OLD_FMT
  148. do {
  149. Type m = value;
  150. value /= 10;
  151. *--str = '0' + m - 10*value;
  152. } while (value);
  153. #else // OLD_FMT
  154. str = fmtDec(value, str);
  155. #endif // OLD_FMT
  156. if (sign) {
  157. *--str = sign;
  158. }
  159. return file->write(str, &buf[sizeof(buf)] - str);
  160. }
  161. //------------------------------------------------------------------------------
  162. int FatFile::printField(float value, char term, uint8_t prec) {
  163. char buf[24];
  164. char* str = &buf[sizeof(buf)];
  165. if (term) {
  166. *--str = term;
  167. if (term == '\n') {
  168. *--str = '\r';
  169. }
  170. }
  171. str = fmtFloat(value, str, prec);
  172. return write(str, buf + sizeof(buf) - str);
  173. }
  174. //------------------------------------------------------------------------------
  175. int FatFile::printField(uint16_t value, char term) {
  176. return printFieldT(this, 0, value, term);
  177. }
  178. //------------------------------------------------------------------------------
  179. int FatFile::printField(int16_t value, char term) {
  180. char sign = 0;
  181. if (value < 0) {
  182. sign = '-';
  183. value = -value;
  184. }
  185. return printFieldT(this, sign, (uint16_t)value, term);
  186. }
  187. //------------------------------------------------------------------------------
  188. int FatFile::printField(uint32_t value, char term) {
  189. return printFieldT(this, 0, value, term);
  190. }
  191. //------------------------------------------------------------------------------
  192. int FatFile::printField(int32_t value, char term) {
  193. char sign = 0;
  194. if (value < 0) {
  195. sign = '-';
  196. value = -value;
  197. }
  198. return printFieldT(this, sign, (uint32_t)value, term);
  199. }
  200. //------------------------------------------------------------------------------
  201. bool FatFile::printModifyDateTime(print_t* pr) {
  202. dir_t dir;
  203. if (!dirEntry(&dir)) {
  204. DBG_FAIL_MACRO;
  205. goto fail;
  206. }
  207. printFatDate(pr, dir.lastWriteDate);
  208. pr->write(' ');
  209. printFatTime(pr, dir.lastWriteTime);
  210. return true;
  211. fail:
  212. return false;
  213. }
  214. //------------------------------------------------------------------------------
  215. size_t FatFile::printName(print_t* pr) {
  216. char name[13];
  217. if (!getFilename(name)) {
  218. DBG_FAIL_MACRO;
  219. goto fail;
  220. }
  221. return pr->write(name);
  222. fail:
  223. return 0;
  224. }
  225. //------------------------------------------------------------------------------
  226. size_t FatFile::printFileSize(print_t* pr) {
  227. char buf[11];
  228. char *ptr = buf + sizeof(buf);
  229. *--ptr = 0;
  230. ptr = fmtDec(fileSize(), ptr);
  231. while (ptr > buf) *--ptr = ' ';
  232. return pr->write(buf);
  233. }