source: rtos_arduino/trunk/arduino_lib/libraries/SD/src/utility/SdFile.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 42.2 KB
Line 
1/* Arduino SdFat Library
2 * Copyright (C) 2009 by William Greiman
3 *
4 * This file is part of the Arduino SdFat 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 Arduino SdFat Library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20#include "SdFat.h"
21#ifdef __AVR__
22#include <avr/pgmspace.h>
23#endif
24#include <Arduino.h>
25//------------------------------------------------------------------------------
26// callback function for date/time
27void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL;
28
29#if ALLOW_DEPRECATED_FUNCTIONS
30// suppress cpplint warnings with NOLINT comment
31void (*SdFile::oldDateTime_)(uint16_t& date, uint16_t& time) = NULL; // NOLINT
32#endif // ALLOW_DEPRECATED_FUNCTIONS
33//------------------------------------------------------------------------------
34// add a cluster to a file
35uint8_t SdFile::addCluster() {
36 if (!vol_->allocContiguous(1, &curCluster_)) return false;
37
38 // if first cluster of file link to directory entry
39 if (firstCluster_ == 0) {
40 firstCluster_ = curCluster_;
41 flags_ |= F_FILE_DIR_DIRTY;
42 }
43 return true;
44}
45//------------------------------------------------------------------------------
46// Add a cluster to a directory file and zero the cluster.
47// return with first block of cluster in the cache
48uint8_t SdFile::addDirCluster(void) {
49 if (!addCluster()) return false;
50
51 // zero data in cluster insure first cluster is in cache
52 uint32_t block = vol_->clusterStartBlock(curCluster_);
53 for (uint8_t i = vol_->blocksPerCluster_; i != 0; i--) {
54 if (!SdVolume::cacheZeroBlock(block + i - 1)) return false;
55 }
56 // Increase directory file size by cluster size
57 fileSize_ += 512UL << vol_->clusterSizeShift_;
58 return true;
59}
60//------------------------------------------------------------------------------
61// cache a file's directory entry
62// return pointer to cached entry or null for failure
63dir_t* SdFile::cacheDirEntry(uint8_t action) {
64 if (!SdVolume::cacheRawBlock(dirBlock_, action)) return NULL;
65 return SdVolume::cacheBuffer_.dir + dirIndex_;
66}
67//------------------------------------------------------------------------------
68/**
69 * Close a file and force cached data and directory information
70 * to be written to the storage device.
71 *
72 * \return The value one, true, is returned for success and
73 * the value zero, false, is returned for failure.
74 * Reasons for failure include no file is open or an I/O error.
75 */
76uint8_t SdFile::close(void) {
77 if (!sync())return false;
78 type_ = FAT_FILE_TYPE_CLOSED;
79 return true;
80}
81//------------------------------------------------------------------------------
82/**
83 * Check for contiguous file and return its raw block range.
84 *
85 * \param[out] bgnBlock the first block address for the file.
86 * \param[out] endBlock the last block address for the file.
87 *
88 * \return The value one, true, is returned for success and
89 * the value zero, false, is returned for failure.
90 * Reasons for failure include file is not contiguous, file has zero length
91 * or an I/O error occurred.
92 */
93uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
94 // error if no blocks
95 if (firstCluster_ == 0) return false;
96
97 for (uint32_t c = firstCluster_; ; c++) {
98 uint32_t next;
99 if (!vol_->fatGet(c, &next)) return false;
100
101 // check for contiguous
102 if (next != (c + 1)) {
103 // error if not end of chain
104 if (!vol_->isEOC(next)) return false;
105 *bgnBlock = vol_->clusterStartBlock(firstCluster_);
106 *endBlock = vol_->clusterStartBlock(c)
107 + vol_->blocksPerCluster_ - 1;
108 return true;
109 }
110 }
111}
112//------------------------------------------------------------------------------
113/**
114 * Create and open a new contiguous file of a specified size.
115 *
116 * \note This function only supports short DOS 8.3 names.
117 * See open() for more information.
118 *
119 * \param[in] dirFile The directory where the file will be created.
120 * \param[in] fileName A valid DOS 8.3 file name.
121 * \param[in] size The desired file size.
122 *
123 * \return The value one, true, is returned for success and
124 * the value zero, false, is returned for failure.
125 * Reasons for failure include \a fileName contains
126 * an invalid DOS 8.3 file name, the FAT volume has not been initialized,
127 * a file is already open, the file already exists, the root
128 * directory is full or an I/O error.
129 *
130 */
131uint8_t SdFile::createContiguous(SdFile* dirFile,
132 const char* fileName, uint32_t size) {
133 // don't allow zero length file
134 if (size == 0) return false;
135 if (!open(dirFile, fileName, O_CREAT | O_EXCL | O_RDWR)) return false;
136
137 // calculate number of clusters needed
138 uint32_t count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1;
139
140 // allocate clusters
141 if (!vol_->allocContiguous(count, &firstCluster_)) {
142 remove();
143 return false;
144 }
145 fileSize_ = size;
146
147 // insure sync() will update dir entry
148 flags_ |= F_FILE_DIR_DIRTY;
149 return sync();
150}
151//------------------------------------------------------------------------------
152/**
153 * Return a files directory entry
154 *
155 * \param[out] dir Location for return of the files directory entry.
156 *
157 * \return The value one, true, is returned for success and
158 * the value zero, false, is returned for failure.
159 */
160uint8_t SdFile::dirEntry(dir_t* dir) {
161 // make sure fields on SD are correct
162 if (!sync()) return false;
163
164 // read entry
165 dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
166 if (!p) return false;
167
168 // copy to caller's struct
169 memcpy(dir, p, sizeof(dir_t));
170 return true;
171}
172//------------------------------------------------------------------------------
173/**
174 * Format the name field of \a dir into the 13 byte array
175 * \a name in standard 8.3 short name format.
176 *
177 * \param[in] dir The directory structure containing the name.
178 * \param[out] name A 13 byte char array for the formatted name.
179 */
180void SdFile::dirName(const dir_t& dir, char* name) {
181 uint8_t j = 0;
182 for (uint8_t i = 0; i < 11; i++) {
183 if (dir.name[i] == ' ')continue;
184 if (i == 8) name[j++] = '.';
185 name[j++] = dir.name[i];
186 }
187 name[j] = 0;
188}
189//------------------------------------------------------------------------------
190/** List directory contents to Serial.
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 * \param[in] indent Amount of space before file name. Used for recursive
201 * list to indicate subdirectory level.
202 */
203void SdFile::ls(uint8_t flags, uint8_t indent) {
204 dir_t* p;
205 rewind();
206 while ((p = readDirCache())) {
207 // done if past last used entry
208 if (p->name[0] == DIR_NAME_FREE) break;
209 // skip deleted entry and entries for . and ..
210 if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
211 // only list subdirectories and files
212 if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
213 // print any indent spaces
214 #if defined(ARDUINO_ARCH_SAMD)
215 for (int8_t i = 0; i < indent; i++) SerialUSB.print(' ');
216 #else
217 for (int8_t i = 0; i < indent; i++) Serial.print(' ');
218 #endif
219
220 // print file name with possible blank fill
221 printDirName(*p, flags & (LS_DATE | LS_SIZE) ? 14 : 0);
222
223 // print modify date/time if requested
224 if (flags & LS_DATE) {
225 printFatDate(p->lastWriteDate);
226 #if defined(ARDUINO_ARCH_SAMD)
227 SerialUSB.print(' ');
228 #else
229 Serial.print(' ');
230 #endif
231 printFatTime(p->lastWriteTime);
232
233 }
234 // print size if requested
235 if (!DIR_IS_SUBDIR(p) && (flags & LS_SIZE)) {
236 #if defined(ARDUINO_ARCH_SAMD)
237 SerialUSB.print(' ');
238 SerialUSB.print(p->fileSize);
239 #else
240 Serial.print(' ');
241 Serial.print(p->fileSize);
242 #endif
243 }
244 #if defined(ARDUINO_ARCH_SAMD)
245 SerialUSB.println();
246 #else
247 Serial.println();
248 #endif
249
250 // list subdirectory content if requested
251 if ((flags & LS_R) && DIR_IS_SUBDIR(p)) {
252 uint16_t index = curPosition()/32 - 1;
253 SdFile s;
254 if (s.open(this, index, O_READ)) s.ls(flags, indent + 2);
255 seekSet(32 * (index + 1));
256 }
257 }
258}
259//------------------------------------------------------------------------------
260// format directory name field from a 8.3 name string
261uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
262 uint8_t c;
263 uint8_t n = 7; // max index for part before dot
264 uint8_t i = 0;
265 // blank fill name and extension
266 while (i < 11) name[i++] = ' ';
267 i = 0;
268 while ((c = *str++) != '\0') {
269 if (c == '.') {
270 if (n == 10) return false; // only one dot allowed
271 n = 10; // max index for full 8.3 name
272 i = 8; // place for extension
273 } else {
274 // illegal FAT characters
275 uint8_t b;
276#if defined(__AVR__)
277 PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
278 while ((b = pgm_read_byte(p++))) if (b == c) return false;
279#elif defined(__arm__)
280 const uint8_t valid[] = "|<>^+=?/[];,*\"\\";
281 const uint8_t *p = valid;
282 while ((b = *p++)) if (b == c) return false;
283#endif
284 // check size and only allow ASCII printable characters
285 if (i > n || c < 0X21 || c > 0X7E)return false;
286 // only upper case allowed in 8.3 names - convert lower to upper
287 name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a');
288 }
289 }
290 // must have a file name, extension is optional
291 return name[0] != ' ';
292}
293//------------------------------------------------------------------------------
294/** Make a new directory.
295 *
296 * \param[in] dir An open SdFat instance for the directory that will containing
297 * the new directory.
298 *
299 * \param[in] dirName A valid 8.3 DOS name for the new directory.
300 *
301 * \return The value one, true, is returned for success and
302 * the value zero, false, is returned for failure.
303 * Reasons for failure include this SdFile is already open, \a dir is not a
304 * directory, \a dirName is invalid or already exists in \a dir.
305 */
306uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) {
307 dir_t d;
308
309 // create a normal file
310 if (!open(dir, dirName, O_CREAT | O_EXCL | O_RDWR)) return false;
311
312 // convert SdFile to directory
313 flags_ = O_READ;
314 type_ = FAT_FILE_TYPE_SUBDIR;
315
316 // allocate and zero first cluster
317 if (!addDirCluster())return false;
318
319 // force entry to SD
320 if (!sync()) return false;
321
322 // cache entry - should already be in cache due to sync() call
323 dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
324 if (!p) return false;
325
326 // change directory entry attribute
327 p->attributes = DIR_ATT_DIRECTORY;
328
329 // make entry for '.'
330 memcpy(&d, p, sizeof(d));
331 for (uint8_t i = 1; i < 11; i++) d.name[i] = ' ';
332 d.name[0] = '.';
333
334 // cache block for '.' and '..'
335 uint32_t block = vol_->clusterStartBlock(firstCluster_);
336 if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
337
338 // copy '.' to block
339 memcpy(&SdVolume::cacheBuffer_.dir[0], &d, sizeof(d));
340
341 // make entry for '..'
342 d.name[1] = '.';
343 if (dir->isRoot()) {
344 d.firstClusterLow = 0;
345 d.firstClusterHigh = 0;
346 } else {
347 d.firstClusterLow = dir->firstCluster_ & 0XFFFF;
348 d.firstClusterHigh = dir->firstCluster_ >> 16;
349 }
350 // copy '..' to block
351 memcpy(&SdVolume::cacheBuffer_.dir[1], &d, sizeof(d));
352
353 // set position after '..'
354 curPosition_ = 2 * sizeof(d);
355
356 // write first block
357 return SdVolume::cacheFlush();
358}
359//------------------------------------------------------------------------------
360/**
361 * Open a file or directory by name.
362 *
363 * \param[in] dirFile An open SdFat instance for the directory containing the
364 * file to be opened.
365 *
366 * \param[in] fileName A valid 8.3 DOS name for a file to be opened.
367 *
368 * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
369 * OR of flags from the following list
370 *
371 * O_READ - Open for reading.
372 *
373 * O_RDONLY - Same as O_READ.
374 *
375 * O_WRITE - Open for writing.
376 *
377 * O_WRONLY - Same as O_WRITE.
378 *
379 * O_RDWR - Open for reading and writing.
380 *
381 * O_APPEND - If set, the file offset shall be set to the end of the
382 * file prior to each write.
383 *
384 * O_CREAT - If the file exists, this flag has no effect except as noted
385 * under O_EXCL below. Otherwise, the file shall be created
386 *
387 * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
388 *
389 * O_SYNC - Call sync() after each write. This flag should not be used with
390 * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
391 * These functions do character at a time writes so sync() will be called
392 * after each byte.
393 *
394 * O_TRUNC - If the file exists and is a regular file, and the file is
395 * successfully opened and is not read only, its length shall be truncated to 0.
396 *
397 * \note Directory files must be opened read only. Write and truncation is
398 * not allowed for directory files.
399 *
400 * \return The value one, true, is returned for success and
401 * the value zero, false, is returned for failure.
402 * Reasons for failure include this SdFile is already open, \a difFile is not
403 * a directory, \a fileName is invalid, the file does not exist
404 * or can't be opened in the access mode specified by oflag.
405 */
406uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) {
407 uint8_t dname[11];
408 dir_t* p;
409
410 // error if already open
411 if (isOpen())return false;
412
413 if (!make83Name(fileName, dname)) return false;
414 vol_ = dirFile->vol_;
415 dirFile->rewind();
416
417 // bool for empty entry found
418 uint8_t emptyFound = false;
419
420 // search for file
421 while (dirFile->curPosition_ < dirFile->fileSize_) {
422 uint8_t index = 0XF & (dirFile->curPosition_ >> 5);
423 p = dirFile->readDirCache();
424 if (p == NULL) return false;
425
426 if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
427 // remember first empty slot
428 if (!emptyFound) {
429 emptyFound = true;
430 dirIndex_ = index;
431 dirBlock_ = SdVolume::cacheBlockNumber_;
432 }
433 // done if no entries follow
434 if (p->name[0] == DIR_NAME_FREE) break;
435 } else if (!memcmp(dname, p->name, 11)) {
436 // don't open existing file if O_CREAT and O_EXCL
437 if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
438
439 // open found file
440 return openCachedEntry(0XF & index, oflag);
441 }
442 }
443 // only create file if O_CREAT and O_WRITE
444 if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
445
446 // cache found slot or add cluster if end of file
447 if (emptyFound) {
448 p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
449 if (!p) return false;
450 } else {
451 if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false;
452
453 // add and zero cluster for dirFile - first cluster is in cache for write
454 if (!dirFile->addDirCluster()) return false;
455
456 // use first entry in cluster
457 dirIndex_ = 0;
458 p = SdVolume::cacheBuffer_.dir;
459 }
460 // initialize as empty file
461 memset(p, 0, sizeof(dir_t));
462 memcpy(p->name, dname, 11);
463
464 // set timestamps
465 if (dateTime_) {
466 // call user function
467 dateTime_(&p->creationDate, &p->creationTime);
468 } else {
469 // use default date/time
470 p->creationDate = FAT_DEFAULT_DATE;
471 p->creationTime = FAT_DEFAULT_TIME;
472 }
473 p->lastAccessDate = p->creationDate;
474 p->lastWriteDate = p->creationDate;
475 p->lastWriteTime = p->creationTime;
476
477 // force write of entry to SD
478 if (!SdVolume::cacheFlush()) return false;
479
480 // open entry in cache
481 return openCachedEntry(dirIndex_, oflag);
482}
483//------------------------------------------------------------------------------
484/**
485 * Open a file by index.
486 *
487 * \param[in] dirFile An open SdFat instance for the directory.
488 *
489 * \param[in] index The \a index of the directory entry for the file to be
490 * opened. The value for \a index is (directory file position)/32.
491 *
492 * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
493 * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
494 *
495 * See open() by fileName for definition of flags and return values.
496 *
497 */
498uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) {
499 // error if already open
500 if (isOpen())return false;
501
502 // don't open existing file if O_CREAT and O_EXCL - user call error
503 if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
504
505 vol_ = dirFile->vol_;
506
507 // seek to location of entry
508 if (!dirFile->seekSet(32 * index)) return false;
509
510 // read entry into cache
511 dir_t* p = dirFile->readDirCache();
512 if (p == NULL) return false;
513
514 // error if empty slot or '.' or '..'
515 if (p->name[0] == DIR_NAME_FREE ||
516 p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
517 return false;
518 }
519 // open cached entry
520 return openCachedEntry(index & 0XF, oflag);
521}
522//------------------------------------------------------------------------------
523// open a cached directory entry. Assumes vol_ is initializes
524uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
525 // location of entry in cache
526 dir_t* p = SdVolume::cacheBuffer_.dir + dirIndex;
527
528 // write or truncate is an error for a directory or read-only file
529 if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
530 if (oflag & (O_WRITE | O_TRUNC)) return false;
531 }
532 // remember location of directory entry on SD
533 dirIndex_ = dirIndex;
534 dirBlock_ = SdVolume::cacheBlockNumber_;
535
536 // copy first cluster number for directory fields
537 firstCluster_ = (uint32_t)p->firstClusterHigh << 16;
538 firstCluster_ |= p->firstClusterLow;
539
540 // make sure it is a normal file or subdirectory
541 if (DIR_IS_FILE(p)) {
542 fileSize_ = p->fileSize;
543 type_ = FAT_FILE_TYPE_NORMAL;
544 } else if (DIR_IS_SUBDIR(p)) {
545 if (!vol_->chainSize(firstCluster_, &fileSize_)) return false;
546 type_ = FAT_FILE_TYPE_SUBDIR;
547 } else {
548 return false;
549 }
550 // save open flags for read/write
551 flags_ = oflag & (O_ACCMODE | O_SYNC | O_APPEND);
552
553 // set to start of file
554 curCluster_ = 0;
555 curPosition_ = 0;
556
557 // truncate file to zero length if requested
558 if (oflag & O_TRUNC) return truncate(0);
559 return true;
560}
561//------------------------------------------------------------------------------
562/**
563 * Open a volume's root directory.
564 *
565 * \param[in] vol The FAT volume containing the root directory to be opened.
566 *
567 * \return The value one, true, is returned for success and
568 * the value zero, false, is returned for failure.
569 * Reasons for failure include the FAT volume has not been initialized
570 * or it a FAT12 volume.
571 */
572uint8_t SdFile::openRoot(SdVolume* vol) {
573 // error if file is already open
574 if (isOpen()) return false;
575
576 if (vol->fatType() == 16) {
577 type_ = FAT_FILE_TYPE_ROOT16;
578 firstCluster_ = 0;
579 fileSize_ = 32 * vol->rootDirEntryCount();
580 } else if (vol->fatType() == 32) {
581 type_ = FAT_FILE_TYPE_ROOT32;
582 firstCluster_ = vol->rootDirStart();
583 if (!vol->chainSize(firstCluster_, &fileSize_)) return false;
584 } else {
585 // volume is not initialized or FAT12
586 return false;
587 }
588 vol_ = vol;
589 // read only
590 flags_ = O_READ;
591
592 // set to start of file
593 curCluster_ = 0;
594 curPosition_ = 0;
595
596 // root has no directory entry
597 dirBlock_ = 0;
598 dirIndex_ = 0;
599 return true;
600}
601//------------------------------------------------------------------------------
602/** %Print the name field of a directory entry in 8.3 format to Serial.
603 *
604 * \param[in] dir The directory structure containing the name.
605 * \param[in] width Blank fill name if length is less than \a width.
606 */
607void SdFile::printDirName(const dir_t& dir, uint8_t width) {
608 uint8_t w = 0;
609 for (uint8_t i = 0; i < 11; i++) {
610 if (dir.name[i] == ' ')continue;
611 if (i == 8) {
612 #if defined(ARDUINO_ARCH_SAMD)
613 SerialUSB.print('.');
614 #else
615 Serial.print('.');
616 #endif
617 w++;
618 }
619 #if defined(ARDUINO_ARCH_SAMD)
620 SerialUSB.write(dir.name[i]);
621 #else
622 Serial.write(dir.name[i]);
623 #endif
624 w++;
625 }
626 if (DIR_IS_SUBDIR(&dir)) {
627 #if defined(ARDUINO_ARCH_SAMD)
628 SerialUSB.print('/');
629 #else
630 Serial.print('/');
631 #endif
632 w++;
633 }
634 while (w < width) {
635 #if defined(ARDUINO_ARCH_SAMD)
636 SerialUSB.print(' ');
637 #else
638 Serial.print(' ');
639 #endif
640 w++;
641 }
642}
643//------------------------------------------------------------------------------
644/** %Print a directory date field to Serial.
645 *
646 * Format is yyyy-mm-dd.
647 *
648 * \param[in] fatDate The date field from a directory entry.
649 */
650void SdFile::printFatDate(uint16_t fatDate) {
651
652 #if defined(ARDUINO_ARCH_SAMD)
653 SerialUSB.print(FAT_YEAR(fatDate));
654 SerialUSB.print('-');
655 #else
656 Serial.print(FAT_YEAR(fatDate));
657 Serial.print('-');
658 #endif
659 printTwoDigits(FAT_MONTH(fatDate));
660 #if defined(ARDUINO_ARCH_SAMD)
661 SerialUSB.print('-');
662 #else
663 Serial.print('-');
664 #endif
665 printTwoDigits(FAT_DAY(fatDate));
666}
667//------------------------------------------------------------------------------
668/** %Print a directory time field to Serial.
669 *
670 * Format is hh:mm:ss.
671 *
672 * \param[in] fatTime The time field from a directory entry.
673 */
674void SdFile::printFatTime(uint16_t fatTime) {
675 printTwoDigits(FAT_HOUR(fatTime));
676 #if defined(ARDUINO_ARCH_SAMD)
677 SerialUSB.print(':');
678 #else
679 Serial.print(':');
680 #endif
681 printTwoDigits(FAT_MINUTE(fatTime));
682 #if defined(ARDUINO_ARCH_SAMD)
683 SerialUSB.print(':');
684 #else
685 Serial.print(':');
686 #endif
687 printTwoDigits(FAT_SECOND(fatTime));
688}
689//------------------------------------------------------------------------------
690/** %Print a value as two digits to Serial.
691 *
692 * \param[in] v Value to be printed, 0 <= \a v <= 99
693 */
694void SdFile::printTwoDigits(uint8_t v) {
695 char str[3];
696 str[0] = '0' + v/10;
697 str[1] = '0' + v % 10;
698 str[2] = 0;
699 #if defined(ARDUINO_ARCH_SAMD)
700 SerialUSB.print(str);
701 #else
702 Serial.print(str);
703 #endif
704
705}
706//------------------------------------------------------------------------------
707/**
708 * Read data from a file starting at the current position.
709 *
710 * \param[out] buf Pointer to the location that will receive the data.
711 *
712 * \param[in] nbyte Maximum number of bytes to read.
713 *
714 * \return For success read() returns the number of bytes read.
715 * A value less than \a nbyte, including zero, will be returned
716 * if end of file is reached.
717 * If an error occurs, read() returns -1. Possible errors include
718 * read() called before a file has been opened, corrupt file system
719 * or an I/O error occurred.
720 */
721int16_t SdFile::read(void* buf, uint16_t nbyte) {
722 uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
723
724 // error if not open or write only
725 if (!isOpen() || !(flags_ & O_READ)) return -1;
726
727 // max bytes left in file
728 if (nbyte > (fileSize_ - curPosition_)) nbyte = fileSize_ - curPosition_;
729
730 // amount left to read
731 uint16_t toRead = nbyte;
732 while (toRead > 0) {
733 uint32_t block; // raw device block number
734 uint16_t offset = curPosition_ & 0X1FF; // offset in block
735 if (type_ == FAT_FILE_TYPE_ROOT16) {
736 block = vol_->rootDirStart() + (curPosition_ >> 9);
737 } else {
738 uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
739 if (offset == 0 && blockOfCluster == 0) {
740 // start of new cluster
741 if (curPosition_ == 0) {
742 // use first cluster in file
743 curCluster_ = firstCluster_;
744 } else {
745 // get next cluster from FAT
746 if (!vol_->fatGet(curCluster_, &curCluster_)) return -1;
747 }
748 }
749 block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
750 }
751 uint16_t n = toRead;
752
753 // amount to be read from current block
754 if (n > (512 - offset)) n = 512 - offset;
755
756 // no buffering needed if n == 512 or user requests no buffering
757 if ((unbufferedRead() || n == 512) &&
758 block != SdVolume::cacheBlockNumber_) {
759 if (!vol_->readData(block, offset, n, dst)) return -1;
760 dst += n;
761 } else {
762 // read block to cache and copy data to caller
763 if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1;
764 uint8_t* src = SdVolume::cacheBuffer_.data + offset;
765 uint8_t* end = src + n;
766 while (src != end) *dst++ = *src++;
767 }
768 curPosition_ += n;
769 toRead -= n;
770 }
771 return nbyte;
772}
773//------------------------------------------------------------------------------
774/**
775 * Read the next directory entry from a directory file.
776 *
777 * \param[out] dir The dir_t struct that will receive the data.
778 *
779 * \return For success readDir() returns the number of bytes read.
780 * A value of zero will be returned if end of file is reached.
781 * If an error occurs, readDir() returns -1. Possible errors include
782 * readDir() called before a directory has been opened, this is not
783 * a directory file or an I/O error occurred.
784 */
785int8_t SdFile::readDir(dir_t* dir) {
786 int8_t n;
787 // if not a directory file or miss-positioned return an error
788 if (!isDir() || (0X1F & curPosition_)) return -1;
789
790 while ((n = read(dir, sizeof(dir_t))) == sizeof(dir_t)) {
791 // last entry if DIR_NAME_FREE
792 if (dir->name[0] == DIR_NAME_FREE) break;
793 // skip empty entries and entry for . and ..
794 if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue;
795 // return if normal file or subdirectory
796 if (DIR_IS_FILE_OR_SUBDIR(dir)) return n;
797 }
798 // error, end of file, or past last entry
799 return n < 0 ? -1 : 0;
800}
801//------------------------------------------------------------------------------
802// Read next directory entry into the cache
803// Assumes file is correctly positioned
804dir_t* SdFile::readDirCache(void) {
805 // error if not directory
806 if (!isDir()) return NULL;
807
808 // index of entry in cache
809 uint8_t i = (curPosition_ >> 5) & 0XF;
810
811 // use read to locate and cache block
812 if (read() < 0) return NULL;
813
814 // advance to next entry
815 curPosition_ += 31;
816
817 // return pointer to entry
818 return (SdVolume::cacheBuffer_.dir + i);
819}
820//------------------------------------------------------------------------------
821/**
822 * Remove a file.
823 *
824 * The directory entry and all data for the file are deleted.
825 *
826 * \note This function should not be used to delete the 8.3 version of a
827 * file that has a long name. For example if a file has the long name
828 * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
829 *
830 * \return The value one, true, is returned for success and
831 * the value zero, false, is returned for failure.
832 * Reasons for failure include the file read-only, is a directory,
833 * or an I/O error occurred.
834 */
835uint8_t SdFile::remove(void) {
836 // free any clusters - will fail if read-only or directory
837 if (!truncate(0)) return false;
838
839 // cache directory entry
840 dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
841 if (!d) return false;
842
843 // mark entry deleted
844 d->name[0] = DIR_NAME_DELETED;
845
846 // set this SdFile closed
847 type_ = FAT_FILE_TYPE_CLOSED;
848
849 // write entry to SD
850 return SdVolume::cacheFlush();
851}
852//------------------------------------------------------------------------------
853/**
854 * Remove a file.
855 *
856 * The directory entry and all data for the file are deleted.
857 *
858 * \param[in] dirFile The directory that contains the file.
859 * \param[in] fileName The name of the file to be removed.
860 *
861 * \note This function should not be used to delete the 8.3 version of a
862 * file that has a long name. For example if a file has the long name
863 * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
864 *
865 * \return The value one, true, is returned for success and
866 * the value zero, false, is returned for failure.
867 * Reasons for failure include the file is a directory, is read only,
868 * \a dirFile is not a directory, \a fileName is not found
869 * or an I/O error occurred.
870 */
871uint8_t SdFile::remove(SdFile* dirFile, const char* fileName) {
872 SdFile file;
873 if (!file.open(dirFile, fileName, O_WRITE)) return false;
874 return file.remove();
875}
876//------------------------------------------------------------------------------
877/** Remove a directory file.
878 *
879 * The directory file will be removed only if it is empty and is not the
880 * root directory. rmDir() follows DOS and Windows and ignores the
881 * read-only attribute for the directory.
882 *
883 * \note This function should not be used to delete the 8.3 version of a
884 * directory that has a long name. For example if a directory has the
885 * long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
886 *
887 * \return The value one, true, is returned for success and
888 * the value zero, false, is returned for failure.
889 * Reasons for failure include the file is not a directory, is the root
890 * directory, is not empty, or an I/O error occurred.
891 */
892uint8_t SdFile::rmDir(void) {
893 // must be open subdirectory
894 if (!isSubDir()) return false;
895
896 rewind();
897
898 // make sure directory is empty
899 while (curPosition_ < fileSize_) {
900 dir_t* p = readDirCache();
901 if (p == NULL) return false;
902 // done if past last used entry
903 if (p->name[0] == DIR_NAME_FREE) break;
904 // skip empty slot or '.' or '..'
905 if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
906 // error not empty
907 if (DIR_IS_FILE_OR_SUBDIR(p)) return false;
908 }
909 // convert empty directory to normal file for remove
910 type_ = FAT_FILE_TYPE_NORMAL;
911 flags_ |= O_WRITE;
912 return remove();
913}
914//------------------------------------------------------------------------------
915/** Recursively delete a directory and all contained files.
916 *
917 * This is like the Unix/Linux 'rm -rf *' if called with the root directory
918 * hence the name.
919 *
920 * Warning - This will remove all contents of the directory including
921 * subdirectories. The directory will then be removed if it is not root.
922 * The read-only attribute for files will be ignored.
923 *
924 * \note This function should not be used to delete the 8.3 version of
925 * a directory that has a long name. See remove() and rmDir().
926 *
927 * \return The value one, true, is returned for success and
928 * the value zero, false, is returned for failure.
929 */
930uint8_t SdFile::rmRfStar(void) {
931 rewind();
932 while (curPosition_ < fileSize_) {
933 SdFile f;
934
935 // remember position
936 uint16_t index = curPosition_/32;
937
938 dir_t* p = readDirCache();
939 if (!p) return false;
940
941 // done if past last entry
942 if (p->name[0] == DIR_NAME_FREE) break;
943
944 // skip empty slot or '.' or '..'
945 if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
946
947 // skip if part of long file name or volume label in root
948 if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
949
950 if (!f.open(this, index, O_READ)) return false;
951 if (f.isSubDir()) {
952 // recursively delete
953 if (!f.rmRfStar()) return false;
954 } else {
955 // ignore read-only
956 f.flags_ |= O_WRITE;
957 if (!f.remove()) return false;
958 }
959 // position to next entry if required
960 if (curPosition_ != (32*(index + 1))) {
961 if (!seekSet(32*(index + 1))) return false;
962 }
963 }
964 // don't try to delete root
965 if (isRoot()) return true;
966 return rmDir();
967}
968//------------------------------------------------------------------------------
969/**
970 * Sets a file's position.
971 *
972 * \param[in] pos The new position in bytes from the beginning of the file.
973 *
974 * \return The value one, true, is returned for success and
975 * the value zero, false, is returned for failure.
976 */
977uint8_t SdFile::seekSet(uint32_t pos) {
978 // error if file not open or seek past end of file
979 if (!isOpen() || pos > fileSize_) return false;
980
981 if (type_ == FAT_FILE_TYPE_ROOT16) {
982 curPosition_ = pos;
983 return true;
984 }
985 if (pos == 0) {
986 // set position to start of file
987 curCluster_ = 0;
988 curPosition_ = 0;
989 return true;
990 }
991 // calculate cluster index for cur and new position
992 uint32_t nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9);
993 uint32_t nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9);
994
995 if (nNew < nCur || curPosition_ == 0) {
996 // must follow chain from first cluster
997 curCluster_ = firstCluster_;
998 } else {
999 // advance from curPosition
1000 nNew -= nCur;
1001 }
1002 while (nNew--) {
1003 if (!vol_->fatGet(curCluster_, &curCluster_)) return false;
1004 }
1005 curPosition_ = pos;
1006 return true;
1007}
1008//------------------------------------------------------------------------------
1009/**
1010 * The sync() call causes all modified data and directory fields
1011 * to be written to the storage device.
1012 *
1013 * \return The value one, true, is returned for success and
1014 * the value zero, false, is returned for failure.
1015 * Reasons for failure include a call to sync() before a file has been
1016 * opened or an I/O error.
1017 */
1018uint8_t SdFile::sync(void) {
1019 // only allow open files and directories
1020 if (!isOpen()) return false;
1021
1022 if (flags_ & F_FILE_DIR_DIRTY) {
1023 dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
1024 if (!d) return false;
1025
1026 // do not set filesize for dir files
1027 if (!isDir()) d->fileSize = fileSize_;
1028
1029 // update first cluster fields
1030 d->firstClusterLow = firstCluster_ & 0XFFFF;
1031 d->firstClusterHigh = firstCluster_ >> 16;
1032
1033 // set modify time if user supplied a callback date/time function
1034 if (dateTime_) {
1035 dateTime_(&d->lastWriteDate, &d->lastWriteTime);
1036 d->lastAccessDate = d->lastWriteDate;
1037 }
1038 // clear directory dirty
1039 flags_ &= ~F_FILE_DIR_DIRTY;
1040 }
1041 return SdVolume::cacheFlush();
1042}
1043//------------------------------------------------------------------------------
1044/**
1045 * Set a file's timestamps in its directory entry.
1046 *
1047 * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive
1048 * OR of flags from the following list
1049 *
1050 * T_ACCESS - Set the file's last access date.
1051 *
1052 * T_CREATE - Set the file's creation date and time.
1053 *
1054 * T_WRITE - Set the file's last write/modification date and time.
1055 *
1056 * \param[in] year Valid range 1980 - 2107 inclusive.
1057 *
1058 * \param[in] month Valid range 1 - 12 inclusive.
1059 *
1060 * \param[in] day Valid range 1 - 31 inclusive.
1061 *
1062 * \param[in] hour Valid range 0 - 23 inclusive.
1063 *
1064 * \param[in] minute Valid range 0 - 59 inclusive.
1065 *
1066 * \param[in] second Valid range 0 - 59 inclusive
1067 *
1068 * \note It is possible to set an invalid date since there is no check for
1069 * the number of days in a month.
1070 *
1071 * \note
1072 * Modify and access timestamps may be overwritten if a date time callback
1073 * function has been set by dateTimeCallback().
1074 *
1075 * \return The value one, true, is returned for success and
1076 * the value zero, false, is returned for failure.
1077 */
1078uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
1079 uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
1080 if (!isOpen()
1081 || year < 1980
1082 || year > 2107
1083 || month < 1
1084 || month > 12
1085 || day < 1
1086 || day > 31
1087 || hour > 23
1088 || minute > 59
1089 || second > 59) {
1090 return false;
1091 }
1092 dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
1093 if (!d) return false;
1094
1095 uint16_t dirDate = FAT_DATE(year, month, day);
1096 uint16_t dirTime = FAT_TIME(hour, minute, second);
1097 if (flags & T_ACCESS) {
1098 d->lastAccessDate = dirDate;
1099 }
1100 if (flags & T_CREATE) {
1101 d->creationDate = dirDate;
1102 d->creationTime = dirTime;
1103 // seems to be units of 1/100 second not 1/10 as Microsoft states
1104 d->creationTimeTenths = second & 1 ? 100 : 0;
1105 }
1106 if (flags & T_WRITE) {
1107 d->lastWriteDate = dirDate;
1108 d->lastWriteTime = dirTime;
1109 }
1110 SdVolume::cacheSetDirty();
1111 return sync();
1112}
1113//------------------------------------------------------------------------------
1114/**
1115 * Truncate a file to a specified length. The current file position
1116 * will be maintained if it is less than or equal to \a length otherwise
1117 * it will be set to end of file.
1118 *
1119 * \param[in] length The desired length for the file.
1120 *
1121 * \return The value one, true, is returned for success and
1122 * the value zero, false, is returned for failure.
1123 * Reasons for failure include file is read only, file is a directory,
1124 * \a length is greater than the current file size or an I/O error occurs.
1125 */
1126uint8_t SdFile::truncate(uint32_t length) {
1127// error if not a normal file or read-only
1128 if (!isFile() || !(flags_ & O_WRITE)) return false;
1129
1130 // error if length is greater than current size
1131 if (length > fileSize_) return false;
1132
1133 // fileSize and length are zero - nothing to do
1134 if (fileSize_ == 0) return true;
1135
1136 // remember position for seek after truncation
1137 uint32_t newPos = curPosition_ > length ? length : curPosition_;
1138
1139 // position to last cluster in truncated file
1140 if (!seekSet(length)) return false;
1141
1142 if (length == 0) {
1143 // free all clusters
1144 if (!vol_->freeChain(firstCluster_)) return false;
1145 firstCluster_ = 0;
1146 } else {
1147 uint32_t toFree;
1148 if (!vol_->fatGet(curCluster_, &toFree)) return false;
1149
1150 if (!vol_->isEOC(toFree)) {
1151 // free extra clusters
1152 if (!vol_->freeChain(toFree)) return false;
1153
1154 // current cluster is end of chain
1155 if (!vol_->fatPutEOC(curCluster_)) return false;
1156 }
1157 }
1158 fileSize_ = length;
1159
1160 // need to update directory entry
1161 flags_ |= F_FILE_DIR_DIRTY;
1162
1163 if (!sync()) return false;
1164
1165 // set file to correct position
1166 return seekSet(newPos);
1167}
1168//------------------------------------------------------------------------------
1169/**
1170 * Write data to an open file.
1171 *
1172 * \note Data is moved to the cache but may not be written to the
1173 * storage device until sync() is called.
1174 *
1175 * \param[in] buf Pointer to the location of the data to be written.
1176 *
1177 * \param[in] nbyte Number of bytes to write.
1178 *
1179 * \return For success write() returns the number of bytes written, always
1180 * \a nbyte. If an error occurs, write() returns -1. Possible errors
1181 * include write() is called before a file has been opened, write is called
1182 * for a read-only file, device is full, a corrupt file system or an I/O error.
1183 *
1184 */
1185size_t SdFile::write(const void* buf, uint16_t nbyte) {
1186 // convert void* to uint8_t* - must be before goto statements
1187 const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
1188
1189 // number of bytes left to write - must be before goto statements
1190 uint16_t nToWrite = nbyte;
1191
1192 // error if not a normal file or is read-only
1193 if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn;
1194
1195 // seek to end of file if append flag
1196 if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
1197 if (!seekEnd()) goto writeErrorReturn;
1198 }
1199
1200 while (nToWrite > 0) {
1201 uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
1202 uint16_t blockOffset = curPosition_ & 0X1FF;
1203 if (blockOfCluster == 0 && blockOffset == 0) {
1204 // start of new cluster
1205 if (curCluster_ == 0) {
1206 if (firstCluster_ == 0) {
1207 // allocate first cluster of file
1208 if (!addCluster()) goto writeErrorReturn;
1209 } else {
1210 curCluster_ = firstCluster_;
1211 }
1212 } else {
1213 uint32_t next;
1214 if (!vol_->fatGet(curCluster_, &next)) return false;
1215 if (vol_->isEOC(next)) {
1216 // add cluster if at end of chain
1217 if (!addCluster()) goto writeErrorReturn;
1218 } else {
1219 curCluster_ = next;
1220 }
1221 }
1222 }
1223 // max space in block
1224 uint16_t n = 512 - blockOffset;
1225
1226 // lesser of space and amount to write
1227 if (n > nToWrite) n = nToWrite;
1228
1229 // block for data write
1230 uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
1231 if (n == 512) {
1232 // full block - don't need to use cache
1233 // invalidate cache if block is in cache
1234 if (SdVolume::cacheBlockNumber_ == block) {
1235 SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
1236 }
1237 if (!vol_->writeBlock(block, src)) goto writeErrorReturn;
1238 src += 512;
1239 } else {
1240 if (blockOffset == 0 && curPosition_ >= fileSize_) {
1241 // start of new block don't need to read into cache
1242 if (!SdVolume::cacheFlush()) goto writeErrorReturn;
1243 SdVolume::cacheBlockNumber_ = block;
1244 SdVolume::cacheSetDirty();
1245 } else {
1246 // rewrite part of block
1247 if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) {
1248 goto writeErrorReturn;
1249 }
1250 }
1251 uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset;
1252 uint8_t* end = dst + n;
1253 while (dst != end) *dst++ = *src++;
1254 }
1255 nToWrite -= n;
1256 curPosition_ += n;
1257 }
1258 if (curPosition_ > fileSize_) {
1259 // update fileSize and insure sync will update dir entry
1260 fileSize_ = curPosition_;
1261 flags_ |= F_FILE_DIR_DIRTY;
1262 } else if (dateTime_ && nbyte) {
1263 // insure sync will update modified date and time
1264 flags_ |= F_FILE_DIR_DIRTY;
1265 }
1266
1267 if (flags_ & O_SYNC) {
1268 if (!sync()) goto writeErrorReturn;
1269 }
1270 return nbyte;
1271
1272 writeErrorReturn:
1273 // return for write error
1274 //writeError = true;
1275 setWriteError();
1276 return 0;
1277}
1278//------------------------------------------------------------------------------
1279/**
1280 * Write a byte to a file. Required by the Arduino Print class.
1281 *
1282 * Use SdFile::writeError to check for errors.
1283 */
1284size_t SdFile::write(uint8_t b) {
1285 return write(&b, 1);
1286}
1287//------------------------------------------------------------------------------
1288/**
1289 * Write a string to a file. Used by the Arduino Print class.
1290 *
1291 * Use SdFile::writeError to check for errors.
1292 */
1293size_t SdFile::write(const char* str) {
1294 return write(str, strlen(str));
1295}
1296#ifdef __AVR__
1297//------------------------------------------------------------------------------
1298/**
1299 * Write a PROGMEM string to a file.
1300 *
1301 * Use SdFile::writeError to check for errors.
1302 */
1303void SdFile::write_P(PGM_P str) {
1304 for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c);
1305}
1306//------------------------------------------------------------------------------
1307/**
1308 * Write a PROGMEM string followed by CR/LF to a file.
1309 *
1310 * Use SdFile::writeError to check for errors.
1311 */
1312void SdFile::writeln_P(PGM_P str) {
1313 write_P(str);
1314 println();
1315}
1316#endif
Note: See TracBrowser for help on using the repository browser.