Skip to content

Commit

Permalink
AP_Filesystem: make fgets() much more efficient
Browse files Browse the repository at this point in the history
normally fgets is on a buffered FILE handle. For AP_Filesystem we use
an unbuffered file descriptor. This means we were reading one byte at
a time from the file

this uses lseek to make fgets() much more efficient by reading the max
buffer size at a time in the file
  • Loading branch information
tridge authored and peterbarker committed Jul 10, 2024
1 parent 0d12cc7 commit c2e52af
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions libraries/AP_Filesystem/AP_Filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,31 @@ bool AP_Filesystem::fgets(char *buf, uint8_t buflen, int fd)
{
const Backend &backend = backend_by_fd(fd);

// we will need to seek back to the right location at the end
auto offset_start = backend.fs.lseek(fd, 0, SEEK_CUR);
if (offset_start < 0) {
return false;
}

auto n = backend.fs.read(fd, buf, buflen);
if (n <= 0) {
return false;
}

uint8_t i = 0;
for (; i<buflen-1; i++) {
if (backend.fs.read(fd, &buf[i], 1) <= 0) {
if (i==0) {
return false;
}
break;
}
for (; i < n; i++) {
if (buf[i] == '\r' || buf[i] == '\n') {
break;
}
}
buf[i] = '\0';

// get back to the right offset
if (backend.fs.lseek(fd, offset_start+i+1, SEEK_SET) != offset_start+i+1) {
// we need to fail if we can't seek back or the caller may loop or get corrupt data
return false;
}

return true;
}

Expand Down

0 comments on commit c2e52af

Please sign in to comment.