/* */ #include "AbstractDiskWriter.h" #include "DlAbortEx.h" #include "File.h" #include "Util.h" #include "message.h" #include "LogFactory.h" #include "a2io.h" #include #include #include #include #include AbstractDiskWriter::AbstractDiskWriter(): fd(-1), fileAllocator(0), glowFileAllocator(0), logger(LogFactory::getInstance()) {} AbstractDiskWriter::~AbstractDiskWriter() { closeFile(); } void AbstractDiskWriter::openFile(const string& filename, int64_t totalLength) { File f(filename); if(f.exists()) { openExistingFile(filename); } else { initAndOpenFile(filename, totalLength); } } void AbstractDiskWriter::closeFile() { if(fd >= 0) { close(fd); fd = -1; } } void AbstractDiskWriter::openExistingFile(const string& filename, int64_t totalLength) { this->filename = filename; File f(filename); if(!f.isFile()) { throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), MSG_FILE_NOT_FOUND); } if((fd = open(filename.c_str(), O_RDWR|O_BINARY, OPEN_MODE)) < 0) { throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno)); } if(f.size() < totalLength) { if(!fileAllocator.isNull()) { logger->notice(MSG_ALLOCATING_FILE, filename.c_str(), Util::ullitos(totalLength).c_str()); glowFileAllocator->allocate(fd, totalLength); } } } void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags) { this->filename = filename; // TODO proper filename handling needed assert(filename.size()); // if(filename.empty()) { // filename = "index.html"; // } if((fd = open(filename.c_str(), O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags, OPEN_MODE)) < 0) { throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno)); } } int32_t AbstractDiskWriter::writeDataInternal(const char* data, int32_t len) { return write(fd, data, len); } int32_t AbstractDiskWriter::readDataInternal(char* data, int32_t len) { return read(fd, data, len); } void AbstractDiskWriter::seek(int64_t offset) { if(offset != lseek(fd, offset, SEEK_SET)) { throw new DlAbortEx(EX_FILE_SEEK, filename.c_str(), strerror(errno)); } } void AbstractDiskWriter::writeData(const char* data, int32_t len, int64_t offset) { seek(offset); if(writeDataInternal(data, len) < 0) { throw new DlAbortEx(EX_FILE_WRITE, filename.c_str(), strerror(errno)); } } int32_t AbstractDiskWriter::readData(char* data, int32_t len, int64_t offset) { int32_t ret; seek(offset); if((ret = readDataInternal(data, len)) < 0) { throw new DlAbortEx(EX_FILE_READ, filename.c_str(), strerror(errno)); } return ret; } void AbstractDiskWriter::truncate(int64_t length) { ftruncate(fd, length); } // TODO the file descriptor fd must be opened before calling this function. int64_t AbstractDiskWriter::size() const { struct stat fileStat; if(fstat(fd, &fileStat) < 0) { return 0; } return fileStat.st_size; }