#include "Buffer.h" #include #include "System.h" #include "File.h" #include "TextLoader.h" #include Buffer::Buffer() { piece_table = std::make_shared(); 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(); 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; }