98 lines
1.9 KiB
C++
98 lines
1.9 KiB
C++
#include <fxos/util.h>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
/* Empty buffer initialized with given byte */
|
|
Buffer::Buffer(size_t size, int fill)
|
|
{
|
|
m_data = malloc(size);
|
|
if(!m_data) throw std::bad_alloc();
|
|
|
|
m_size = size;
|
|
memset(m_data, fill, size);
|
|
|
|
m_path = "(anonymous)";
|
|
}
|
|
|
|
/* Buffer initialized from file */
|
|
Buffer::Buffer(std::string filepath, ssize_t size, int fill)
|
|
{
|
|
char const *path = filepath.c_str();
|
|
|
|
int fd = open(path, O_RDONLY);
|
|
if(!fd) throw std::runtime_error(format("cannot open '%s'", path));
|
|
|
|
struct stat statbuf;
|
|
ssize_t x = fstat(fd, &statbuf);
|
|
|
|
if(x < 0)
|
|
{
|
|
close(fd);
|
|
throw std::runtime_error(format("cannot stat '%s'", path));
|
|
}
|
|
|
|
m_size = (size < 0) ? statbuf.st_size : size;
|
|
size_t size_to_read = std::min(m_size, (size_t)statbuf.st_size);
|
|
|
|
m_data = malloc(m_size);
|
|
if(!m_data) throw std::bad_alloc();
|
|
|
|
/* Read buffer and fill whatever is left */
|
|
memset(m_data, fill, m_size);
|
|
x = read(fd, m_data, size_to_read);
|
|
|
|
close(fd);
|
|
if(x != (ssize_t)size_to_read)
|
|
{
|
|
throw std::runtime_error(format(
|
|
"error while reading '%s'", path));
|
|
}
|
|
|
|
m_path = filepath;
|
|
}
|
|
|
|
/* Create a buffer by copying another buffer */
|
|
Buffer::Buffer(Buffer const &other):
|
|
Buffer(other.size(), 0x00)
|
|
{
|
|
}
|
|
|
|
/* Create a buffer by copying and resizing another buffer */
|
|
Buffer::Buffer(Buffer const &other, size_t new_size, int fill):
|
|
Buffer(new_size, fill)
|
|
{
|
|
memcpy(m_data, other.data(), std::min(new_size, other.size()));
|
|
}
|
|
|
|
/* Free allocated data, obviously */
|
|
Buffer::~Buffer()
|
|
{
|
|
free(m_data);
|
|
}
|
|
|
|
/* Buffer size */
|
|
size_t Buffer::size() const noexcept
|
|
{
|
|
return m_size;
|
|
}
|
|
|
|
/* Buffer data */
|
|
char *Buffer::data() noexcept
|
|
{
|
|
return static_cast<char *>(m_data);
|
|
}
|
|
char const *Buffer::data() const noexcept
|
|
{
|
|
return static_cast<char const *>(m_data);
|
|
}
|
|
|
|
/* File path */
|
|
std::string Buffer::path() const noexcept
|
|
{
|
|
return m_path;
|
|
}
|