* Remove a file. * * The directory entry and all data for the file are deleted. * * \note This function should not be used to delete the 8.3 version of a * file that has a long name. For example if a file has the long name * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". * * \return true for success, false for failure. * Reasons for failure include the file rea
| 1593 | * or an I/O error occurred. |
| 1594 | */ |
| 1595 | bool SdBaseFile::remove() { |
| 1596 | if (ENABLED(SDCARD_READONLY)) return false; |
| 1597 | |
| 1598 | // free any clusters - will fail if read-only or directory |
| 1599 | if (!truncate(0)) return false; |
| 1600 | |
| 1601 | // cache directory entry |
| 1602 | dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); |
| 1603 | if (!d) return false; |
| 1604 | |
| 1605 | #if ENABLED(LONG_FILENAME_WRITE_SUPPORT) |
| 1606 | // get SFN checksum before name rewrite (needed for LFN deletion) |
| 1607 | const uint8_t sfn_checksum = lfn_checksum(d->name); |
| 1608 | #endif |
| 1609 | |
| 1610 | // mark entry deleted |
| 1611 | d->name[0] = DIR_NAME_DELETED; |
| 1612 | |
| 1613 | // set this file closed |
| 1614 | type_ = FAT_FILE_TYPE_CLOSED; |
| 1615 | |
| 1616 | // write entry to SD |
| 1617 | #if DISABLED(LONG_FILENAME_WRITE_SUPPORT) |
| 1618 | |
| 1619 | return vol_->cacheFlush(); |
| 1620 | |
| 1621 | #else // LONG_FILENAME_WRITE_SUPPORT |
| 1622 | |
| 1623 | flags_ = 0; |
| 1624 | |
| 1625 | if (!vol_->cacheFlush()) return false; |
| 1626 | |
| 1627 | // Check if the entry has a LFN |
| 1628 | bool lastEntry = false; |
| 1629 | // loop back to search for any LFN entries related to this file |
| 1630 | for (uint8_t sequenceNumber = 1; sequenceNumber <= VFAT_ENTRIES_LIMIT; ++sequenceNumber) { |
| 1631 | dirIndex_ = (dirIndex_ - 1) & 0xF; |
| 1632 | if (dirBlock_ == 0) break; |
| 1633 | if (dirIndex_ == 0xF) dirBlock_--; |
| 1634 | dir_t *dir = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); |
| 1635 | if (!dir) return false; |
| 1636 | |
| 1637 | // check for valid LFN: not deleted, not top dirs (".", ".."), must be a LFN |
| 1638 | if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.' || !isDirLFN(dir)) break; |
| 1639 | // check coherent LFN: checksum and sequenceNumber must match |
| 1640 | vfat_t* dirlfn = (vfat_t*) dir; |
| 1641 | if (dirlfn->checksum != sfn_checksum || (dirlfn->sequenceNumber & 0x1F) != sequenceNumber) break; // orphan entry |
| 1642 | // is last entry of LFN ? |
| 1643 | lastEntry = (dirlfn->sequenceNumber & 0x40); |
| 1644 | // mark as deleted |
| 1645 | dirlfn->sequenceNumber = DIR_NAME_DELETED; |
| 1646 | // Flush to SD |
| 1647 | if (!vol_->cacheFlush()) return false; |
| 1648 | // exit on last entry of LFN deleted |
| 1649 | if (lastEntry) break; |
| 1650 | } |
| 1651 | |
| 1652 | // Restore current index |
no test coverage detected