replace FileReader with File class; prepare for removing FileLoader

This commit is contained in:
Josh Holtrop 2016-07-14 18:44:18 -04:00
parent 5a8894498b
commit e562f77dab
9 changed files with 153 additions and 133 deletions

View File

@ -1,15 +1,43 @@
#include "Buffer.h" #include "Buffer.h"
#include <stdio.h>
#include "System.h"
#include "File.h"
#include "FileLoader.h"
bool Buffer::load_from_file(const char * filename) bool Buffer::load_from_file(const char * filename)
{ {
if (!m_fl.load(filename)) File file;
if (!file.open(filename))
{ {
return false; return false;
} }
for (size_t i = 0, num_lines = m_fl.num_lines(); i < num_lines; i++) size_t file_size = file.get_size();
if (file_size < 0)
{ {
m_lines.push_back(m_fl.get_line(i)); return false;
}
unsigned long file_buffer_size = ((unsigned long)file_size + System::page_size - 1u) & System::page_base_mask;
uint8_t * file_buffer = (uint8_t *)System::alloc_pages(file_buffer_size >> System::page_size_log);
if (file_buffer == NULL)
{
return false;
}
if (!file.read(file_buffer, file_size))
{
System::free_pages(file_buffer, file_buffer_size >> System::page_size_log);
return false;
}
/* TODO: record file_buffer for freeing */
/* TODO: remove FileLoader */
FileLoader fl;
fl.load_buf(file_buffer, file_size);
for (size_t i = 0, num_lines = fl.num_lines(); i < num_lines; i++)
{
m_lines.push_back(fl.get_line(i));
} }
return true; return true;

View File

@ -4,7 +4,6 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include "Text.h" #include "Text.h"
#include "FileLoader.h"
class Buffer class Buffer
{ {
@ -27,8 +26,6 @@ public:
protected: protected:
LinesType m_lines; LinesType m_lines;
/* TODO: delete this */
FileLoader m_fl;
}; };
#endif #endif

91
src/core/File.cc Normal file
View File

@ -0,0 +1,91 @@
#include "File.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef _WIN32
#define JES_O_BINARY O_BINARY
#else
#define JES_O_BINARY 0
#endif
/**
* Open a file.
*
* @param[in] filename The filename.
* @param[in] writing Whether to open for writing.
*/
bool File::open(const char * filename, bool writing)
{
int flags = (writing ? 0 : O_RDONLY) | JES_O_BINARY;
int fd = ::open(filename, flags);
if (fd < 0)
{
return false;
}
m_fd = fd;
return true;
}
/**
* Close the file.
*/
void File::close()
{
if (m_fd >= 0)
{
::close(m_fd);
m_fd = -1;
}
}
/**
* Get the file's size.
*
* This function will reset the file position to the beginning of the file.
*
* @return The file's size, or -1 on error.
*/
size_t File::get_size()
{
if (m_fd >= 0)
{
off_t o = lseek(m_fd, 0, SEEK_END);
lseek(m_fd, 0, SEEK_SET);
return o;
}
return -1;
}
/**
* Read from the file.
*
* @param[in] buf Memory buffer to read into. Must be large enough to hold
* size bytes.
* @param[in] size Number of bytes to read.
*
* @retval false The file failed to read.
* @retval true The file was read successfully.
*/
bool File::read(uint8_t * buf, size_t size)
{
off_t n_bytes_read = 0u;
for (;;)
{
off_t rd_size = ::read(m_fd, &buf[n_bytes_read], size - n_bytes_read);
if (rd_size <= 0)
break;
n_bytes_read += rd_size;
if (n_bytes_read >= size)
break;
}
if (n_bytes_read != size)
{
return false;
}
return true;
}

21
src/core/File.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef FILE_H
#define FILE_H
#include <stdint.h>
#include <stdlib.h>
class File
{
public:
File() : m_fd(-1) {}
~File() { close(); }
bool open(const char * filename, bool writing = false);
void close();
size_t get_size();
bool read(uint8_t * buf, size_t size);
protected:
int m_fd;
};
#endif

View File

@ -1,43 +1,14 @@
#include "FileLoader.h" #include "FileLoader.h"
#include "FileReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h> #include <stdint.h>
/** Create a FileLoader. */ /** Create a FileLoader. */
FileLoader::FileLoader() FileLoader::FileLoader()
{ {
m_buf = NULL;
m_line_endings = LINE_ENDING_LF; m_line_endings = LINE_ENDING_LF;
m_lines = NULL; m_lines = NULL;
} }
FileLoader::~FileLoader() void FileLoader::load_buf(uint8_t * buf, size_t size)
{
if (m_buf != NULL)
{
delete[] m_buf;
m_buf = NULL;
}
}
bool FileLoader::load(const char * fname)
{
size_t size;
if (!FileReader::read(fname, &m_buf, &size))
{
return false;
}
load_buf(size);
return true;
}
void FileLoader::load_buf(size_t size)
{ {
LineIndexPairVectorRef lines[LINE_ENDING_COUNT]; LineIndexPairVectorRef lines[LINE_ENDING_COUNT];
size_t line_start[LINE_ENDING_COUNT] = {0}; size_t line_start[LINE_ENDING_COUNT] = {0};
@ -50,16 +21,16 @@ void FileLoader::load_buf(size_t size)
} }
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
{ {
if (m_buf[i] == '\r') if (buf[i] == '\r')
{ {
lines[LINE_ENDING_CR]->push_back(LineIndexPair(&m_buf[line_start[LINE_ENDING_CR]], i - line_start[LINE_ENDING_CR])); lines[LINE_ENDING_CR]->push_back(LineIndexPair(&buf[line_start[LINE_ENDING_CR]], i - line_start[LINE_ENDING_CR]));
n_cr++; n_cr++;
line_start[LINE_ENDING_CR] = i + 1; line_start[LINE_ENDING_CR] = i + 1;
if (crlf) if (crlf)
{ {
if ((i < (size - 1)) && (m_buf[i + 1] == '\n')) if ((i < (size - 1)) && (buf[i + 1] == '\n'))
{ {
lines[LINE_ENDING_CRLF]->push_back(LineIndexPair(&m_buf[line_start[LINE_ENDING_CRLF]], i - line_start[LINE_ENDING_CRLF])); lines[LINE_ENDING_CRLF]->push_back(LineIndexPair(&buf[line_start[LINE_ENDING_CRLF]], i - line_start[LINE_ENDING_CRLF]));
n_lf++; n_lf++;
i++; i++;
line_start[LINE_ENDING_CRLF] = i + 1; line_start[LINE_ENDING_CRLF] = i + 1;
@ -70,9 +41,9 @@ void FileLoader::load_buf(size_t size)
} }
} }
} }
else if (m_buf[i] == '\n') else if (buf[i] == '\n')
{ {
lines[LINE_ENDING_LF]->push_back(LineIndexPair(&m_buf[line_start[LINE_ENDING_LF]], i - line_start[LINE_ENDING_LF])); lines[LINE_ENDING_LF]->push_back(LineIndexPair(&buf[line_start[LINE_ENDING_LF]], i - line_start[LINE_ENDING_LF]));
crlf = false; crlf = false;
n_lf++; n_lf++;
line_start[LINE_ENDING_LF] = i + 1; line_start[LINE_ENDING_LF] = i + 1;

View File

@ -18,8 +18,7 @@ public:
}; };
FileLoader(); FileLoader();
~FileLoader(); void load_buf(uint8_t * buf, size_t size);
bool load(const char * fname);
size_t num_lines() size_t num_lines()
{ {
if (m_lines == NULL) if (m_lines == NULL)
@ -37,8 +36,6 @@ protected:
typedef std::pair<const uint8_t *, size_t> LineIndexPair; typedef std::pair<const uint8_t *, size_t> LineIndexPair;
typedef std::vector<LineIndexPair> LineIndexPairVector; typedef std::vector<LineIndexPair> LineIndexPairVector;
typedef std::shared_ptr<LineIndexPairVector> LineIndexPairVectorRef; typedef std::shared_ptr<LineIndexPairVector> LineIndexPairVectorRef;
void load_buf(size_t size);
uint8_t * m_buf;
int m_line_endings; int m_line_endings;
LineIndexPairVectorRef m_lines; LineIndexPairVectorRef m_lines;
}; };

View File

@ -1,74 +0,0 @@
#include "FileReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef _WIN32
#define JES_O_BINARY O_BINARY
#else
#define JES_O_BINARY 0
#endif
/**
* Load a file into memory.
*
* @param[in] fname File name.
* @param[out] buf Pointer to memory buffer containing file. Must be freed by
* caller with delete[].
* @param[out] size Set to length of the file. If the return value is true
* and *size is 0, then no buffer was allocated and *buf should not be used.
*
* @retval false The file failed to read. In this case the output parameter
* values *buf and *size should not be used.
* @retval true The file was read successfully.
*/
bool FileReader::read(const char * fname, uint8_t ** buf, size_t * size)
{
struct stat st;
if (stat(fname, &st) != 0)
{
return false;
}
if (st.st_size < 0)
{
return false;
}
*size = st.st_size;
if (st.st_size == 0)
{
return true;
}
int fd = open(fname, O_RDONLY | JES_O_BINARY);
if (fd < 0)
{
return false;
}
*buf = new uint8_t[st.st_size];
off_t n_bytes_read = 0u;
for (;;)
{
off_t rd_size = ::read(fd, &(*buf)[n_bytes_read], st.st_size - n_bytes_read);
if (rd_size <= 0)
break;
n_bytes_read += rd_size;
if (n_bytes_read >= st.st_size)
break;
}
if (n_bytes_read != st.st_size)
{
delete[] *buf;
*buf = NULL;
close(fd);
return false;
}
close(fd);
return true;
}

View File

@ -1,13 +0,0 @@
#ifndef JES_FILEREADER_H
#define JES_FILEREADER_H
#include <stdint.h>
#include <stdlib.h>
class FileReader
{
public:
static bool read(const char * fname, uint8_t ** buf, size_t * size);
};
#endif

View File

@ -7,6 +7,7 @@ TEST(FileLoaderTest, num_lines_defaults_to_0)
EXPECT_EQ(0u, fr.num_lines()); EXPECT_EQ(0u, fr.num_lines());
} }
#if 0
TEST(FileLoaderTest, load_returns_false_for_nonexistent_file) TEST(FileLoaderTest, load_returns_false_for_nonexistent_file)
{ {
FileLoader fr; FileLoader fr;
@ -49,3 +50,4 @@ TEST(FileLoaderTest, reads_crlf_format_file)
// EXPECT_EQ("Hello.", fr.get_line(0)->to_s()); // EXPECT_EQ("Hello.", fr.get_line(0)->to_s());
// EXPECT_EQ("This file is in DOS line ending format.", fr.get_line(1)->to_s()); // EXPECT_EQ("This file is in DOS line ending format.", fr.get_line(1)->to_s());
} }
#endif