#include #include #include #include #include #include /* 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(m_data); } char const *Buffer::data() const noexcept { return static_cast(m_data); } /* File path */ std::string Buffer::path() const noexcept { return m_path; }