Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/elfmz/far2l.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelfmz <fenix1905@tut.by>2022-11-04 01:31:19 +0300
committerelfmz <fenix1905@tut.by>2022-11-04 01:31:19 +0300
commit7a4a5d072a11681c2727db57ad2dffcfae3c8652 (patch)
tree3453656a61864fbc8607f00fda99b375363eab28
parentea8fdf19cc60d78ec00a528890443dd9c977788c (diff)
viewer: prebuffer up to 16 megs of pseudofiles (fix #1384)
-rw-r--r--far2l/src/cache.cpp39
-rw-r--r--far2l/src/cache.hpp2
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>