diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-17 15:54:43 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-17 15:54:43 +0100 |
commit | ce7017e1ec46e00d3a36308f4ce951f03d5c9624 (patch) | |
tree | 41ddeae5752e3445bc328d45e862ebcfbe684d6c /LibGUI/GIODevice.cpp | |
parent | ef05d8cbf6ac5e378d3d9205ef095de754f6a8d2 (diff) | |
download | serenity-ce7017e1ec46e00d3a36308f4ce951f03d5c9624.zip |
LibGUI: Add GFile and base class GIODevice.
Working with the LibC API's is tedious, so let's add some comfy C++ API's.
Diffstat (limited to 'LibGUI/GIODevice.cpp')
-rw-r--r-- | LibGUI/GIODevice.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/LibGUI/GIODevice.cpp b/LibGUI/GIODevice.cpp new file mode 100644 index 0000000000..d62d36622f --- /dev/null +++ b/LibGUI/GIODevice.cpp @@ -0,0 +1,89 @@ +#include <LibGUI/GIODevice.h> +#include <unistd.h> + +GIODevice::GIODevice(GObject* parent) + : GObject(parent) +{ +} + +GIODevice::~GIODevice() +{ +} + +const char* GIODevice::error_string() const +{ + return strerror(m_error); +} + +ByteBuffer GIODevice::read(int max_size) +{ + if (m_fd < 0) + return { }; + if (!max_size) + return { }; + auto buffer = ByteBuffer::create_uninitialized(max_size); + auto* buffer_ptr = (char*)buffer.pointer(); + int remaining_buffer_space = buffer.size(); + if (!m_buffered_data.is_empty()) { + int taken_from_buffered = min(remaining_buffer_space, m_buffered_data.size()); + memcpy(buffer_ptr, m_buffered_data.data(), taken_from_buffered); + Vector<byte> new_buffered_data; + new_buffered_data.append(m_buffered_data.data() + taken_from_buffered, m_buffered_data.size() - taken_from_buffered); + m_buffered_data = move(new_buffered_data); + remaining_buffer_space -= taken_from_buffered; + buffer_ptr += taken_from_buffered; + } + if (!remaining_buffer_space) + return buffer; + int nread = ::read(m_fd, buffer_ptr, remaining_buffer_space); + if (nread < 0) { + set_error(errno); + return { }; + } + buffer.trim(nread); + return buffer; +} + +ByteBuffer GIODevice::read_line(int max_size) +{ + if (m_fd < 0) + return { }; + if (!max_size) + return { }; + auto line = ByteBuffer::create_uninitialized(max_size); + int line_index = 0; + while (line_index < line.size()) { + if (line_index >= m_buffered_data.size()) { + if (!populate_read_buffer()) + return { }; + } + byte ch = m_buffered_data[line_index]; + line[line_index++] = ch; + if (ch == '\n') { + Vector<byte> new_buffered_data; + new_buffered_data.append(m_buffered_data.data() + line_index, m_buffered_data.size() - line_index); + m_buffered_data = move(new_buffered_data); + line.trim(line_index); + return line; + } + } + return { }; +} + +bool GIODevice::populate_read_buffer() +{ + if (m_fd < 0) + return false; + auto buffer = ByteBuffer::create_uninitialized(1024); + int nread = ::read(m_fd, buffer.pointer(), buffer.size()); + if (nread < 0) { + set_error(errno); + return false; + } + if (nread == 0) { + set_eof(true); + return false; + } + m_buffered_data.append(buffer.pointer(), buffer.size()); + return true; +} |