Patch goto labels for consistency

2.0.x
Scott Lahteine 7 years ago
parent 75e6f72c89
commit 8fd58cd6dc

@ -244,7 +244,7 @@ void Sd2Card::chipSelectLow() {
*/ */
bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
csd_t csd; csd_t csd;
if (!readCSD(&csd)) goto fail; if (!readCSD(&csd)) goto FAIL;
// check for single block erase // check for single block erase
if (!csd.v1.erase_blk_en) { if (!csd.v1.erase_blk_en) {
// erase size mask // erase size mask
@ -252,7 +252,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
// error card can't erase specified area // error card can't erase specified area
error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
goto fail; goto FAIL;
} }
} }
if (type_ != SD_CARD_TYPE_SDHC) { if (type_ != SD_CARD_TYPE_SDHC) {
@ -263,15 +263,15 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|| cardCommand(CMD33, lastBlock) || cardCommand(CMD33, lastBlock)
|| cardCommand(CMD38, 0)) { || cardCommand(CMD38, 0)) {
error(SD_CARD_ERROR_ERASE); error(SD_CARD_ERROR_ERASE);
goto fail; goto FAIL;
} }
if (!waitNotBusy(SD_ERASE_TIMEOUT)) { if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
error(SD_CARD_ERROR_ERASE_TIMEOUT); error(SD_CARD_ERROR_ERASE_TIMEOUT);
goto fail; goto FAIL;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -335,7 +335,7 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
error(SD_CARD_ERROR_CMD0); error(SD_CARD_ERROR_CMD0);
goto fail; goto FAIL;
} }
} }
// check SD version // check SD version
@ -347,7 +347,7 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
if (status_ != 0xAA) { if (status_ != 0xAA) {
error(SD_CARD_ERROR_CMD8); error(SD_CARD_ERROR_CMD8);
goto fail; goto FAIL;
} }
type(SD_CARD_TYPE_SD2); type(SD_CARD_TYPE_SD2);
} }
@ -358,14 +358,14 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
// check for timeout // check for timeout
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
error(SD_CARD_ERROR_ACMD41); error(SD_CARD_ERROR_ACMD41);
goto fail; goto FAIL;
} }
} }
// if SD2 read OCR register to check for SDHC card // if SD2 read OCR register to check for SDHC card
if (type() == SD_CARD_TYPE_SD2) { if (type() == SD_CARD_TYPE_SD2) {
if (cardCommand(CMD58, 0)) { if (cardCommand(CMD58, 0)) {
error(SD_CARD_ERROR_CMD58); error(SD_CARD_ERROR_CMD58);
goto fail; goto FAIL;
} }
if ((spiRec() & 0xC0) == 0xC0) type(SD_CARD_TYPE_SDHC); if ((spiRec() & 0xC0) == 0xC0) type(SD_CARD_TYPE_SDHC);
// discard rest of ocr - contains allowed voltage range // discard rest of ocr - contains allowed voltage range
@ -380,7 +380,7 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
return true; return true;
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -486,12 +486,12 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
while ((status_ = spiRec()) == 0XFF) { while ((status_ = spiRec()) == 0XFF) {
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
error(SD_CARD_ERROR_READ_TIMEOUT); error(SD_CARD_ERROR_READ_TIMEOUT);
goto fail; goto FAIL;
} }
} }
if (status_ != DATA_START_BLOCK) { if (status_ != DATA_START_BLOCK) {
error(SD_CARD_ERROR_READ); error(SD_CARD_ERROR_READ);
goto fail; goto FAIL;
} }
// transfer data // transfer data
spiRead(dst, count); spiRead(dst, count);
@ -503,7 +503,7 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
recvCrc |= spiRec(); recvCrc |= spiRec();
if (calcCrc != recvCrc) { if (calcCrc != recvCrc) {
error(SD_CARD_ERROR_CRC); error(SD_CARD_ERROR_CRC);
goto fail; goto FAIL;
} }
} }
#else #else
@ -515,7 +515,7 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
// Send an additional dummy byte, required by Toshiba Flash Air SD Card // Send an additional dummy byte, required by Toshiba Flash Air SD Card
spiSend(0XFF); spiSend(0XFF);
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
// Send an additional dummy byte, required by Toshiba Flash Air SD Card // Send an additional dummy byte, required by Toshiba Flash Air SD Card
spiSend(0XFF); spiSend(0XFF);
@ -527,10 +527,10 @@ bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
uint8_t* dst = reinterpret_cast<uint8_t*>(buf); uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
if (cardCommand(cmd, 0)) { if (cardCommand(cmd, 0)) {
error(SD_CARD_ERROR_READ_REG); error(SD_CARD_ERROR_READ_REG);
goto fail; goto FAIL;
} }
return readData(dst, 16); return readData(dst, 16);
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -549,11 +549,11 @@ bool Sd2Card::readStart(uint32_t blockNumber) {
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD18, blockNumber)) { if (cardCommand(CMD18, blockNumber)) {
error(SD_CARD_ERROR_CMD18); error(SD_CARD_ERROR_CMD18);
goto fail; goto FAIL;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -567,11 +567,11 @@ bool Sd2Card::readStop() {
chipSelectLow(); chipSelectLow();
if (cardCommand(CMD12, 0)) { if (cardCommand(CMD12, 0)) {
error(SD_CARD_ERROR_CMD12); error(SD_CARD_ERROR_CMD12);
goto fail; goto FAIL;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -601,10 +601,10 @@ bool Sd2Card::setSckRate(uint8_t sckRateID) {
bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
uint16_t t0 = millis(); uint16_t t0 = millis();
while (spiRec() != 0XFF) { while (spiRec() != 0XFF) {
if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail; if (((uint16_t)millis() - t0) >= timeoutMillis) goto FAIL;
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -621,23 +621,23 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD24, blockNumber)) { if (cardCommand(CMD24, blockNumber)) {
error(SD_CARD_ERROR_CMD24); error(SD_CARD_ERROR_CMD24);
goto fail; goto FAIL;
} }
if (!writeData(DATA_START_BLOCK, src)) goto fail; if (!writeData(DATA_START_BLOCK, src)) goto FAIL;
// wait for flash programming to complete // wait for flash programming to complete
if (!waitNotBusy(SD_WRITE_TIMEOUT)) { if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
error(SD_CARD_ERROR_WRITE_TIMEOUT); error(SD_CARD_ERROR_WRITE_TIMEOUT);
goto fail; goto FAIL;
} }
// response is r2 so get and check two bytes for nonzero // response is r2 so get and check two bytes for nonzero
if (cardCommand(CMD13, 0) || spiRec()) { if (cardCommand(CMD13, 0) || spiRec()) {
error(SD_CARD_ERROR_WRITE_PROGRAMMING); error(SD_CARD_ERROR_WRITE_PROGRAMMING);
goto fail; goto FAIL;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -650,11 +650,11 @@ fail:
bool Sd2Card::writeData(const uint8_t* src) { bool Sd2Card::writeData(const uint8_t* src) {
chipSelectLow(); chipSelectLow();
// wait for previous write to finish // wait for previous write to finish
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail; if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto FAIL;
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
error(SD_CARD_ERROR_WRITE_MULTIPLE); error(SD_CARD_ERROR_WRITE_MULTIPLE);
chipSelectHigh(); chipSelectHigh();
return false; return false;
@ -670,10 +670,10 @@ bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
status_ = spiRec(); status_ = spiRec();
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
error(SD_CARD_ERROR_WRITE); error(SD_CARD_ERROR_WRITE);
goto fail; goto FAIL;
} }
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -693,17 +693,17 @@ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
// send pre-erase count // send pre-erase count
if (cardAcmd(ACMD23, eraseCount)) { if (cardAcmd(ACMD23, eraseCount)) {
error(SD_CARD_ERROR_ACMD23); error(SD_CARD_ERROR_ACMD23);
goto fail; goto FAIL;
} }
// use address if not SDHC card // use address if not SDHC card
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD25, blockNumber)) { if (cardCommand(CMD25, blockNumber)) {
error(SD_CARD_ERROR_CMD25); error(SD_CARD_ERROR_CMD25);
goto fail; goto FAIL;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@ -715,12 +715,12 @@ fail:
*/ */
bool Sd2Card::writeStop() { bool Sd2Card::writeStop() {
chipSelectLow(); chipSelectLow();
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
spiSend(STOP_TRAN_TOKEN); spiSend(STOP_TRAN_TOKEN);
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail: FAIL:
error(SD_CARD_ERROR_STOP_TRAN); error(SD_CARD_ERROR_STOP_TRAN);
chipSelectHigh(); chipSelectHigh();
return false; return false;

@ -39,7 +39,7 @@ void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// add a cluster to a file // add a cluster to a file
bool SdBaseFile::addCluster() { bool SdBaseFile::addCluster() {
if (!vol_->allocContiguous(1, &curCluster_)) goto fail; if (!vol_->allocContiguous(1, &curCluster_)) goto FAIL;
// if first cluster of file link to directory entry // if first cluster of file link to directory entry
if (firstCluster_ == 0) { if (firstCluster_ == 0) {
@ -48,7 +48,7 @@ bool SdBaseFile::addCluster() {
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -57,10 +57,10 @@ bool SdBaseFile::addCluster() {
bool SdBaseFile::addDirCluster() { bool SdBaseFile::addDirCluster() {
uint32_t block; uint32_t block;
// max folder size // max folder size
if (fileSize_ / sizeof(dir_t) >= 0xFFFF) goto fail; if (fileSize_ / sizeof(dir_t) >= 0xFFFF) goto FAIL;
if (!addCluster()) goto fail; if (!addCluster()) goto FAIL;
if (!vol_->cacheFlush()) goto fail; if (!vol_->cacheFlush()) goto FAIL;
block = vol_->clusterStartBlock(curCluster_); block = vol_->clusterStartBlock(curCluster_);
@ -72,21 +72,21 @@ bool SdBaseFile::addDirCluster() {
// zero rest of cluster // zero rest of cluster
for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) {
if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto fail; if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto FAIL;
} }
// Increase directory file size by cluster size // Increase directory file size by cluster size
fileSize_ += 512UL << vol_->clusterSizeShift_; fileSize_ += 512UL << vol_->clusterSizeShift_;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// cache a file's directory entry // cache a file's directory entry
// return pointer to cached entry or null for failure // return pointer to cached entry or null for failure
dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { dir_t* SdBaseFile::cacheDirEntry(uint8_t action) {
if (!vol_->cacheRawBlock(dirBlock_, action)) goto fail; if (!vol_->cacheRawBlock(dirBlock_, action)) goto FAIL;
return vol_->cache()->dir + dirIndex_; return vol_->cache()->dir + dirIndex_;
fail: FAIL:
return 0; return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -115,16 +115,16 @@ bool SdBaseFile::close() {
*/ */
bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
// error if no blocks // error if no blocks
if (firstCluster_ == 0) goto fail; if (firstCluster_ == 0) goto FAIL;
for (uint32_t c = firstCluster_; ; c++) { for (uint32_t c = firstCluster_; ; c++) {
uint32_t next; uint32_t next;
if (!vol_->fatGet(c, &next)) goto fail; if (!vol_->fatGet(c, &next)) goto FAIL;
// check for contiguous // check for contiguous
if (next != (c + 1)) { if (next != (c + 1)) {
// error if not end of chain // error if not end of chain
if (!vol_->isEOC(next)) goto fail; if (!vol_->isEOC(next)) goto FAIL;
*bgnBlock = vol_->clusterStartBlock(firstCluster_); *bgnBlock = vol_->clusterStartBlock(firstCluster_);
*endBlock = vol_->clusterStartBlock(c) *endBlock = vol_->clusterStartBlock(c)
+ vol_->blocksPerCluster_ - 1; + vol_->blocksPerCluster_ - 1;
@ -132,7 +132,7 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
} }
} }
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -157,8 +157,8 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile,
const char* path, uint32_t size) { const char* path, uint32_t size) {
uint32_t count; uint32_t count;
// don't allow zero length file // don't allow zero length file
if (size == 0) goto fail; if (size == 0) goto FAIL;
if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto fail; if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto FAIL;
// calculate number of clusters needed // calculate number of clusters needed
count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1;
@ -166,7 +166,7 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile,
// allocate clusters // allocate clusters
if (!vol_->allocContiguous(count, &firstCluster_)) { if (!vol_->allocContiguous(count, &firstCluster_)) {
remove(); remove();
goto fail; goto FAIL;
} }
fileSize_ = size; fileSize_ = size;
@ -174,7 +174,7 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile,
flags_ |= F_FILE_DIR_DIRTY; flags_ |= F_FILE_DIR_DIRTY;
return sync(); return sync();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -188,16 +188,16 @@ fail:
bool SdBaseFile::dirEntry(dir_t* dir) { bool SdBaseFile::dirEntry(dir_t* dir) {
dir_t* p; dir_t* p;
// make sure fields on SD are correct // make sure fields on SD are correct
if (!sync()) goto fail; if (!sync()) goto FAIL;
// read entry // read entry
p = cacheDirEntry(SdVolume::CACHE_FOR_READ); p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
if (!p) goto fail; if (!p) goto FAIL;
// copy to caller's struct // copy to caller's struct
memcpy(dir, p, sizeof(dir_t)); memcpy(dir, p, sizeof(dir_t));
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -395,7 +395,7 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
while (*str != '\0' && *str != '/') { while (*str != '\0' && *str != '/') {
c = *str++; c = *str++;
if (c == '.') { if (c == '.') {
if (n == 10) goto fail; // only one dot allowed if (n == 10) goto FAIL; // only one dot allowed
n = 10; // max index for full 8.3 name n = 10; // max index for full 8.3 name
i = 8; // place for extension i = 8; // place for extension
} }
@ -403,9 +403,9 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
// illegal FAT characters // illegal FAT characters
PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
uint8_t b; uint8_t b;
while ((b = pgm_read_byte(p++))) if (b == c) goto fail; while ((b = pgm_read_byte(p++))) if (b == c) goto FAIL;
// check size and only allow ASCII printable characters // check size and only allow ASCII printable characters
if (i > n || c < 0x21 || c == 0x7F) goto fail; if (i > n || c < 0x21 || c == 0x7F) goto FAIL;
// only upper case allowed in 8.3 names - convert lower to upper // only upper case allowed in 8.3 names - convert lower to upper
name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a'));
} }
@ -413,7 +413,7 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
*ptr = str; *ptr = str;
// must have a file name, extension is optional // must have a file name, extension is optional
return name[0] != ' '; return name[0] != ' ';
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -437,22 +437,22 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
SdBaseFile* sub = &dir1; SdBaseFile* sub = &dir1;
SdBaseFile* start = parent; SdBaseFile* start = parent;
if (!parent || isOpen()) goto fail; if (!parent || isOpen()) goto FAIL;
if (*path == '/') { if (*path == '/') {
while (*path == '/') path++; while (*path == '/') path++;
if (!parent->isRoot()) { if (!parent->isRoot()) {
if (!dir2.openRoot(parent->vol_)) goto fail; if (!dir2.openRoot(parent->vol_)) goto FAIL;
parent = &dir2; parent = &dir2;
} }
} }
while (1) { while (1) {
if (!make83Name(path, dname, &path)) goto fail; if (!make83Name(path, dname, &path)) goto FAIL;
while (*path == '/') path++; while (*path == '/') path++;
if (!*path) break; if (!*path) break;
if (!sub->open(parent, dname, O_READ)) { if (!sub->open(parent, dname, O_READ)) {
if (!pFlag || !sub->mkdir(parent, dname)) { if (!pFlag || !sub->mkdir(parent, dname)) {
goto fail; goto FAIL;
} }
} }
if (parent != start) parent->close(); if (parent != start) parent->close();
@ -460,7 +460,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
sub = parent != &dir1 ? &dir1 : &dir2; sub = parent != &dir1 ? &dir1 : &dir2;
} }
return mkdir(parent, dname); return mkdir(parent, dname);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -469,24 +469,24 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
dir_t d; dir_t d;
dir_t* p; dir_t* p;
if (!parent->isDir()) goto fail; if (!parent->isDir()) goto FAIL;
// create a normal file // create a normal file
if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto fail; if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto FAIL;
// convert file to directory // convert file to directory
flags_ = O_READ; flags_ = O_READ;
type_ = FAT_FILE_TYPE_SUBDIR; type_ = FAT_FILE_TYPE_SUBDIR;
// allocate and zero first cluster // allocate and zero first cluster
if (!addDirCluster())goto fail; if (!addDirCluster())goto FAIL;
// force entry to SD // force entry to SD
if (!sync()) goto fail; if (!sync()) goto FAIL;
// cache entry - should already be in cache due to sync() call // cache entry - should already be in cache due to sync() call
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!p) goto fail; if (!p) goto FAIL;
// change directory entry attribute // change directory entry attribute
p->attributes = DIR_ATT_DIRECTORY; p->attributes = DIR_ATT_DIRECTORY;
@ -498,7 +498,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
// cache block for '.' and '..' // cache block for '.' and '..'
block = vol_->clusterStartBlock(firstCluster_); block = vol_->clusterStartBlock(firstCluster_);
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL;
// copy '.' to block // copy '.' to block
memcpy(&vol_->cache()->dir[0], &d, sizeof(d)); memcpy(&vol_->cache()->dir[0], &d, sizeof(d));
@ -518,7 +518,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
// write first block // write first block
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -592,29 +592,29 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) {
SdBaseFile* parent = dirFile; SdBaseFile* parent = dirFile;
SdBaseFile* sub = &dir1; SdBaseFile* sub = &dir1;
if (!dirFile) goto fail; if (!dirFile) goto FAIL;
// error if already open // error if already open
if (isOpen()) goto fail; if (isOpen()) goto FAIL;
if (*path == '/') { if (*path == '/') {
while (*path == '/') path++; while (*path == '/') path++;
if (!dirFile->isRoot()) { if (!dirFile->isRoot()) {
if (!dir2.openRoot(dirFile->vol_)) goto fail; if (!dir2.openRoot(dirFile->vol_)) goto FAIL;
parent = &dir2; parent = &dir2;
} }
} }
while (1) { while (1) {
if (!make83Name(path, dname, &path)) goto fail; if (!make83Name(path, dname, &path)) goto FAIL;
while (*path == '/') path++; while (*path == '/') path++;
if (!*path) break; if (!*path) break;
if (!sub->open(parent, dname, O_READ)) goto fail; if (!sub->open(parent, dname, O_READ)) goto FAIL;
if (parent != dirFile) parent->close(); if (parent != dirFile) parent->close();
parent = sub; parent = sub;
sub = parent != &dir1 ? &dir1 : &dir2; sub = parent != &dir1 ? &dir1 : &dir2;
} }
return open(parent, dname, oflag); return open(parent, dname, oflag);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -634,7 +634,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
while (dirFile->curPosition_ < dirFile->fileSize_) { while (dirFile->curPosition_ < dirFile->fileSize_) {
index = 0XF & (dirFile->curPosition_ >> 5); index = 0XF & (dirFile->curPosition_ >> 5);
p = dirFile->readDirCache(); p = dirFile->readDirCache();
if (!p) goto fail; if (!p) goto FAIL;
if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
// remember first empty slot // remember first empty slot
@ -653,21 +653,21 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
} }
if (fileFound) { if (fileFound) {
// don't open existing file if O_EXCL // don't open existing file if O_EXCL
if (oflag & O_EXCL) goto fail; if (oflag & O_EXCL) goto FAIL;
} }
else { else {
// don't create unless O_CREAT and O_WRITE // don't create unless O_CREAT and O_WRITE
if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto fail; if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto FAIL;
if (emptyFound) { if (emptyFound) {
index = dirIndex_; index = dirIndex_;
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!p) goto fail; if (!p) goto FAIL;
} }
else { else {
if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto fail; if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto FAIL;
// add and zero cluster for dirFile - first cluster is in cache for write // add and zero cluster for dirFile - first cluster is in cache for write
if (!dirFile->addDirCluster()) goto fail; if (!dirFile->addDirCluster()) goto FAIL;
// use first entry in cluster // use first entry in cluster
p = dirFile->vol_->cache()->dir; p = dirFile->vol_->cache()->dir;
@ -692,11 +692,11 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
p->lastWriteTime = p->creationTime; p->lastWriteTime = p->creationTime;
// write entry to SD // write entry to SD
if (!dirFile->vol_->cacheFlush()) goto fail; if (!dirFile->vol_->cacheFlush()) goto FAIL;
} }
// open entry in cache // open entry in cache
return openCachedEntry(index, oflag); return openCachedEntry(index, oflag);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -719,26 +719,26 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
vol_ = dirFile->vol_; vol_ = dirFile->vol_;
// error if already open // error if already open
if (isOpen() || !dirFile) goto fail; if (isOpen() || !dirFile) goto FAIL;
// don't open existing file if O_EXCL - user call error // don't open existing file if O_EXCL - user call error
if (oflag & O_EXCL) goto fail; if (oflag & O_EXCL) goto FAIL;
// seek to location of entry // seek to location of entry
if (!dirFile->seekSet(32 * index)) goto fail; if (!dirFile->seekSet(32 * index)) goto FAIL;
// read entry into cache // read entry into cache
p = dirFile->readDirCache(); p = dirFile->readDirCache();
if (!p) goto fail; if (!p) goto FAIL;
// error if empty slot or '.' or '..' // error if empty slot or '.' or '..'
if (p->name[0] == DIR_NAME_FREE || if (p->name[0] == DIR_NAME_FREE ||
p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
goto fail; goto FAIL;
} }
// open cached entry // open cached entry
return openCachedEntry(index & 0XF, oflag); return openCachedEntry(index & 0XF, oflag);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -749,7 +749,7 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
// write or truncate is an error for a directory or read-only file // write or truncate is an error for a directory or read-only file
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) { if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
if (oflag & (O_WRITE | O_TRUNC)) goto fail; if (oflag & (O_WRITE | O_TRUNC)) goto FAIL;
} }
// remember location of directory entry on SD // remember location of directory entry on SD
dirBlock_ = vol_->cacheBlockNumber(); dirBlock_ = vol_->cacheBlockNumber();
@ -765,11 +765,11 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
type_ = FAT_FILE_TYPE_NORMAL; type_ = FAT_FILE_TYPE_NORMAL;
} }
else if (DIR_IS_SUBDIR(p)) { else if (DIR_IS_SUBDIR(p)) {
if (!vol_->chainSize(firstCluster_, &fileSize_)) goto fail; if (!vol_->chainSize(firstCluster_, &fileSize_)) goto FAIL;
type_ = FAT_FILE_TYPE_SUBDIR; type_ = FAT_FILE_TYPE_SUBDIR;
} }
else { else {
goto fail; goto FAIL;
} }
// save open flags for read/write // save open flags for read/write
flags_ = oflag & F_OFLAG; flags_ = oflag & F_OFLAG;
@ -779,7 +779,7 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
curPosition_ = 0; curPosition_ = 0;
if ((oflag & O_TRUNC) && !truncate(0)) return false; if ((oflag & O_TRUNC) && !truncate(0)) return false;
return oflag & O_AT_END ? seekEnd(0) : true; return oflag & O_AT_END ? seekEnd(0) : true;
fail: FAIL:
type_ = FAT_FILE_TYPE_CLOSED; type_ = FAT_FILE_TYPE_CLOSED;
return false; return false;
} }
@ -799,10 +799,10 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
dir_t* p; dir_t* p;
uint8_t index; uint8_t index;
if (!dirFile) goto fail; if (!dirFile) goto FAIL;
// error if already open // error if already open
if (isOpen()) goto fail; if (isOpen()) goto FAIL;
vol_ = dirFile->vol_; vol_ = dirFile->vol_;
@ -811,10 +811,10 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
// read entry into cache // read entry into cache
p = dirFile->readDirCache(); p = dirFile->readDirCache();
if (!p) goto fail; if (!p) goto FAIL;
// done if last entry // done if last entry
if (p->name[0] == DIR_NAME_FREE) goto fail; if (p->name[0] == DIR_NAME_FREE) goto FAIL;
// skip empty slot or '.' or '..' // skip empty slot or '.' or '..'
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
@ -825,7 +825,7 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
return openCachedEntry(index, oflag); return openCachedEntry(index, oflag);
} }
} }
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -844,14 +844,14 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
uint32_t cluster; uint32_t cluster;
uint32_t lbn; uint32_t lbn;
// error if already open or dir is root or dir is not a directory // error if already open or dir is root or dir is not a directory
if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto fail; if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto FAIL;
vol_ = dir->vol_; vol_ = dir->vol_;
// position to '..' // position to '..'
if (!dir->seekSet(32)) goto fail; if (!dir->seekSet(32)) goto FAIL;
// read '..' entry // read '..' entry
if (dir->read(&entry, sizeof(entry)) != 32) goto fail; if (dir->read(&entry, sizeof(entry)) != 32) goto FAIL;
// verify it is '..' // verify it is '..'
if (entry.name[0] != '.' || entry.name[1] != '.') goto fail; if (entry.name[0] != '.' || entry.name[1] != '.') goto FAIL;
// start cluster for '..' // start cluster for '..'
cluster = entry.firstClusterLow; cluster = entry.firstClusterLow;
cluster |= (uint32_t)entry.firstClusterHigh << 16; cluster |= (uint32_t)entry.firstClusterHigh << 16;
@ -860,27 +860,27 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
lbn = vol_->clusterStartBlock(cluster); lbn = vol_->clusterStartBlock(cluster);
// first block of parent dir // first block of parent dir
if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) { if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) {
goto fail; goto FAIL;
} }
p = &vol_->cacheBuffer_.dir[1]; p = &vol_->cacheBuffer_.dir[1];
// verify name for '../..' // verify name for '../..'
if (p->name[0] != '.' || p->name[1] != '.') goto fail; if (p->name[0] != '.' || p->name[1] != '.') goto FAIL;
// '..' is pointer to first cluster of parent. open '../..' to find parent // '..' is pointer to first cluster of parent. open '../..' to find parent
if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) {
if (!file.openRoot(dir->volume())) goto fail; if (!file.openRoot(dir->volume())) goto FAIL;
} }
else if (!file.openCachedEntry(1, O_READ)) { else if (!file.openCachedEntry(1, O_READ)) {
goto fail; goto FAIL;
} }
// search for parent in '../..' // search for parent in '../..'
do { do {
if (file.readDir(&entry, NULL) != 32) goto fail; if (file.readDir(&entry, NULL) != 32) goto FAIL;
c = entry.firstClusterLow; c = entry.firstClusterLow;
c |= (uint32_t)entry.firstClusterHigh << 16; c |= (uint32_t)entry.firstClusterHigh << 16;
} while (c != cluster); } while (c != cluster);
// open parent // open parent
return open(&file, file.curPosition() / 32 - 1, O_READ); return open(&file, file.curPosition() / 32 - 1, O_READ);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -895,7 +895,7 @@ fail:
*/ */
bool SdBaseFile::openRoot(SdVolume* vol) { bool SdBaseFile::openRoot(SdVolume* vol) {
// error if file is already open // error if file is already open
if (isOpen()) goto fail; if (isOpen()) goto FAIL;
if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) {
type_ = FAT_FILE_TYPE_ROOT_FIXED; type_ = FAT_FILE_TYPE_ROOT_FIXED;
@ -905,7 +905,7 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
else if (vol->fatType() == 32) { else if (vol->fatType() == 32) {
type_ = FAT_FILE_TYPE_ROOT32; type_ = FAT_FILE_TYPE_ROOT32;
firstCluster_ = vol->rootDirStart(); firstCluster_ = vol->rootDirStart();
if (!vol->chainSize(firstCluster_, &fileSize_)) goto fail; if (!vol->chainSize(firstCluster_, &fileSize_)) goto FAIL;
} }
else { else {
// volume is not initialized, invalid, or FAT12 without support // volume is not initialized, invalid, or FAT12 without support
@ -923,7 +923,7 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
dirBlock_ = 0; dirBlock_ = 0;
dirIndex_ = 0; dirIndex_ = 0;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1055,7 +1055,7 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
uint32_t block; // raw device block number uint32_t block; // raw device block number
// error if not open or write only // error if not open or write only
if (!isOpen() || !(flags_ & O_READ)) goto fail; if (!isOpen() || !(flags_ & O_READ)) goto FAIL;
// max bytes left in file // max bytes left in file
NOMORE(nbyte, fileSize_ - curPosition_); NOMORE(nbyte, fileSize_ - curPosition_);
@ -1077,7 +1077,7 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
} }
else { else {
// get next cluster from FAT // get next cluster from FAT
if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL;
} }
} }
block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
@ -1089,11 +1089,11 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
// no buffering needed if n == 512 // no buffering needed if n == 512
if (n == 512 && block != vol_->cacheBlockNumber()) { if (n == 512 && block != vol_->cacheBlockNumber()) {
if (!vol_->readBlock(block, dst)) goto fail; if (!vol_->readBlock(block, dst)) goto FAIL;
} }
else { else {
// read block to cache and copy data to caller // read block to cache and copy data to caller
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL;
uint8_t* src = vol_->cache()->data + offset; uint8_t* src = vol_->cache()->data + offset;
memcpy(dst, src, n); memcpy(dst, src, n);
} }
@ -1102,7 +1102,7 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
toRead -= n; toRead -= n;
} }
return nbyte; return nbyte;
fail: FAIL:
return -1; return -1;
} }
@ -1161,20 +1161,20 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
dir_t* SdBaseFile::readDirCache() { dir_t* SdBaseFile::readDirCache() {
uint8_t i; uint8_t i;
// error if not directory // error if not directory
if (!isDir()) goto fail; if (!isDir()) goto FAIL;
// index of entry in cache // index of entry in cache
i = (curPosition_ >> 5) & 0XF; i = (curPosition_ >> 5) & 0XF;
// use read to locate and cache block // use read to locate and cache block
if (read() < 0) goto fail; if (read() < 0) goto FAIL;
// advance to next entry // advance to next entry
curPosition_ += 31; curPosition_ += 31;
// return pointer to entry // return pointer to entry
return vol_->cache()->dir + i; return vol_->cache()->dir + i;
fail: FAIL:
return 0; return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1194,11 +1194,11 @@ fail:
bool SdBaseFile::remove() { bool SdBaseFile::remove() {
dir_t* d; dir_t* d;
// free any clusters - will fail if read-only or directory // free any clusters - will fail if read-only or directory
if (!truncate(0)) goto fail; if (!truncate(0)) goto FAIL;
// cache directory entry // cache directory entry
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
// mark entry deleted // mark entry deleted
d->name[0] = DIR_NAME_DELETED; d->name[0] = DIR_NAME_DELETED;
@ -1209,7 +1209,7 @@ bool SdBaseFile::remove() {
// write entry to SD // write entry to SD
return vol_->cacheFlush(); return vol_->cacheFlush();
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1232,9 +1232,9 @@ fail:
*/ */
bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
SdBaseFile file; SdBaseFile file;
if (!file.open(dirFile, path, O_WRITE)) goto fail; if (!file.open(dirFile, path, O_WRITE)) goto FAIL;
return file.remove(); return file.remove();
fail: FAIL:
// can't set iostate - static function // can't set iostate - static function
return false; return false;
} }
@ -1256,15 +1256,15 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
dir_t* d; dir_t* d;
// must be an open file or subdirectory // must be an open file or subdirectory
if (!(isFile() || isSubDir())) goto fail; if (!(isFile() || isSubDir())) goto FAIL;
// can't move file // can't move file
if (vol_ != dirFile->vol_) goto fail; if (vol_ != dirFile->vol_) goto FAIL;
// sync() and cache directory entry // sync() and cache directory entry
sync(); sync();
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
// save directory entry // save directory entry
memcpy(&entry, d, sizeof(entry)); memcpy(&entry, d, sizeof(entry));
@ -1295,7 +1295,7 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
// cache new directory entry // cache new directory entry
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
// copy all but name field to new directory entry // copy all but name field to new directory entry
memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name));
@ -1304,27 +1304,27 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
if (dirCluster) { if (dirCluster) {
// get new dot dot // get new dot dot
uint32_t block = vol_->clusterStartBlock(dirCluster); uint32_t block = vol_->clusterStartBlock(dirCluster);
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL;
memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry)); memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry));
// free unused cluster // free unused cluster
if (!vol_->freeChain(dirCluster)) goto fail; if (!vol_->freeChain(dirCluster)) goto FAIL;
// store new dot dot // store new dot dot
block = vol_->clusterStartBlock(firstCluster_); block = vol_->clusterStartBlock(firstCluster_);
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL;
memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry)); memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry));
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
restore: restore:
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
// restore entry // restore entry
d->name[0] = entry.name[0]; d->name[0] = entry.name[0];
vol_->cacheFlush(); vol_->cacheFlush();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1345,26 +1345,26 @@ fail:
*/ */
bool SdBaseFile::rmdir() { bool SdBaseFile::rmdir() {
// must be open subdirectory // must be open subdirectory
if (!isSubDir()) goto fail; if (!isSubDir()) goto FAIL;
rewind(); rewind();
// make sure directory is empty // make sure directory is empty
while (curPosition_ < fileSize_) { while (curPosition_ < fileSize_) {
dir_t* p = readDirCache(); dir_t* p = readDirCache();
if (!p) goto fail; if (!p) goto FAIL;
// done if past last used entry // done if past last used entry
if (p->name[0] == DIR_NAME_FREE) break; if (p->name[0] == DIR_NAME_FREE) break;
// skip empty slot, '.' or '..' // skip empty slot, '.' or '..'
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
// error not empty // error not empty
if (DIR_IS_FILE_OR_SUBDIR(p)) goto fail; if (DIR_IS_FILE_OR_SUBDIR(p)) goto FAIL;
} }
// convert empty directory to normal file for remove // convert empty directory to normal file for remove
type_ = FAT_FILE_TYPE_NORMAL; type_ = FAT_FILE_TYPE_NORMAL;
flags_ |= O_WRITE; flags_ |= O_WRITE;
return remove(); return remove();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1392,7 +1392,7 @@ bool SdBaseFile::rmRfStar() {
index = curPosition_ / 32; index = curPosition_ / 32;
dir_t* p = readDirCache(); dir_t* p = readDirCache();
if (!p) goto fail; if (!p) goto FAIL;
// done if past last entry // done if past last entry
if (p->name[0] == DIR_NAME_FREE) break; if (p->name[0] == DIR_NAME_FREE) break;
@ -1403,27 +1403,27 @@ bool SdBaseFile::rmRfStar() {
// skip if part of long file name or volume label in root // skip if part of long file name or volume label in root
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
if (!f.open(this, index, O_READ)) goto fail; if (!f.open(this, index, O_READ)) goto FAIL;
if (f.isSubDir()) { if (f.isSubDir()) {
// recursively delete // recursively delete
if (!f.rmRfStar()) goto fail; if (!f.rmRfStar()) goto FAIL;
} }
else { else {
// ignore read-only // ignore read-only
f.flags_ |= O_WRITE; f.flags_ |= O_WRITE;
if (!f.remove()) goto fail; if (!f.remove()) goto FAIL;
} }
// position to next entry if required // position to next entry if required
if (curPosition_ != (32 * (index + 1))) { if (curPosition_ != (32 * (index + 1))) {
if (!seekSet(32 * (index + 1))) goto fail; if (!seekSet(32 * (index + 1))) goto FAIL;
} }
} }
// don't try to delete root // don't try to delete root
if (!isRoot()) { if (!isRoot()) {
if (!rmdir()) goto fail; if (!rmdir()) goto FAIL;
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1451,7 +1451,7 @@ bool SdBaseFile::seekSet(uint32_t pos) {
uint32_t nCur; uint32_t nCur;
uint32_t nNew; uint32_t nNew;
// error if file not open or seek past end of file // error if file not open or seek past end of file
if (!isOpen() || pos > fileSize_) goto fail; if (!isOpen() || pos > fileSize_) goto FAIL;
if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { if (type_ == FAT_FILE_TYPE_ROOT_FIXED) {
curPosition_ = pos; curPosition_ = pos;
@ -1476,14 +1476,14 @@ bool SdBaseFile::seekSet(uint32_t pos) {
nNew -= nCur; nNew -= nCur;
} }
while (nNew--) { while (nNew--) {
if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL;
} }
curPosition_ = pos; curPosition_ = pos;
done: done:
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1502,12 +1502,12 @@ void SdBaseFile::setpos(filepos_t* pos) {
*/ */
bool SdBaseFile::sync() { bool SdBaseFile::sync() {
// only allow open files and directories // only allow open files and directories
if (!isOpen()) goto fail; if (!isOpen()) goto FAIL;
if (flags_ & F_FILE_DIR_DIRTY) { if (flags_ & F_FILE_DIR_DIRTY) {
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
// check for deleted by another open file object // check for deleted by another open file object
if (!d || d->name[0] == DIR_NAME_DELETED) goto fail; if (!d || d->name[0] == DIR_NAME_DELETED) goto FAIL;
// do not set filesize for dir files // do not set filesize for dir files
if (!isDir()) d->fileSize = fileSize_; if (!isDir()) d->fileSize = fileSize_;
@ -1526,7 +1526,7 @@ bool SdBaseFile::sync() {
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: FAIL:
writeError = true; writeError = true;
return false; return false;
} }
@ -1547,13 +1547,13 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
dir_t dir; dir_t dir;
// get timestamps // get timestamps
if (!file->dirEntry(&dir)) goto fail; if (!file->dirEntry(&dir)) goto FAIL;
// update directory fields // update directory fields
if (!sync()) goto fail; if (!sync()) goto FAIL;
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
// copy timestamps // copy timestamps
d->lastAccessDate = dir.lastAccessDate; d->lastAccessDate = dir.lastAccessDate;
@ -1566,7 +1566,7 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
// write back entry // write back entry
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1619,13 +1619,13 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|| hour > 23 || hour > 23
|| minute > 59 || minute > 59
|| second > 59) { || second > 59) {
goto fail; goto FAIL;
} }
// update directory entry // update directory entry
if (!sync()) goto fail; if (!sync()) goto FAIL;
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto FAIL;
dirDate = FAT_DATE(year, month, day); dirDate = FAT_DATE(year, month, day);
dirTime = FAT_TIME(hour, minute, second); dirTime = FAT_TIME(hour, minute, second);
@ -1643,7 +1643,7 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
d->lastWriteTime = dirTime; d->lastWriteTime = dirTime;
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1661,10 +1661,10 @@ fail:
bool SdBaseFile::truncate(uint32_t length) { bool SdBaseFile::truncate(uint32_t length) {
uint32_t newPos; uint32_t newPos;
// error if not a normal file or read-only // error if not a normal file or read-only
if (!isFile() || !(flags_ & O_WRITE)) goto fail; if (!isFile() || !(flags_ & O_WRITE)) goto FAIL;
// error if length is greater than current size // error if length is greater than current size
if (length > fileSize_) goto fail; if (length > fileSize_) goto FAIL;
// fileSize and length are zero - nothing to do // fileSize and length are zero - nothing to do
if (fileSize_ == 0) return true; if (fileSize_ == 0) return true;
@ -1673,23 +1673,23 @@ bool SdBaseFile::truncate(uint32_t length) {
newPos = curPosition_ > length ? length : curPosition_; newPos = curPosition_ > length ? length : curPosition_;
// position to last cluster in truncated file // position to last cluster in truncated file
if (!seekSet(length)) goto fail; if (!seekSet(length)) goto FAIL;
if (length == 0) { if (length == 0) {
// free all clusters // free all clusters
if (!vol_->freeChain(firstCluster_)) goto fail; if (!vol_->freeChain(firstCluster_)) goto FAIL;
firstCluster_ = 0; firstCluster_ = 0;
} }
else { else {
uint32_t toFree; uint32_t toFree;
if (!vol_->fatGet(curCluster_, &toFree)) goto fail; if (!vol_->fatGet(curCluster_, &toFree)) goto FAIL;
if (!vol_->isEOC(toFree)) { if (!vol_->isEOC(toFree)) {
// free extra clusters // free extra clusters
if (!vol_->freeChain(toFree)) goto fail; if (!vol_->freeChain(toFree)) goto FAIL;
// current cluster is end of chain // current cluster is end of chain
if (!vol_->fatPutEOC(curCluster_)) goto fail; if (!vol_->fatPutEOC(curCluster_)) goto FAIL;
} }
} }
fileSize_ = length; fileSize_ = length;
@ -1697,12 +1697,12 @@ bool SdBaseFile::truncate(uint32_t length) {
// need to update directory entry // need to update directory entry
flags_ |= F_FILE_DIR_DIRTY; flags_ |= F_FILE_DIR_DIRTY;
if (!sync()) goto fail; if (!sync()) goto FAIL;
// set file to correct position // set file to correct position
return seekSet(newPos); return seekSet(newPos);
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1729,11 +1729,11 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
uint16_t nToWrite = nbyte; uint16_t nToWrite = nbyte;
// error if not a normal file or is read-only // error if not a normal file or is read-only
if (!isFile() || !(flags_ & O_WRITE)) goto fail; if (!isFile() || !(flags_ & O_WRITE)) goto FAIL;
// seek to end of file if append flag // seek to end of file if append flag
if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
if (!seekEnd()) goto fail; if (!seekEnd()) goto FAIL;
} }
while (nToWrite > 0) { while (nToWrite > 0) {
@ -1744,7 +1744,7 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
if (curCluster_ == 0) { if (curCluster_ == 0) {
if (firstCluster_ == 0) { if (firstCluster_ == 0) {
// allocate first cluster of file // allocate first cluster of file
if (!addCluster()) goto fail; if (!addCluster()) goto FAIL;
} }
else { else {
curCluster_ = firstCluster_; curCluster_ = firstCluster_;
@ -1752,10 +1752,10 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
} }
else { else {
uint32_t next; uint32_t next;
if (!vol_->fatGet(curCluster_, &next)) goto fail; if (!vol_->fatGet(curCluster_, &next)) goto FAIL;
if (vol_->isEOC(next)) { if (vol_->isEOC(next)) {
// add cluster if at end of chain // add cluster if at end of chain
if (!addCluster()) goto fail; if (!addCluster()) goto FAIL;
} }
else { else {
curCluster_ = next; curCluster_ = next;
@ -1776,18 +1776,18 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
// invalidate cache if block is in cache // invalidate cache if block is in cache
vol_->cacheSetBlockNumber(0xFFFFFFFF, false); vol_->cacheSetBlockNumber(0xFFFFFFFF, false);
} }
if (!vol_->writeBlock(block, src)) goto fail; if (!vol_->writeBlock(block, src)) goto FAIL;
} }
else { else {
if (blockOffset == 0 && curPosition_ >= fileSize_) { if (blockOffset == 0 && curPosition_ >= fileSize_) {
// start of new block don't need to read into cache // start of new block don't need to read into cache
if (!vol_->cacheFlush()) goto fail; if (!vol_->cacheFlush()) goto FAIL;
// set cache dirty and SD address of block // set cache dirty and SD address of block
vol_->cacheSetBlockNumber(block, true); vol_->cacheSetBlockNumber(block, true);
} }
else { else {
// rewrite part of block // rewrite part of block
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL;
} }
uint8_t* dst = vol_->cache()->data + blockOffset; uint8_t* dst = vol_->cache()->data + blockOffset;
memcpy(dst, src, n); memcpy(dst, src, n);
@ -1807,11 +1807,11 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
} }
if (flags_ & O_SYNC) { if (flags_ & O_SYNC) {
if (!sync()) goto fail; if (!sync()) goto FAIL;
} }
return nbyte; return nbyte;
fail: FAIL:
// return for write error // return for write error
writeError = true; writeError = true;
return -1; return -1;

@ -73,14 +73,14 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
// search the FAT for free clusters // search the FAT for free clusters
for (uint32_t n = 0;; n++, endCluster++) { for (uint32_t n = 0;; n++, endCluster++) {
// can't find space checked all clusters // can't find space checked all clusters
if (n >= clusterCount_) goto fail; if (n >= clusterCount_) goto FAIL;
// past end - start from beginning of FAT // past end - start from beginning of FAT
if (endCluster > fatEnd) { if (endCluster > fatEnd) {
bgnCluster = endCluster = 2; bgnCluster = endCluster = 2;
} }
uint32_t f; uint32_t f;
if (!fatGet(endCluster, &f)) goto fail; if (!fatGet(endCluster, &f)) goto FAIL;
if (f != 0) { if (f != 0) {
// cluster in use try next cluster as bgnCluster // cluster in use try next cluster as bgnCluster
@ -92,16 +92,16 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
} }
} }
// mark end of chain // mark end of chain
if (!fatPutEOC(endCluster)) goto fail; if (!fatPutEOC(endCluster)) goto FAIL;
// link clusters // link clusters
while (endCluster > bgnCluster) { while (endCluster > bgnCluster) {
if (!fatPut(endCluster - 1, endCluster)) goto fail; if (!fatPut(endCluster - 1, endCluster)) goto FAIL;
endCluster--; endCluster--;
} }
if (*curCluster != 0) { if (*curCluster != 0) {
// connect chains // connect chains
if (!fatPut(*curCluster, bgnCluster)) goto fail; if (!fatPut(*curCluster, bgnCluster)) goto FAIL;
} }
// return first cluster number to caller // return first cluster number to caller
*curCluster = bgnCluster; *curCluster = bgnCluster;
@ -110,38 +110,38 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
if (setStart) allocSearchStart_ = bgnCluster + 1; if (setStart) allocSearchStart_ = bgnCluster + 1;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool SdVolume::cacheFlush() { bool SdVolume::cacheFlush() {
if (cacheDirty_) { if (cacheDirty_) {
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) {
goto fail; goto FAIL;
} }
// mirror FAT tables // mirror FAT tables
if (cacheMirrorBlock_) { if (cacheMirrorBlock_) {
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) {
goto fail; goto FAIL;
} }
cacheMirrorBlock_ = 0; cacheMirrorBlock_ = 0;
} }
cacheDirty_ = 0; cacheDirty_ = 0;
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) { bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) {
if (cacheBlockNumber_ != blockNumber) { if (cacheBlockNumber_ != blockNumber) {
if (!cacheFlush()) goto fail; if (!cacheFlush()) goto FAIL;
if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto fail; if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto FAIL;
cacheBlockNumber_ = blockNumber; cacheBlockNumber_ = blockNumber;
} }
if (dirty) cacheDirty_ = true; if (dirty) cacheDirty_ = true;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -149,29 +149,29 @@ fail:
bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) { bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
uint32_t s = 0; uint32_t s = 0;
do { do {
if (!fatGet(cluster, &cluster)) goto fail; if (!fatGet(cluster, &cluster)) goto FAIL;
s += 512UL << clusterSizeShift_; s += 512UL << clusterSizeShift_;
} while (!isEOC(cluster)); } while (!isEOC(cluster));
*size = s; *size = s;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Fetch a FAT entry // Fetch a FAT entry
bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
uint32_t lba; uint32_t lba;
if (cluster > (clusterCount_ + 1)) goto fail; if (cluster > (clusterCount_ + 1)) goto FAIL;
if (FAT12_SUPPORT && fatType_ == 12) { if (FAT12_SUPPORT && fatType_ == 12) {
uint16_t index = cluster; uint16_t index = cluster;
index += index >> 1; index += index >> 1;
lba = fatStartBlock_ + (index >> 9); lba = fatStartBlock_ + (index >> 9);
if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL;
index &= 0x1FF; index &= 0x1FF;
uint16_t tmp = cacheBuffer_.data[index]; uint16_t tmp = cacheBuffer_.data[index];
index++; index++;
if (index == 512) { if (index == 512) {
if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto FAIL;
index = 0; index = 0;
} }
tmp |= cacheBuffer_.data[index] << 8; tmp |= cacheBuffer_.data[index] << 8;
@ -185,10 +185,10 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
lba = fatStartBlock_ + (cluster >> 7); lba = fatStartBlock_ + (cluster >> 7);
} }
else { else {
goto fail; goto FAIL;
} }
if (lba != cacheBlockNumber_) { if (lba != cacheBlockNumber_) {
if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL;
} }
if (fatType_ == 16) { if (fatType_ == 16) {
*value = cacheBuffer_.fat16[cluster & 0xFF]; *value = cacheBuffer_.fat16[cluster & 0xFF];
@ -197,7 +197,7 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
*value = cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK; *value = cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK;
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -205,16 +205,16 @@ fail:
bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
uint32_t lba; uint32_t lba;
// error if reserved cluster // error if reserved cluster
if (cluster < 2) goto fail; if (cluster < 2) goto FAIL;
// error if not in FAT // error if not in FAT
if (cluster > (clusterCount_ + 1)) goto fail; if (cluster > (clusterCount_ + 1)) goto FAIL;
if (FAT12_SUPPORT && fatType_ == 12) { if (FAT12_SUPPORT && fatType_ == 12) {
uint16_t index = cluster; uint16_t index = cluster;
index += index >> 1; index += index >> 1;
lba = fatStartBlock_ + (index >> 9); lba = fatStartBlock_ + (index >> 9);
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL;
// mirror second FAT // mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
index &= 0x1FF; index &= 0x1FF;
@ -227,7 +227,7 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
if (index == 512) { if (index == 512) {
lba++; lba++;
index = 0; index = 0;
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL;
// mirror second FAT // mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
} }
@ -245,9 +245,9 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
lba = fatStartBlock_ + (cluster >> 7); lba = fatStartBlock_ + (cluster >> 7);
} }
else { else {
goto fail; goto FAIL;
} }
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL;
// store entry // store entry
if (fatType_ == 16) { if (fatType_ == 16) {
cacheBuffer_.fat16[cluster & 0xFF] = value; cacheBuffer_.fat16[cluster & 0xFF] = value;
@ -258,7 +258,7 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
// mirror second FAT // mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -270,16 +270,16 @@ bool SdVolume::freeChain(uint32_t cluster) {
allocSearchStart_ = 2; allocSearchStart_ = 2;
do { do {
if (!fatGet(cluster, &next)) goto fail; if (!fatGet(cluster, &next)) goto FAIL;
// free cluster // free cluster
if (!fatPut(cluster, 0)) goto fail; if (!fatPut(cluster, 0)) goto FAIL;
cluster = next; cluster = next;
} while (!isEOC(cluster)); } while (!isEOC(cluster));
return true; return true;
fail: FAIL:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -349,25 +349,25 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
// if part == 0 assume super floppy with FAT boot sector in block zero // if part == 0 assume super floppy with FAT boot sector in block zero
// if part > 0 assume mbr volume with partition table // if part > 0 assume mbr volume with partition table
if (part) { if (part) {
if (part > 4)goto fail; if (part > 4)goto FAIL;
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL;
part_t* p = &cacheBuffer_.mbr.part[part - 1]; part_t* p = &cacheBuffer_.mbr.part[part - 1];
if ((p->boot & 0x7F) != 0 || if ((p->boot & 0x7F) != 0 ||
p->totalSectors < 100 || p->totalSectors < 100 ||
p->firstSector == 0) { p->firstSector == 0) {
// not a valid partition // not a valid partition
goto fail; goto FAIL;
} }
volumeStartBlock = p->firstSector; volumeStartBlock = p->firstSector;
} }
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL;
fbs = &cacheBuffer_.fbs32; fbs = &cacheBuffer_.fbs32;
if (fbs->bytesPerSector != 512 || if (fbs->bytesPerSector != 512 ||
fbs->fatCount == 0 || fbs->fatCount == 0 ||
fbs->reservedSectorCount == 0 || fbs->reservedSectorCount == 0 ||
fbs->sectorsPerCluster == 0) { fbs->sectorsPerCluster == 0) {
// not valid FAT volume // not valid FAT volume
goto fail; goto FAIL;
} }
fatCount_ = fbs->fatCount; fatCount_ = fbs->fatCount;
blocksPerCluster_ = fbs->sectorsPerCluster; blocksPerCluster_ = fbs->sectorsPerCluster;
@ -375,7 +375,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
clusterSizeShift_ = 0; clusterSizeShift_ = 0;
while (blocksPerCluster_ != _BV(clusterSizeShift_)) { while (blocksPerCluster_ != _BV(clusterSizeShift_)) {
// error if not power of 2 // error if not power of 2
if (clusterSizeShift_++ > 7) goto fail; if (clusterSizeShift_++ > 7) goto FAIL;
} }
blocksPerFat_ = fbs->sectorsPerFat16 ? blocksPerFat_ = fbs->sectorsPerFat16 ?
fbs->sectorsPerFat16 : fbs->sectorsPerFat32; fbs->sectorsPerFat16 : fbs->sectorsPerFat32;
@ -404,7 +404,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
// FAT type is determined by cluster count // FAT type is determined by cluster count
if (clusterCount_ < 4085) { if (clusterCount_ < 4085) {
fatType_ = 12; fatType_ = 12;
if (!FAT12_SUPPORT) goto fail; if (!FAT12_SUPPORT) goto FAIL;
} }
else if (clusterCount_ < 65525) { else if (clusterCount_ < 65525) {
fatType_ = 16; fatType_ = 16;
@ -414,7 +414,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
fatType_ = 32; fatType_ = 32;
} }
return true; return true;
fail: FAIL:
return false; return false;
} }
#endif #endif

Loading…
Cancel
Save