//---------------------------------------------------------------------------// // 1100101 |_ mov #0, r4 __ // // 11 |_ <0xb380 %5c4> / _|_ _____ ___ // // 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< // // |_ base# + offset |_| /_\_\___/__/ // //---------------------------------------------------------------------------// #include #include #include #include #include #include #include #include namespace fs = std::filesystem; Buffer::Buffer(): size {0}, data {nullptr}, path {"(none)"} { } /* Empty buffer initialized with given byte */ Buffer::Buffer(size_t bufsize, int fill) { this->size = bufsize; this->data = std::make_unique(bufsize); memset(this->data.get(), fill, bufsize); this->path = "(anonymous)"; } /* Buffer initialized from file */ void Buffer::loadFromFile( std::string const &filepath, ssize_t bufsize, 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; if(fstat(fd, &statbuf) < 0) { close(fd); throw std::runtime_error(format("cannot stat '%s'", path)); } this->size = (bufsize < 0) ? statbuf.st_size : bufsize; size_t size_to_read = std::min(size, (size_t)statbuf.st_size); /* Read buffer and fill whatever is left */ this->data = std::make_unique(this->size); memset(this->data.get(), fill, this->size); ssize_t x = read(fd, this->data.get(), size_to_read); close(fd); if(x != (ssize_t)size_to_read) throw std::runtime_error(format("error while reading '%s'", path)); this->path = filepath; } /* Buffer initialized from file */ Buffer::Buffer(std::string const &filepath, ssize_t bufsize, int fill): Buffer() { this->loadFromFile(filepath, bufsize, fill); } Buffer::Buffer(std::string filepath, std::vector const &folders, ssize_t size, int fill): Buffer() { for(auto const &f: folders) { fs::path p = fs::path(f) / fs::path(filepath); if(fs::exists(p)) { this->loadFromFile(p, size, fill); return; } } char const *path = filepath.c_str(); throw std::runtime_error(format("cannot find '%s' in library", path)); } /* 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(this->data.get(), other.data.get(), std::min(new_size, other.size)); this->path = other.path; }