mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:27:35 +00:00
Spreadsheet: Generate file previews in memory and save directly to file
When we were asked to make a new preview text, we first generated the whole file in the /tmp directory and then read the first 8 lines to put them in a text box. This was doing a bit of unnecessary work at first, but more importantly, didn't work on a given file descriptor from FileSystemAccessServer as we were copying a file to a filename instead, meaning that we also had to unveil the whole home directory. Anyway, previews will be written now to a MemoryStream by the generator, which will limit to 8 lines. File saves will omit /tmp entirely, allowing us to tighten program unveil list a little. :^)
This commit is contained in:
parent
c74441395b
commit
29a3cdcfb7
4 changed files with 60 additions and 113 deletions
|
@ -53,17 +53,15 @@ constexpr WriterBehavior default_behaviors()
|
|||
template<typename ContainerType, typename HeaderType = Vector<StringView>>
|
||||
class XSV {
|
||||
public:
|
||||
XSV(OutputStream& output, ContainerType const& data, WriterTraits const& traits, HeaderType const& headers = {}, WriterBehavior behaviors = default_behaviors())
|
||||
XSV(OutputStream& output, ContainerType const& data, WriterTraits traits, HeaderType const& headers = {}, WriterBehavior behaviors = default_behaviors())
|
||||
: m_data(data)
|
||||
, m_traits(traits)
|
||||
, m_traits(move(traits))
|
||||
, m_behaviors(behaviors)
|
||||
, m_names(headers)
|
||||
, m_output(output)
|
||||
{
|
||||
if (!headers.is_empty())
|
||||
m_behaviors = m_behaviors | WriterBehavior::WriteHeaders;
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
virtual ~XSV() = default;
|
||||
|
@ -83,13 +81,6 @@ public:
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
private:
|
||||
void set_error(WriteError error)
|
||||
{
|
||||
if (m_error == WriteError::None)
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
void generate()
|
||||
{
|
||||
auto with_headers = has_flag(m_behaviors, WriterBehavior::WriteHeaders);
|
||||
|
@ -111,6 +102,42 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void generate_preview()
|
||||
{
|
||||
auto lines_written = 0;
|
||||
constexpr auto max_preview_lines = 8;
|
||||
|
||||
auto with_headers = has_flag(m_behaviors, WriterBehavior::WriteHeaders);
|
||||
if (with_headers) {
|
||||
write_row(m_names);
|
||||
if (m_output.write({ "\n", 1 }) != 1)
|
||||
set_error(WriteError::InternalError);
|
||||
++lines_written;
|
||||
}
|
||||
|
||||
for (auto&& row : m_data) {
|
||||
if (with_headers) {
|
||||
if (row.size() != m_names.size())
|
||||
set_error(WriteError::NonConformingColumnCount);
|
||||
}
|
||||
|
||||
write_row(row);
|
||||
if (m_output.write({ "\n", 1 }) != 1)
|
||||
set_error(WriteError::InternalError);
|
||||
++lines_written;
|
||||
|
||||
if (lines_written >= max_preview_lines)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void set_error(WriteError error)
|
||||
{
|
||||
if (m_error == WriteError::None)
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void write_row(T&& row)
|
||||
{
|
||||
|
@ -180,7 +207,7 @@ private:
|
|||
}
|
||||
|
||||
ContainerType const& m_data;
|
||||
WriterTraits const& m_traits;
|
||||
WriterTraits m_traits;
|
||||
WriterBehavior m_behaviors;
|
||||
HeaderType const& m_names;
|
||||
WriteError m_error { WriteError::None };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue