diff --git a/src/core/Buffer.cc b/src/core/Buffer.cc index 1d493fc..9e70d9a 100644 --- a/src/core/Buffer.cc +++ b/src/core/Buffer.cc @@ -11,7 +11,7 @@ Buffer::Buffer() m_file_buffer = nullptr; m_file_buffer_size = 0u; m_eol_at_eof = true; - m_line_endings = TextLoader::LINE_ENDING_LF; + m_line_endings = LineEndings::LF; } Buffer::~Buffer() @@ -71,26 +71,6 @@ bool Buffer::load_from_file(const char * filename) bool Buffer::write_to_file(const char * filename) { File file; - const char * eol_seq; - size_t eol_len; - switch (m_line_endings) - { - case TextLoader::LINE_ENDING_LF: - eol_seq = "\n"; - eol_len = 1u; - break; - case TextLoader::LINE_ENDING_CR: - eol_seq = "\r"; - eol_len = 1u; - break; - case TextLoader::LINE_ENDING_CRLF: - eol_seq = "\r\n"; - eol_len = 2u; - break; - default: - assert(false); - break; - } if (!file.open(filename, true)) { return false; @@ -108,17 +88,19 @@ bool Buffer::write_to_file(const char * filename) bytes_written += pd->length; if (pd->eol()) { - if (!file.write((const uint8_t *)eol_seq, eol_len)) + if (!file.write(LineEndings::spans[m_line_endings].start, + LineEndings::spans[m_line_endings].length)) { return false; } - bytes_written += eol_len; + bytes_written += LineEndings::spans[m_line_endings].length; } } if (m_eol_at_eof && bytes_written > 0u) { - if (!file.write((const uint8_t *)eol_seq, eol_len)) + if (!file.write(LineEndings::spans[m_line_endings].start, + LineEndings::spans[m_line_endings].length)) { return false; } diff --git a/src/core/Buffer.h b/src/core/Buffer.h index 982a8be..80b1490 100644 --- a/src/core/Buffer.h +++ b/src/core/Buffer.h @@ -4,6 +4,7 @@ #include #include #include "PieceTable.h" +#include "LineEndings.h" class Buffer { @@ -19,7 +20,7 @@ protected: uint8_t * m_file_buffer; unsigned long m_file_buffer_size; bool m_eol_at_eof; - uint8_t m_line_endings; + LineEndings::Type m_line_endings; void free_file_buffer(); }; diff --git a/src/core/LineEndings.cc b/src/core/LineEndings.cc new file mode 100644 index 0000000..89fe720 --- /dev/null +++ b/src/core/LineEndings.cc @@ -0,0 +1,11 @@ +#include "LineEndings.h" + +static uint8_t lf[] = "\n"; +static uint8_t crlf[] = "\r\n"; +static uint8_t cr[] = "\r"; + +const Span LineEndings::spans[] = { + Span(lf, 1u), + Span(crlf, 2u), + Span(cr, 1u), +}; diff --git a/src/core/LineEndings.h b/src/core/LineEndings.h new file mode 100644 index 0000000..95de16f --- /dev/null +++ b/src/core/LineEndings.h @@ -0,0 +1,20 @@ +#ifndef LINEENDINGS_H +#define LINEENDINGS_H + +#include "Span.h" + +class LineEndings +{ +public: + enum Type + { + LF, + CRLF, + CR, + COUNT, + }; + + static const Span spans[COUNT]; +}; + +#endif diff --git a/src/core/TextLoader.cc b/src/core/TextLoader.cc index 25934ce..c638f2a 100644 --- a/src/core/TextLoader.cc +++ b/src/core/TextLoader.cc @@ -4,7 +4,7 @@ /** Create a TextLoader. */ TextLoader::TextLoader() { - m_line_endings = LINE_ENDING_LF; + m_line_endings = LineEndings::LF; m_lines = NULL; m_eol_at_eof = true; } @@ -17,12 +17,12 @@ TextLoader::TextLoader() */ void TextLoader::load_buffer(uint8_t * buffer, size_t size) { - std::shared_ptr> lines[LINE_ENDING_COUNT]; - size_t line_start[LINE_ENDING_COUNT] = {0}; + std::shared_ptr> lines[LineEndings::COUNT]; + size_t line_start[LineEndings::COUNT] = {0}; unsigned int n_cr = 0; unsigned int n_lf = 0; bool crlf = true; - for (size_t i = 0; i < LINE_ENDING_COUNT; i++) + for (size_t i = 0; i < LineEndings::COUNT; i++) { lines[i] = std::make_shared>(); } @@ -30,17 +30,17 @@ void TextLoader::load_buffer(uint8_t * buffer, size_t size) { if (buffer[i] == '\r') { - lines[LINE_ENDING_CR]->push_back(Span(&buffer[line_start[LINE_ENDING_CR]], i - line_start[LINE_ENDING_CR])); + lines[LineEndings::CR]->push_back(Span(&buffer[line_start[LineEndings::CR]], i - line_start[LineEndings::CR])); n_cr++; - line_start[LINE_ENDING_CR] = i + 1; + line_start[LineEndings::CR] = i + 1; if (crlf) { if ((i < (size - 1)) && (buffer[i + 1] == '\n')) { - lines[LINE_ENDING_CRLF]->push_back(Span(&buffer[line_start[LINE_ENDING_CRLF]], i - line_start[LINE_ENDING_CRLF])); + lines[LineEndings::CRLF]->push_back(Span(&buffer[line_start[LineEndings::CRLF]], i - line_start[LineEndings::CRLF])); n_lf++; i++; - line_start[LINE_ENDING_CRLF] = i + 1; + line_start[LineEndings::CRLF] = i + 1; } else { @@ -50,24 +50,24 @@ void TextLoader::load_buffer(uint8_t * buffer, size_t size) } else if (buffer[i] == '\n') { - lines[LINE_ENDING_LF]->push_back(Span(&buffer[line_start[LINE_ENDING_LF]], i - line_start[LINE_ENDING_LF])); + lines[LineEndings::LF]->push_back(Span(&buffer[line_start[LineEndings::LF]], i - line_start[LineEndings::LF])); crlf = false; n_lf++; - line_start[LINE_ENDING_LF] = i + 1; + line_start[LineEndings::LF] = i + 1; } } if (crlf && (n_lf > 0u)) { - m_line_endings = LINE_ENDING_CRLF; + m_line_endings = LineEndings::CRLF; } else if ((n_cr > 0u) && (n_lf == 0u)) { - m_line_endings = LINE_ENDING_CR; + m_line_endings = LineEndings::CR; } else { - m_line_endings = LINE_ENDING_LF; + m_line_endings = LineEndings::LF; } m_lines = lines[m_line_endings]; diff --git a/src/core/TextLoader.h b/src/core/TextLoader.h index 241623b..899ff53 100644 --- a/src/core/TextLoader.h +++ b/src/core/TextLoader.h @@ -5,18 +5,11 @@ #include #include #include "Span.h" +#include "LineEndings.h" class TextLoader { public: - enum - { - LINE_ENDING_LF, - LINE_ENDING_CR, - LINE_ENDING_CRLF, - LINE_ENDING_COUNT - }; - TextLoader(); void load_buffer(uint8_t * buffer, size_t size); size_t num_lines() @@ -30,13 +23,13 @@ public: return m_lines->size(); } } - int get_line_endings() { return m_line_endings; } + LineEndings::Type get_line_endings() { return m_line_endings; } auto begin() { return m_lines->begin(); } auto end() { return m_lines->end(); } bool get_eol_at_eof() { return m_eol_at_eof; } protected: - int m_line_endings; + LineEndings::Type m_line_endings; bool m_eol_at_eof; std::shared_ptr> m_lines; }; diff --git a/test/src/test_TextLoader.cc b/test/src/test_TextLoader.cc index 20d1bec..bd5ade9 100644 --- a/test/src/test_TextLoader.cc +++ b/test/src/test_TextLoader.cc @@ -31,7 +31,7 @@ TEST(TextLoaderTest, detects_lf_line_endings) TextLoader tl; auto file = TestSupport::read_file("test/files/line_endings/lf_format.txt"); tl.load_buffer(&(*file)[0], file->size()); - EXPECT_EQ(TextLoader::LINE_ENDING_LF, tl.get_line_endings()); + EXPECT_EQ(LineEndings::LF, tl.get_line_endings()); ASSERT_EQ(2u, tl.num_lines()); auto it = tl.begin(); EXPECT_EQ("Hello.", line_to_string(it)); @@ -45,7 +45,7 @@ TEST(TextLoaderTest, detects_cr_line_endings) TextLoader tl; auto file = TestSupport::read_file("test/files/line_endings/cr_format.txt"); tl.load_buffer(&(*file)[0], file->size()); - EXPECT_EQ(TextLoader::LINE_ENDING_CR, tl.get_line_endings()); + EXPECT_EQ(LineEndings::CR, tl.get_line_endings()); ASSERT_EQ(2u, tl.num_lines()); auto it = tl.begin(); EXPECT_EQ("Hello.", line_to_string(it)); @@ -59,7 +59,7 @@ TEST(TextLoaderTest, detects_crlf_line_endings) TextLoader tl; auto file = TestSupport::read_file("test/files/line_endings/crlf_format.txt"); tl.load_buffer(&(*file)[0], file->size()); - EXPECT_EQ(TextLoader::LINE_ENDING_CRLF, tl.get_line_endings()); + EXPECT_EQ(LineEndings::CRLF, tl.get_line_endings()); ASSERT_EQ(2u, tl.num_lines()); auto it = tl.begin(); EXPECT_EQ("Hello.", line_to_string(it));