diff options
author | elfmz <fenix1905@tut.by> | 2022-11-04 01:31:19 +0300 |
---|---|---|
committer | elfmz <fenix1905@tut.by> | 2022-11-04 01:31:19 +0300 |
commit | 7a4a5d072a11681c2727db57ad2dffcfae3c8652 (patch) | |
tree | 3453656a61864fbc8607f00fda99b375363eab28 /far2l | |
parent | ea8fdf19cc60d78ec00a528890443dd9c977788c (diff) |
viewer: prebuffer up to 16 megs of pseudofiles (fix #1384)
Diffstat (limited to 'far2l')
-rw-r--r-- | far2l/src/cache.cpp | 39 | ||||
-rw-r--r-- | far2l/src/cache.hpp | 2 |
2 files changed, 39 insertions, 2 deletions
diff --git a/far2l/src/cache.cpp b/far2l/src/cache.cpp index fb18b8a3..a3f33bce 100644 --- a/far2l/src/cache.cpp +++ b/far2l/src/cache.cpp @@ -36,6 +36,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <fcntl.h> +#define PSEUDOFILE_FULLREAD_LIMIT 0x1000000 +#define PSEUDOFILE_FULLREAD_BLOCK 0x1000 BufferedFileView::BufferedFileView() { @@ -62,6 +64,34 @@ bool BufferedFileView::Open(const std::string &PathName) FileSize = 0; ActualizeFileSize(); + + if (FileSize == 0) { + std::vector<unsigned char> Tmp(PSEUDOFILE_FULLREAD_BLOCK); + for (size_t ofs = 0;;) { + ssize_t rv = sdc_read(FD, Tmp.data() + ofs, Tmp.size() - ofs); + if (rv <= 0) { + Tmp.resize(ofs); + break; + } + ofs+= (size_t)rv; + if (ofs >= PSEUDOFILE_FULLREAD_LIMIT) { + Tmp.resize(ofs); + break; + } + if (Tmp.size() <= ofs) { + Tmp.resize(Tmp.size() + PSEUDOFILE_FULLREAD_BLOCK); + } + } + if (!Tmp.empty()) { + Buffer = AllocBuffer(Tmp.size()); + memcpy(Buffer, Tmp.data(), Tmp.size()); + FileSize = Tmp.size(); + BufferBounds.Ptr = 0; + BufferBounds.End = Tmp.size(); + PseudoFile = true; + } + } + return true; } @@ -96,7 +126,7 @@ void BufferedFileView::Close() void BufferedFileView::ActualizeFileSize() { struct stat s = {}; - if (FD != -1 && sdc_fstat(FD, &s) == 0 && FileSize != (UINT64)s.st_size) { + if (FD != -1 && !PseudoFile && sdc_fstat(FD, &s) == 0 && FileSize != (UINT64)s.st_size) { Clear(); FileSize = s.st_size; } @@ -129,6 +159,11 @@ LPBYTE BufferedFileView::ViewBytesAt(UINT64 Ptr, DWORD &Size) return &Buffer[CheckedCast<size_t>(Ptr - BufferBounds.Ptr)]; } + if (PseudoFile) { + Size = 0; + return nullptr; + } + Bounds NewBufferBounds; if (Ptr < LastPtr) { // backward buffering CalcBufferBounds(NewBufferBounds, Ptr, Size, AheadCount, BehindCount); @@ -207,7 +242,7 @@ LPBYTE BufferedFileView::ViewBytesAt(UINT64 Ptr, DWORD &Size) LPBYTE BufferedFileView::AllocBuffer(size_t Size) { - void *ptr; + void *ptr = nullptr; if (posix_memalign(&ptr, AlignSize, Size) != 0) { ptr = (LPBYTE)malloc(Size); } diff --git a/far2l/src/cache.hpp b/far2l/src/cache.hpp index a800ad3b..dc0c4beb 100644 --- a/far2l/src/cache.hpp +++ b/far2l/src/cache.hpp @@ -84,6 +84,8 @@ private: DWORD BufferSize = 0; UINT64 CurPtr = 0, LastPtr = 0; UINT64 FileSize = 0; + // something from /proc/ that has zero stat size but still can read some content from it + bool PseudoFile = false; template <class T> |