Skip to content

BUGFIX - FS.read / seek fixes #6536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions libraries/FS/src/vfs_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,21 +376,33 @@ size_t VFSFileImpl::read(uint8_t* buf, size_t size)
if(_isDirectory || !_f || !buf || !size) {
return 0;
}

//ERASE BYTEBUFFER and use read when size > READ_SIZE_SWITCH always
if(size > READ_SIZE_SWITCH)

if(size > READ_SIZE_SWITCH) //to be tested -> switch between fread/read to optimize speeds (call sd status check only once for each read)
{
//check some data in buffer exists –> clear buffer and move pointer to deleted data
size_t bytesinbuf = __fpending(_f);
if (bytesinbuf && (bytesinbuf != 128)) //buffer lenght is 128 bytes
size_t buf_size = __fbufsize(_f);

if (bytesinbuf && (bytesinbuf != buf_size)) //buffer size SD=128 , LittleFS=4096
{
fpos_t pointer = 0;
//clear buffer
fpurge(_f);
lseek(fileno(_f),(-128+bytesinbuf),SEEK_CUR);
//get file pointer
fgetpos(_f, &pointer);

if(pointer <= buf_size){
lseek(fileno(_f),(-pointer+bytesinbuf),SEEK_CUR);
}
else{
uint64_t modulo = pointer % buf_size;
lseek(fileno(_f),(-modulo+bytesinbuf),SEEK_CUR);
}
}

int res = ::read(fileno(_f), buf, size);
if (res < 0) {
// an error occurred
log_d("FILE READ ERROR OCCURED");
return 0;
}
return res;
Expand All @@ -416,16 +428,24 @@ bool VFSFileImpl::seek(uint32_t pos, SeekMode mode)
if(_isDirectory || !_f) {
return false;
}
auto rc = fseek(_f, pos, mode);
return rc == 0;

fpurge(_f); //clear the file internal buffer -> no longer valid when changing file position
off_t res = lseek(fileno(_f), pos, mode);
if (res < 0) {
// an error occurred
log_d("FILE SEEK ERROR OCCURED");
return 0; //return error -> for lseek its all above 0
}
return 1; //return success -> for fseek its 0
}

size_t VFSFileImpl::position() const
{
if(_isDirectory || !_f) {
return 0;
}
return ftell(_f);
return lseek(fileno(_f), 0, SEEK_CUR);
//return ftell(_f); // old implementation
}

size_t VFSFileImpl::size() const
Expand Down