118 lines
2.8 KiB
C++
118 lines
2.8 KiB
C++
#include "Buffer.h"
|
|
#include <stdio.h>
|
|
#include "System.h"
|
|
#include "File.h"
|
|
#include "TextLoader.h"
|
|
#include <cassert>
|
|
|
|
Buffer::Buffer()
|
|
{
|
|
piece_table = std::make_shared<PieceTable>();
|
|
m_file_buffer = nullptr;
|
|
m_file_buffer_size = 0u;
|
|
m_eol_at_eof = true;
|
|
m_line_endings = LineEndings::LF;
|
|
m_encoding = Encoding::UTF_8;
|
|
piece_table->encoding = m_encoding;
|
|
}
|
|
|
|
Buffer::~Buffer()
|
|
{
|
|
if (m_file_buffer != nullptr)
|
|
{
|
|
free_file_buffer();
|
|
}
|
|
}
|
|
|
|
bool Buffer::load_from_file(const char * filename)
|
|
{
|
|
File file;
|
|
if (!file.open(filename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
size_t file_size = file.get_size();
|
|
if (file_size < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_file_buffer_size = ((unsigned long)file_size + System::page_size) & System::page_base_mask;
|
|
m_file_buffer = (uint8_t *)System::alloc_pages(m_file_buffer_size >> System::page_size_log);
|
|
if (m_file_buffer == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!file.read(m_file_buffer, file_size))
|
|
{
|
|
free_file_buffer();
|
|
return false;
|
|
}
|
|
|
|
TextLoader text_loader;
|
|
text_loader.load_buffer(m_file_buffer, file_size);
|
|
|
|
piece_table = std::make_shared<PieceTable>();
|
|
for (auto it = text_loader.begin(); it != text_loader.end(); it++)
|
|
{
|
|
auto next = it;
|
|
next++;
|
|
bool eol = next != text_loader.end();
|
|
it->start[it->length] = PieceTable::INTERNAL_EOL;
|
|
piece_table->append_initial_line_piece(it->start, it->length + 1u, eol);
|
|
}
|
|
|
|
m_eol_at_eof = text_loader.get_eol_at_eof();
|
|
m_line_endings = text_loader.get_line_endings();
|
|
m_encoding = text_loader.get_encoding();
|
|
piece_table->encoding = m_encoding;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Buffer::write_to_file(const char * filename)
|
|
{
|
|
File file;
|
|
if (!file.open(filename, true))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
uint32_t bytes_written = 0u;
|
|
for (auto piece = piece_table->start_piece->next;
|
|
piece != piece_table->end_piece;
|
|
piece = piece->next)
|
|
{
|
|
uint32_t length = piece->length;
|
|
if (piece->eol())
|
|
{
|
|
length--;
|
|
}
|
|
if (!file.write(piece->start, length))
|
|
{
|
|
return false;
|
|
}
|
|
bytes_written += length;
|
|
if (((piece->next != piece_table->end_piece) && piece->eol()) ||
|
|
(m_eol_at_eof && bytes_written > 0u))
|
|
{
|
|
if (!file.write(LineEndings::spans[m_line_endings]))
|
|
{
|
|
return false;
|
|
}
|
|
bytes_written += LineEndings::spans[m_line_endings].length;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Buffer::free_file_buffer()
|
|
{
|
|
System::free_pages(m_file_buffer, m_file_buffer_size >> System::page_size_log);
|
|
m_file_buffer = nullptr;
|
|
m_file_buffer_size = 0u;
|
|
}
|