From e6e108d091c0802558b98a0e46ba9f86cdd53b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:55:17 +0200 Subject: [PATCH] Implement `get_length()` for pipes. --- core/io/file_access.cpp | 2 +- doc/classes/FileAccess.xml | 2 +- drivers/unix/file_access_unix_pipe.cpp | 9 +++++++++ drivers/unix/file_access_unix_pipe.h | 2 +- drivers/windows/file_access_windows_pipe.cpp | 8 ++++++++ drivers/windows/file_access_windows_pipe.h | 2 +- 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 230184ad04b..7d422bf0946 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -451,7 +451,7 @@ String FileAccess::get_line() const { uint8_t c = get_8(); while (!eof_reached()) { - if (c == '\n' || c == '\0') { + if (c == '\n' || c == '\0' || get_error() != OK) { line.push_back(0); return String::utf8(line.get_data()); } else if (c != '\r') { diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml index a2ee5a13230..03a1146a913 100644 --- a/doc/classes/FileAccess.xml +++ b/doc/classes/FileAccess.xml @@ -204,7 +204,7 @@ - Returns the size of the file in bytes. + Returns the size of the file in bytes. For a pipe, returns the number of bytes available for reading from the pipe. diff --git a/drivers/unix/file_access_unix_pipe.cpp b/drivers/unix/file_access_unix_pipe.cpp index 775d3f7d867..56be559a34c 100644 --- a/drivers/unix/file_access_unix_pipe.cpp +++ b/drivers/unix/file_access_unix_pipe.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -132,6 +133,14 @@ String FileAccessUnixPipe::get_path_absolute() const { return path_src; } +uint64_t FileAccessUnixPipe::get_length() const { + ERR_FAIL_COND_V_MSG(fd[0] < 0, 0, "Pipe must be opened before use."); + + int buf_rem = 0; + ERR_FAIL_COND_V(ioctl(fd[0], FIONREAD, &buf_rem) != 0, 0); + return buf_rem; +} + uint64_t FileAccessUnixPipe::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V_MSG(fd[0] < 0, -1, "Pipe must be opened before use."); ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); diff --git a/drivers/unix/file_access_unix_pipe.h b/drivers/unix/file_access_unix_pipe.h index a95cbc8e614..b1633db015c 100644 --- a/drivers/unix/file_access_unix_pipe.h +++ b/drivers/unix/file_access_unix_pipe.h @@ -61,7 +61,7 @@ public: virtual void seek(uint64_t p_position) override {} virtual void seek_end(int64_t p_position = 0) override {} virtual uint64_t get_position() const override { return 0; } - virtual uint64_t get_length() const override { return 0; } + virtual uint64_t get_length() const override; virtual bool eof_reached() const override { return false; } diff --git a/drivers/windows/file_access_windows_pipe.cpp b/drivers/windows/file_access_windows_pipe.cpp index 88e76f67ef5..6960e9d7153 100644 --- a/drivers/windows/file_access_windows_pipe.cpp +++ b/drivers/windows/file_access_windows_pipe.cpp @@ -102,6 +102,14 @@ String FileAccessWindowsPipe::get_path_absolute() const { return path_src; } +uint64_t FileAccessWindowsPipe::get_length() const { + ERR_FAIL_COND_V_MSG(fd[0] == nullptr, -1, "Pipe must be opened before use."); + + DWORD buf_rem = 0; + ERR_FAIL_COND_V(!PeekNamedPipe(fd[0], nullptr, 0, nullptr, &buf_rem, nullptr), 0); + return buf_rem; +} + uint64_t FileAccessWindowsPipe::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V_MSG(fd[0] == nullptr, -1, "Pipe must be opened before use."); ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); diff --git a/drivers/windows/file_access_windows_pipe.h b/drivers/windows/file_access_windows_pipe.h index b01b48fe133..0eb570ae229 100644 --- a/drivers/windows/file_access_windows_pipe.h +++ b/drivers/windows/file_access_windows_pipe.h @@ -60,7 +60,7 @@ public: virtual void seek(uint64_t p_position) override {} virtual void seek_end(int64_t p_position = 0) override {} virtual uint64_t get_position() const override { return 0; } - virtual uint64_t get_length() const override { return 0; } + virtual uint64_t get_length() const override; virtual bool eof_reached() const override { return false; }