From 4cf88810db2fd4b2544c529e208f9945d59de6c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Tue, 12 Apr 2022 12:08:09 +0200
Subject: [PATCH 1/2] Revert "Edited VFSFileImpl::read to use both read/fread
 (#6456)"

This reverts commit 7b89b39e1087742ada6e8992159390f885c07919.
---
 libraries/FS/src/vfs_api.cpp | 26 +-------------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp
index 9e200a1500b..e43b4397452 100644
--- a/libraries/FS/src/vfs_api.cpp
+++ b/libraries/FS/src/vfs_api.cpp
@@ -13,12 +13,9 @@
 // limitations under the License.
 
 #include "vfs_api.h"
-#include <stdio_ext.h>
 
 using namespace fs;
 
-#define READ_SIZE_SWITCH 128    //swithc to read func when read size > 128bytes
-
 FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create)
 {
     if(!_mountpoint) {
@@ -377,28 +374,7 @@ size_t VFSFileImpl::read(uint8_t* buf, size_t size)
         return 0;
     }
 
-    //ERASE BYTEBUFFER and use read when size > READ_SIZE_SWITCH always
-    if(size > READ_SIZE_SWITCH)
-    {
-        //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
-        {
-            fpurge(_f);
-            lseek(fileno(_f),(-128+bytesinbuf),SEEK_CUR);
-        }
-
-        int res = ::read(fileno(_f), buf, size);
-        if (res < 0) {
-            // an error occurred
-            return 0;
-        }
-        return res;
-    }
-    else
-    {
-        return fread(buf, 1, size, _f);
-    }
+    return fread(buf, 1, size, _f);
 }
 
 void VFSFileImpl::flush()

From 757479c2b3c764870255c46b850807ce93a559b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Tue, 12 Apr 2022 12:16:23 +0200
Subject: [PATCH 2/2] Added default file buffer size + function to change it by
 user

---
 libraries/FS/src/FS.cpp      |  9 +++++++++
 libraries/FS/src/FS.h        |  1 +
 libraries/FS/src/FSImpl.h    |  1 +
 libraries/FS/src/vfs_api.cpp | 23 +++++++++++++++++++++++
 libraries/FS/src/vfs_api.h   |  3 ++-
 5 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/libraries/FS/src/FS.cpp b/libraries/FS/src/FS.cpp
index f5e9a8ab2cc..80d0958a759 100644
--- a/libraries/FS/src/FS.cpp
+++ b/libraries/FS/src/FS.cpp
@@ -130,6 +130,15 @@ size_t File::size() const
     return _p->size();
 }
 
+bool File::setBufferSize(size_t size)
+{
+    if (!*this) {
+        return 0;
+    }
+
+    return _p->setBufferSize(size);
+}
+
 void File::close()
 {
     if (_p) {
diff --git a/libraries/FS/src/FS.h b/libraries/FS/src/FS.h
index c3a1c51c5ec..64e630c4577 100644
--- a/libraries/FS/src/FS.h
+++ b/libraries/FS/src/FS.h
@@ -70,6 +70,7 @@ class File : public Stream
     }
     size_t position() const;
     size_t size() const;
+    bool setBufferSize(size_t size);
     void close();
     operator bool() const;
     time_t getLastWrite();
diff --git a/libraries/FS/src/FSImpl.h b/libraries/FS/src/FSImpl.h
index 4c5c9786840..bb20cd499ae 100644
--- a/libraries/FS/src/FSImpl.h
+++ b/libraries/FS/src/FSImpl.h
@@ -36,6 +36,7 @@ class FileImpl
     virtual bool seek(uint32_t pos, SeekMode mode) = 0;
     virtual size_t position() const = 0;
     virtual size_t size() const = 0;
+    virtual bool setBufferSize(size_t size) = 0;
     virtual void close() = 0;
     virtual time_t getLastWrite() = 0;
     virtual const char* path() const = 0;
diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp
index e43b4397452..25a27c70bcf 100644
--- a/libraries/FS/src/vfs_api.cpp
+++ b/libraries/FS/src/vfs_api.cpp
@@ -16,6 +16,8 @@
 
 using namespace fs;
 
+#define DEFAULT_FILE_BUFFER_SIZE 4096
+
 FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create)
 {
     if(!_mountpoint) {
@@ -280,6 +282,10 @@ VFSFileImpl::VFSFileImpl(VFSImpl* fs, const char* fpath, const char* mode)
             if(!_f) {
                 log_e("fopen(%s) failed", temp);
             }
+            if(_f && (_stat.st_blksize == 0))
+            {
+                setvbuf(_f,NULL,_IOFBF,DEFAULT_FILE_BUFFER_SIZE);
+            } 
         } else if(S_ISDIR(_stat.st_mode)) {
             _isDirectory = true;
             _d = opendir(temp);
@@ -307,6 +313,10 @@ VFSFileImpl::VFSFileImpl(VFSImpl* fs, const char* fpath, const char* mode)
             if(!_f) {
                 log_e("fopen(%s) failed", temp);
             }
+            if(_f && (_stat.st_blksize == 0))
+            {
+                setvbuf(_f,NULL,_IOFBF,DEFAULT_FILE_BUFFER_SIZE);
+            } 
         }
     }
     free(temp);
@@ -415,6 +425,19 @@ size_t VFSFileImpl::size() const
     return _stat.st_size;
 }
 
+/*
+* Change size of files internal buffer used for read / write operations.
+* Need to be called right after opening file before any other operation!
+*/
+bool VFSFileImpl::setBufferSize(size_t size)
+{
+    if(_isDirectory || !_f) {
+        return 0;
+    }
+    int res = setvbuf(_f,NULL,_IOFBF,size);
+    return res == 0;
+}
+
 const char* VFSFileImpl::path() const
 {
     return (const char*) _path;
diff --git a/libraries/FS/src/vfs_api.h b/libraries/FS/src/vfs_api.h
index f79852cdcfe..780c334aa5c 100644
--- a/libraries/FS/src/vfs_api.h
+++ b/libraries/FS/src/vfs_api.h
@@ -65,10 +65,11 @@ class VFSFileImpl : public FileImpl
     bool        seek(uint32_t pos, SeekMode mode) override;
     size_t      position() const override;
     size_t      size() const override;
+    bool        setBufferSize(size_t size);
     void        close() override;
     const char* path() const override;
     const char* name() const override;
-    time_t getLastWrite()  override;
+    time_t      getLastWrite()  override;
     boolean     isDirectory(void) override;
     FileImplPtr openNextFile(const char* mode) override;
     void        rewindDirectory(void) override;