replace FileReader with File class; prepare for removing FileLoader
This commit is contained in:
parent
5a8894498b
commit
e562f77dab
@ -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;
|
||||||
|
@ -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
91
src/core/File.cc
Normal 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
21
src/core/File.h
Normal 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
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user