103 lines
3.4 KiB
C++
103 lines
3.4 KiB
C++
#include "FileJsObject.hpp"
|
|
|
|
#include <QJSValue>
|
|
#include <QTextStream>
|
|
|
|
#include "exception/FileNotFoundException.hpp"
|
|
#include "javascript/engine/AtlasJsEngine.hpp"
|
|
#include "utils/qt/fileOpenMode.hpp"
|
|
|
|
|
|
FileJsObject::FileJsObject(AtlasJsEngine* engine, const std::filesystem::path& virtualPath) {
|
|
// save the engine
|
|
this->engine = engine;
|
|
|
|
// create the internal QFile
|
|
std::filesystem::path realPath;
|
|
try {
|
|
realPath = this->engine->getFileSystem().resolve(virtualPath);
|
|
} catch (const vfs::exception::FileNotFoundException& exception) {
|
|
this->engine->throwError(QJSValue::ErrorType::URIError, "Invalid path.");
|
|
return;
|
|
}
|
|
|
|
// allocate the internal file
|
|
this->_internal = std::make_unique<QFile>(realPath);
|
|
}
|
|
|
|
void FileJsObject::open(const QString& mode) {
|
|
// get the mode flags from its string representation
|
|
this->mode = fileModeFromString(mode);
|
|
|
|
// open the file with the corresponding mode
|
|
if (!this->_internal->open(this->mode)) {
|
|
this->engine->throwError(QJSValue::URIError, "Cannot open the file.");
|
|
return;
|
|
}
|
|
|
|
// if we are in text mode, prepare the QTextStream wrapper
|
|
if (this->mode.testFlag(QIODevice::Text))
|
|
this->textStream = std::make_unique<QTextStream>(this->_internal.get());
|
|
}
|
|
|
|
QJSValue FileJsObject::read(const std::size_t size) const {
|
|
// check if we can read the file
|
|
if (!this->mode.testFlag(QIODevice::ReadOnly)) {
|
|
this->engine->throwError(QJSValue::ErrorType::TypeError, "The file is not open in read mode.");
|
|
return QJSValue(QJSPrimitiveNull());
|
|
}
|
|
|
|
// if we are in text mode, read from the text stream
|
|
if (this->mode.testFlag(QIODevice::Text))
|
|
return this->textStream->read(static_cast<qint64>(size));
|
|
|
|
// if we are in binary mode, read from the binary stream
|
|
const auto data = this->_internal->read(static_cast<qint64>(size));
|
|
return this->engine->toScriptValue(data);
|
|
}
|
|
|
|
std::size_t FileJsObject::write(const QJSValue& data) const {
|
|
// check if we can write into the file
|
|
if (!this->mode.testFlag(QIODevice::WriteOnly)) {
|
|
this->engine->throwError(QJSValue::ErrorType::TypeError, "The file is not open in write mode.");
|
|
return 0;
|
|
}
|
|
|
|
const QString dataString = data.toString();
|
|
|
|
// if we are in text mode, write text data
|
|
if (this->mode.testFlag(QIODevice::Text)) {
|
|
*this->textStream << dataString;
|
|
return dataString.size();
|
|
}
|
|
|
|
const QByteArray dataByte = dataString.toUtf8();
|
|
// if we are in binary mode, insert the raw binary data
|
|
return this->_internal->write(dataByte);
|
|
}
|
|
|
|
std::size_t FileJsObject::tell() const {
|
|
// if we are in text mode, return the position of the text stream
|
|
if (this->mode.testFlag(QIODevice::Text))
|
|
return this->textStream->pos();
|
|
|
|
// if we are in binary mode, return the position of the raw binary stream
|
|
return this->_internal->pos();
|
|
}
|
|
|
|
void FileJsObject::seek(const std::size_t position) const {
|
|
// if we are in text mode, set the position of the text stream
|
|
if (this->mode.testFlag(QIODevice::Text)) {
|
|
this->textStream->seek(static_cast<qint64>(position));
|
|
return;
|
|
}
|
|
|
|
// if we are in binary mode, set the position of the raw binary stream
|
|
this->_internal->seek(static_cast<qint64>(position));
|
|
}
|
|
|
|
void FileJsObject::close() const {
|
|
// if still opened, close the file
|
|
if (this->_internal->isOpen())
|
|
this->_internal->close();
|
|
}
|