macdependency/MachO/internalfile.cpp

89 lines
1.9 KiB
C++

#include "internalfile.h"
#include "machoexception.h"
// use reference counting to reuse files for all used architectures
InternalFile* InternalFile::create(InternalFile* file) {
file->counter++;
return file;
}
InternalFile* InternalFile::create(const std::string& filename) {
return new InternalFile(filename);
}
void InternalFile::release() {
counter--;
if (counter < 1) {
delete this;
}
}
InternalFile::InternalFile(const std::string& filename) :
filename(filename), counter(1)
{
// open file handle
file.open(this->filename, std::ios_base::in | std::ios_base::binary);
if (file.fail()) {
std::ostringstream error;
error << "Couldn't open file '" << filename << "'.";
throw MachOException(error.str());
}
struct stat buffer;
if (stat(filename.c_str(), &buffer) >= 0) {
_fileSize = buffer.st_size;
_lastWriteTime = buffer.st_mtime;
}
}
// destructor is private since we use reference counting mechanism
InternalFile::~InternalFile() {
file.close();
}
/* returns whole filename (including path)*/
std::string InternalFile::getName() const {
// Try to canonicalize path.
char buffer[PATH_MAX];
if (realpath(filename.c_str(), buffer) == nullptr)
return filename;
return buffer;
}
/* returns filename without path */
std::string InternalFile::getTitle() const {
return filename;
}
unsigned long long InternalFile::getSize() const {
return _fileSize;
}
bool InternalFile::seek(long long int position) {
file.seekg(position, std::ios_base::beg);
if (file.fail()) {
file.clear();
return false;
}
return true;
}
std::streamsize InternalFile::read(char* buffer, std::streamsize size) {
file.read(buffer, size);
if (file.fail()) {
file.clear();
return file.gcount();
}
// TODO: handle badbit
return size;
}
long long int InternalFile::getPosition() {
return file.tellg();
}
time_t InternalFile::getLastModificationTime() const {
return _lastWriteTime;
}