|
@@ -1,5 +1,5 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2011-2020 Bill Greiman
|
|
|
+ * Copyright (c) 2011-2021 Bill Greiman
|
|
|
* This file is part of the SdFat library for SD memory cards.
|
|
|
*
|
|
|
* MIT License
|
|
@@ -24,8 +24,7 @@
|
|
|
*/
|
|
|
#define DBG_FILE "FatFile.cpp"
|
|
|
#include "../common/DebugMacros.h"
|
|
|
-#include "FatFile.h"
|
|
|
-#include "FatVolume.h"
|
|
|
+#include "FatLib.h"
|
|
|
//------------------------------------------------------------------------------
|
|
|
// Add a cluster to a file.
|
|
|
bool FatFile::addCluster() {
|
|
@@ -55,7 +54,7 @@ bool FatFile::addCluster() {
|
|
|
// Return with first sector of cluster in the cache.
|
|
|
bool FatFile::addDirCluster() {
|
|
|
uint32_t sector;
|
|
|
- cache_t* pc;
|
|
|
+ uint8_t* pc;
|
|
|
|
|
|
if (isRootFixed()) {
|
|
|
DBG_FAIL_MACRO;
|
|
@@ -71,18 +70,13 @@ bool FatFile::addDirCluster() {
|
|
|
goto fail;
|
|
|
}
|
|
|
sector = m_vol->clusterStartSector(m_curCluster);
|
|
|
- pc = m_vol->cacheFetchData(sector, FsCache::CACHE_RESERVE_FOR_WRITE);
|
|
|
- if (!pc) {
|
|
|
- DBG_FAIL_MACRO;
|
|
|
- goto fail;
|
|
|
- }
|
|
|
- memset(pc, 0, m_vol->bytesPerSector());
|
|
|
- // zero rest of clusters
|
|
|
- for (uint8_t i = 1; i < m_vol->sectorsPerCluster(); i++) {
|
|
|
- if (!m_vol->writeSector(sector + i, pc->data)) {
|
|
|
+ for (uint8_t i = 0; i < m_vol->sectorsPerCluster(); i++) {
|
|
|
+ pc = m_vol->dataCachePrepare(sector + i, FsCache::CACHE_RESERVE_FOR_WRITE);
|
|
|
+ if (!pc) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
+ memset(pc, 0, m_vol->bytesPerSector());
|
|
|
}
|
|
|
// Set position to EOF to avoid inconsistent curCluster/curPosition.
|
|
|
m_curPosition += m_vol->bytesPerCluster();
|
|
@@ -95,13 +89,13 @@ bool FatFile::addDirCluster() {
|
|
|
// cache a file's directory entry
|
|
|
// return pointer to cached entry or null for failure
|
|
|
DirFat_t* FatFile::cacheDirEntry(uint8_t action) {
|
|
|
- cache_t* pc;
|
|
|
- pc = m_vol->cacheFetchData(m_dirSector, action);
|
|
|
- if (!pc) {
|
|
|
+ uint8_t* pc = m_vol->dataCachePrepare(m_dirSector, action);
|
|
|
+ DirFat_t* dir = reinterpret_cast<DirFat_t*>(pc);
|
|
|
+ if (!dir) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
- return pc->dir + (m_dirIndex & 0XF);
|
|
|
+ return dir + (m_dirIndex & 0XF);
|
|
|
|
|
|
fail:
|
|
|
return nullptr;
|
|
@@ -206,7 +200,7 @@ uint32_t FatFile::dirSize() {
|
|
|
return 0;
|
|
|
}
|
|
|
if (isRootFixed()) {
|
|
|
- return 32*m_vol->rootDirEntryCount();
|
|
|
+ return FS_DIR_SIZE*m_vol->rootDirEntryCount();
|
|
|
}
|
|
|
uint16_t n = 0;
|
|
|
uint32_t c = isRoot32() ? m_vol->rootDirStart() : m_firstCluster;
|
|
@@ -353,7 +347,7 @@ bool FatFile::mkdir(FatFile* parent, FatName_t* fname) {
|
|
|
uint32_t sector;
|
|
|
DirFat_t dot;
|
|
|
DirFat_t* dir;
|
|
|
- cache_t* pc;
|
|
|
+ uint8_t* pc;
|
|
|
|
|
|
if (!parent->isDir()) {
|
|
|
DBG_FAIL_MACRO;
|
|
@@ -399,19 +393,20 @@ bool FatFile::mkdir(FatFile* parent, FatName_t* fname) {
|
|
|
|
|
|
// cache sector for '.' and '..'
|
|
|
sector = m_vol->clusterStartSector(m_firstCluster);
|
|
|
- pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_WRITE);
|
|
|
- if (!pc) {
|
|
|
+ pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
|
|
+ dir = reinterpret_cast<DirFat_t*>(pc);
|
|
|
+ if (!dir) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
// copy '.' to sector
|
|
|
- memcpy(&pc->dir[0], &dot, sizeof(dot));
|
|
|
+ memcpy(&dir[0], &dot, sizeof(dot));
|
|
|
// make entry for '..'
|
|
|
dot.name[1] = '.';
|
|
|
setLe16(dot.firstClusterLow, parent->m_firstCluster & 0XFFFF);
|
|
|
setLe16(dot.firstClusterHigh, parent->m_firstCluster >> 16);
|
|
|
// copy '..' to sector
|
|
|
- memcpy(&pc->dir[1], &dot, sizeof(dot));
|
|
|
+ memcpy(&dir[1], &dot, sizeof(dot));
|
|
|
// write first sector
|
|
|
return m_vol->cacheSync();
|
|
|
|
|
@@ -619,7 +614,7 @@ bool FatFile::openNext(FatFile* dirFile, oflag_t oflag) {
|
|
|
}
|
|
|
while (1) {
|
|
|
// read entry into cache
|
|
|
- index = dirFile->curPosition()/32;
|
|
|
+ index = dirFile->curPosition()/FS_DIR_SIZE;
|
|
|
DirFat_t* dir = dirFile->readDirCache();
|
|
|
if (!dir) {
|
|
|
if (dirFile->getError()) {
|
|
@@ -735,8 +730,7 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|
|
uint16_t offset;
|
|
|
size_t toRead;
|
|
|
uint32_t sector; // raw device sector number
|
|
|
- cache_t* pc;
|
|
|
-
|
|
|
+ uint8_t* pc;
|
|
|
// error if not open for read
|
|
|
if (!isReadable()) {
|
|
|
DBG_FAIL_MACRO;
|
|
@@ -749,7 +743,8 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|
|
nbyte = tmp32;
|
|
|
}
|
|
|
} else if (isRootFixed()) {
|
|
|
- uint16_t tmp16 = 32*m_vol->m_rootDirEntryCount - (uint16_t)m_curPosition;
|
|
|
+ uint16_t tmp16 =
|
|
|
+ FS_DIR_SIZE*m_vol->m_rootDirEntryCount - (uint16_t)m_curPosition;
|
|
|
if (nbyte > tmp16) {
|
|
|
nbyte = tmp16;
|
|
|
}
|
|
@@ -798,12 +793,12 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|
|
n = toRead;
|
|
|
}
|
|
|
// read sector to cache and copy data to caller
|
|
|
- pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_READ);
|
|
|
+ pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
|
|
if (!pc) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
- uint8_t* src = pc->data + offset;
|
|
|
+ uint8_t* src = pc + offset;
|
|
|
memcpy(dst, src, n);
|
|
|
#if USE_MULTI_SECTOR_IO
|
|
|
} else if (toRead >= 2*m_vol->bytesPerSector()) {
|
|
@@ -880,9 +875,9 @@ DirFat_t* FatFile::readDirCache(bool skipReadOk) {
|
|
|
}
|
|
|
goto fail;
|
|
|
}
|
|
|
- m_curPosition += 31;
|
|
|
+ m_curPosition += FS_DIR_SIZE - 1;
|
|
|
} else {
|
|
|
- m_curPosition += 32;
|
|
|
+ m_curPosition += FS_DIR_SIZE;
|
|
|
}
|
|
|
// return pointer to entry
|
|
|
return reinterpret_cast<DirFat_t*>(m_vol->cacheAddress()) + i;
|
|
@@ -912,7 +907,7 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|
|
uint32_t dirCluster = 0;
|
|
|
FatFile file;
|
|
|
FatFile oldFile;
|
|
|
- cache_t* pc;
|
|
|
+ uint8_t* pc;
|
|
|
DirFat_t* dir;
|
|
|
|
|
|
// Must be an open file or subdirectory.
|
|
@@ -980,12 +975,13 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|
|
if (dirCluster) {
|
|
|
// get new dot dot
|
|
|
uint32_t sector = m_vol->clusterStartSector(dirCluster);
|
|
|
- pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_READ);
|
|
|
- if (!pc) {
|
|
|
+ pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
|
|
+ dir = reinterpret_cast<DirFat_t*>(pc);
|
|
|
+ if (!dir) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
- memcpy(&entry, &pc->dir[1], sizeof(entry));
|
|
|
+ memcpy(&entry, &dir[1], sizeof(entry));
|
|
|
|
|
|
// free unused cluster
|
|
|
if (!m_vol->freeChain(dirCluster)) {
|
|
@@ -994,12 +990,13 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|
|
}
|
|
|
// store new dot dot
|
|
|
sector = m_vol->clusterStartSector(m_firstCluster);
|
|
|
- pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_WRITE);
|
|
|
- if (!pc) {
|
|
|
+ uint8_t* pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
|
|
+ dir = reinterpret_cast<DirFat_t*>(pc);
|
|
|
+ if (!dir) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
- memcpy(&pc->dir[1], &entry, sizeof(entry));
|
|
|
+ memcpy(&dir[1], &entry, sizeof(entry));
|
|
|
}
|
|
|
// Remove old directory entry;
|
|
|
oldFile.m_firstCluster = 0;
|
|
@@ -1067,7 +1064,7 @@ bool FatFile::rmRfStar() {
|
|
|
rewind();
|
|
|
while (1) {
|
|
|
// remember position
|
|
|
- index = m_curPosition/32;
|
|
|
+ index = m_curPosition/FS_DIR_SIZE;
|
|
|
|
|
|
DirFat_t* dir = readDirCache();
|
|
|
if (!dir) {
|
|
@@ -1156,7 +1153,7 @@ bool FatFile::seekSet(uint32_t pos) {
|
|
|
goto fail;
|
|
|
}
|
|
|
} else if (isRootFixed()) {
|
|
|
- if (pos <= 32*m_vol->rootDirEntryCount()) {
|
|
|
+ if (pos <= FS_DIR_SIZE*m_vol->rootDirEntryCount()) {
|
|
|
goto done;
|
|
|
}
|
|
|
DBG_FAIL_MACRO;
|
|
@@ -1335,7 +1332,7 @@ bool FatFile::truncate() {
|
|
|
size_t FatFile::write(const void* buf, size_t nbyte) {
|
|
|
// convert void* to uint8_t* - must be before goto statements
|
|
|
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
|
|
- cache_t* pc;
|
|
|
+ uint8_t* pc;
|
|
|
uint8_t cacheOption;
|
|
|
// number of bytes left to write - must be before goto statements
|
|
|
size_t nToWrite = nbyte;
|
|
@@ -1423,12 +1420,12 @@ size_t FatFile::write(const void* buf, size_t nbyte) {
|
|
|
// rewrite part of sector
|
|
|
cacheOption = FsCache::CACHE_FOR_WRITE;
|
|
|
}
|
|
|
- pc = m_vol->cacheFetchData(sector, cacheOption);
|
|
|
+ pc = m_vol->dataCachePrepare(sector, cacheOption);
|
|
|
if (!pc) {
|
|
|
DBG_FAIL_MACRO;
|
|
|
goto fail;
|
|
|
}
|
|
|
- uint8_t* dst = pc->data + sectorOffset;
|
|
|
+ uint8_t* dst = pc + sectorOffset;
|
|
|
memcpy(dst, src, n);
|
|
|
if (m_vol->bytesPerSector() == (n + sectorOffset)) {
|
|
|
// Force write if sector is full - improves large writes.
|