1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 17:37:34 +00:00

HexEditor: Stream input files instead of keeping them in memory

To support editing of large files it is an advantage to not load the
entire file into memory but only load whatever is needed for display at
the moment. To make it work, file access is abstracted into a socalled
HexDocument, of which there two: a memory based and a file based one.
The former can be used for newly created documents, the latter for file
based editing.

Hex documents now do track changes instead of the HexEditor. HexEditor
only sets new values. This frees HexEditor of some responsibility.
This commit is contained in:
Arne Elster 2021-11-10 01:37:10 +01:00 committed by Brian Gianforcaro
parent 60c3ad9ae8
commit fd66dda1d7
7 changed files with 362 additions and 117 deletions

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, Arne Elster <arne@elster.li>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/StringView.h>
#include <AK/Types.h>
#include <LibCore/File.h>
class HexDocument {
public:
enum class Type {
Memory,
File
};
struct Cell {
u8 value;
bool modified;
};
virtual ~HexDocument() = default;
virtual Cell get(size_t position) = 0;
virtual void set(size_t position, u8 value);
virtual size_t size() const = 0;
virtual Type type() const = 0;
virtual bool is_dirty() const;
virtual void clear_changes() = 0;
protected:
HashMap<size_t, u8> m_changes;
};
class HexDocumentMemory : public HexDocument {
public:
explicit HexDocumentMemory(ByteBuffer&& buffer);
virtual ~HexDocumentMemory() = default;
Cell get(size_t position) override;
size_t size() const override;
Type type() const override;
void clear_changes() override;
bool write_to_file(NonnullRefPtr<Core::File> file);
private:
ByteBuffer m_buffer;
};
class HexDocumentFile : public HexDocument {
public:
explicit HexDocumentFile(NonnullRefPtr<Core::File> file);
virtual ~HexDocumentFile() = default;
HexDocumentFile(const HexDocumentFile&) = delete;
void set_file(NonnullRefPtr<Core::File> file);
NonnullRefPtr<Core::File> file() const;
void write_to_file();
bool write_to_file(NonnullRefPtr<Core::File> file);
Cell get(size_t position) override;
size_t size() const override;
Type type() const override;
void clear_changes() override;
private:
NonnullRefPtr<Core::File> m_file;
size_t m_file_size;
Array<u8, 2048> m_buffer;
size_t m_buffer_file_pos;
};