mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-06 12:03:39 +00:00
721 lines
23 KiB
C++
721 lines
23 KiB
C++
#include "APIHelp.h"
|
|
#include "FileSystemAPI.h"
|
|
#include <Engine/TimeTaskSystem.h>
|
|
#include <Engine/LocalShareData.h>
|
|
#include <Engine/EngineManager.h>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <Utils/FileHelper.h>
|
|
|
|
using namespace std::filesystem;
|
|
using namespace std;
|
|
|
|
//////////////////// Class Definition ////////////////////
|
|
|
|
enum class FileOpenMode : int {
|
|
ReadMode,
|
|
WriteMode,
|
|
AppendMode
|
|
};
|
|
|
|
ClassDefine<FileClass> FileClassBuilder =
|
|
defineClass<FileClass>("File")
|
|
.constructor(&FileClass::constructor)
|
|
.instanceProperty("path", &FileClass::getPath)
|
|
.instanceProperty("absolutePath", &FileClass::getAbsolutePath)
|
|
.instanceProperty("size", &FileClass::getSize)
|
|
|
|
.instanceFunction("readSync", &FileClass::readSync)
|
|
.instanceFunction("readLineSync", &FileClass::readLineSync)
|
|
.instanceFunction("readAllSync", &FileClass::readAllSync)
|
|
.instanceFunction("writeSync", &FileClass::writeSync)
|
|
.instanceFunction("writeLineSync", &FileClass::writeLineSync)
|
|
|
|
.instanceFunction("read", &FileClass::read)
|
|
.instanceFunction("readLine", &FileClass::readLine)
|
|
.instanceFunction("readAll", &FileClass::readAll)
|
|
.instanceFunction("write", &FileClass::write)
|
|
.instanceFunction("writeLine", &FileClass::writeLine)
|
|
|
|
.instanceFunction("isEOF", &FileClass::isEOF)
|
|
.instanceFunction("seekTo", &FileClass::seekTo)
|
|
.instanceFunction("setSize", &FileClass::setSize)
|
|
.instanceFunction("close", &FileClass::close)
|
|
.instanceFunction("flush", &FileClass::flush)
|
|
.instanceFunction("errorCode", &FileClass::errorCode)
|
|
.instanceFunction("clear", &FileClass::clear)
|
|
|
|
.property("ReadMode", [] { return Number::newNumber((int)FileOpenMode::ReadMode); })
|
|
.property("WriteMode", [] { return Number::newNumber((int)FileOpenMode::WriteMode); })
|
|
.property("AppendMode", [] { return Number::newNumber((int)FileOpenMode::AppendMode); })
|
|
|
|
.function("readFrom", &FileClass::readFromStatic)
|
|
.function("writeTo", &FileClass::writeToStatic)
|
|
.function("writeLine", &FileClass::writeLineStatic)
|
|
|
|
.function("createDir", &FileClass::createDir)
|
|
.function("mkdir", &FileClass::createDir)
|
|
.function("copy", &FileClass::copy)
|
|
.function("move", &FileClass::move)
|
|
.function("rename", &FileClass::rename)
|
|
.function("delete", &FileClass::del)
|
|
.function("exists", &FileClass::exists)
|
|
.function("checkIsDir", &FileClass::checkIsDir)
|
|
.function("getFileSize", &FileClass::getFileSize)
|
|
.function("getFilesList", &FileClass::getFilesList)
|
|
|
|
// For Compatibility
|
|
.function("open", &FileClass::open)
|
|
.build();
|
|
|
|
//////////////////// Classes ////////////////////
|
|
|
|
//生成函数
|
|
FileClass::FileClass(const Local<Object>& scriptObj, std::fstream&& f, const std::string& path, bool isBinary)
|
|
: ScriptClass(scriptObj) {
|
|
this->file = std::move(f);
|
|
this->path = path;
|
|
this->isBinary = isBinary;
|
|
}
|
|
|
|
FileClass::FileClass(std::fstream&& f, const std::string& path, bool isBinary)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<FileClass>{}) {
|
|
this->file = std::move(f);
|
|
this->path = path;
|
|
this->isBinary = isBinary;
|
|
}
|
|
|
|
FileClass* FileClass::constructor(const Arguments& args) {
|
|
CHECK_ARGS_COUNT_C(args, 2);
|
|
CHECK_ARG_TYPE_C(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE_C(args[1], ValueKind::kNumber);
|
|
if (args.size() >= 3)
|
|
CHECK_ARG_TYPE_C(args[2], ValueKind::kBoolean);
|
|
|
|
try {
|
|
string path = args[0].toStr();
|
|
CreateDirs(path);
|
|
|
|
FileOpenMode fMode = (FileOpenMode)(args[1].toInt());
|
|
// Auto Create
|
|
if (fMode == FileOpenMode::ReadMode || fMode == FileOpenMode::WriteMode) {
|
|
fstream tmp(str2wstr(path), ios_base::app);
|
|
tmp.flush();
|
|
tmp.close();
|
|
}
|
|
|
|
ios_base::openmode mode = ios_base::in;
|
|
if (fMode == FileOpenMode::WriteMode) {
|
|
mode |= ios_base::out;
|
|
// mode |= ios_base::ate;
|
|
mode |= ios_base::trunc;
|
|
} else if (fMode == FileOpenMode::AppendMode) {
|
|
mode |= ios_base::app;
|
|
}
|
|
|
|
bool isBinary = false;
|
|
if (args.size() >= 3 && args[2].asBoolean().value()) {
|
|
isBinary = true;
|
|
mode |= ios_base::binary;
|
|
}
|
|
|
|
fstream fs(str2wstr(path), mode);
|
|
if (!fs.is_open()) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Open File " + path + "!\n");
|
|
return nullptr;
|
|
}
|
|
return new FileClass(args.thiz(), std::move(fs), path, isBinary);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Open File " + args[0].asString().toString() + "!\n");
|
|
return nullptr;
|
|
}
|
|
CATCH_C("Fail in OpenFile!");
|
|
}
|
|
|
|
//成员函数
|
|
Local<Value> FileClass::getPath() {
|
|
try {
|
|
return String::newString(path);
|
|
}
|
|
CATCH("Fail in getPath!");
|
|
}
|
|
|
|
Local<Value> FileClass::getAbsolutePath() {
|
|
try {
|
|
return String::newString(canonical(filesystem::path(str2wstr(path))).u8string());
|
|
}
|
|
CATCH("Fail in getAbsolutePath!");
|
|
}
|
|
|
|
Local<Value> FileClass::getSize() {
|
|
try {
|
|
size_t cur = file.tellg();
|
|
file.seekg(0, file.end);
|
|
size_t size = file.tellg();
|
|
file.seekg(cur, file.beg);
|
|
|
|
return Number::newNumber((long long)size);
|
|
}
|
|
CATCH("Fail in getPath!");
|
|
}
|
|
|
|
Local<Value> FileClass::readSync(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
int cnt = args[0].toInt();
|
|
char* buf = new char[cnt];
|
|
file.read(buf, cnt);
|
|
size_t bytes = file.gcount();
|
|
|
|
Local<Value> res = isBinary ? ByteBuffer::newByteBuffer(buf, bytes).asValue() : String::newString(string_view(buf, bytes)).asValue();
|
|
delete[] buf;
|
|
return res;
|
|
}
|
|
CATCH("Fail in readSync!");
|
|
}
|
|
|
|
Local<Value> FileClass::readLineSync(const Arguments& args) {
|
|
try {
|
|
string buf;
|
|
getline(file, buf);
|
|
return String::newString(buf);
|
|
}
|
|
CATCH("Fail in readLineSync!");
|
|
}
|
|
|
|
Local<Value> FileClass::readAllSync(const Arguments& args) {
|
|
try {
|
|
string res((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
|
return isBinary ? ByteBuffer::newByteBuffer(res.data(), res.size()).asValue() : String::newString(res).asValue();
|
|
}
|
|
CATCH("Fail in readAllSync!");
|
|
}
|
|
|
|
Local<Value> FileClass::writeSync(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
if (args[0].isString()) {
|
|
file << args[0].toStr();
|
|
} else if (args[0].isByteBuffer()) {
|
|
file.write((char*)args[0].asByteBuffer().getRawBytes(), args[0].asByteBuffer().byteLength());
|
|
} else {
|
|
LOG_WRONG_ARG_TYPE();
|
|
return Local<Value>();
|
|
}
|
|
return Boolean::newBoolean(!file.fail() && !file.bad());
|
|
}
|
|
CATCH("Fail in writeSync!");
|
|
}
|
|
|
|
Local<Value> FileClass::writeLineSync(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
file << args[0].toStr() << "\n";
|
|
return Boolean::newBoolean(!file.fail() && !file.bad());
|
|
}
|
|
CATCH("Fail in writeLineSync!");
|
|
}
|
|
|
|
Local<Value> FileClass::read(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
|
|
|
|
try {
|
|
int cnt = args[0].toInt();
|
|
script::Global<Function> callbackFunc{args[1].asFunction()};
|
|
|
|
pool.enqueue([cnt, fp{&file}, isBinary{isBinary}, lock{&lock},
|
|
callback{std::move(callbackFunc)}, engine{EngineScope::currentEngine()}]() {
|
|
if (LL::isServerStopping())
|
|
return;
|
|
if (!EngineManager::isValid(engine))
|
|
return;
|
|
|
|
char* buf = new char[cnt];
|
|
lock->lock();
|
|
fp->read(buf, cnt);
|
|
size_t bytes = fp->gcount();
|
|
lock->unlock();
|
|
|
|
EngineScope scope(engine);
|
|
try {
|
|
Local<Value> res = isBinary ? ByteBuffer::newByteBuffer(buf, bytes).asValue() : String::newString(string_view(buf, bytes)).asValue();
|
|
delete[] buf;
|
|
// dangerous
|
|
NewTimeout(callback.get(), {res}, 1);
|
|
}
|
|
CATCH_IN_CALLBACK("ReadFile")
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in read!");
|
|
}
|
|
|
|
Local<Value> FileClass::readLine(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kFunction);
|
|
|
|
try {
|
|
script::Global<Function> callbackFunc{args[0].asFunction()};
|
|
|
|
pool.enqueue([fp{&file}, lock{&lock},
|
|
callback{std::move(callbackFunc)}, engine{EngineScope::currentEngine()}]() {
|
|
if (LL::isServerStopping())
|
|
return;
|
|
if (!EngineManager::isValid(engine))
|
|
return;
|
|
|
|
string buf;
|
|
lock->lock();
|
|
getline(*fp, buf);
|
|
lock->unlock();
|
|
|
|
EngineScope scope(engine);
|
|
try {
|
|
NewTimeout(callback.get(), {String::newString(buf)}, 1);
|
|
}
|
|
CATCH_IN_CALLBACK("FileReadLine")
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in readLine!");
|
|
}
|
|
|
|
Local<Value> FileClass::readAll(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kFunction);
|
|
|
|
try {
|
|
script::Global<Function> callbackFunc{args[0].asFunction()};
|
|
|
|
pool.enqueue([fp{&file}, isBinary{isBinary}, lock{&lock},
|
|
callback{std::move(callbackFunc)}, engine{EngineScope::currentEngine()}]() {
|
|
if (LL::isServerStopping())
|
|
return;
|
|
if (!EngineManager::isValid(engine))
|
|
return;
|
|
|
|
lock->lock();
|
|
string res((std::istreambuf_iterator<char>(*fp)), std::istreambuf_iterator<char>());
|
|
lock->unlock();
|
|
|
|
EngineScope scope(engine);
|
|
try {
|
|
Local<Value> readed = isBinary ? ByteBuffer::newByteBuffer(res.data(), res.size()).asValue() : String::newString(res).asValue();
|
|
NewTimeout(callback.get(), {readed}, 1);
|
|
}
|
|
CATCH_IN_CALLBACK("FileReadAll")
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in readAll!");
|
|
}
|
|
|
|
Local<Value> FileClass::write(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
if (args.size() >= 2)
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
|
|
|
|
try {
|
|
string data;
|
|
bool isString = true;
|
|
if (args[0].isString()) {
|
|
data = std::move(args[0].toStr());
|
|
} else if (args[0].isByteBuffer()) {
|
|
isString = false;
|
|
data = std::move(string((char*)args[0].asByteBuffer().getRawBytes(), args[0].asByteBuffer().byteLength()));
|
|
} else {
|
|
LOG_WRONG_ARG_TYPE();
|
|
return Local<Value>();
|
|
}
|
|
|
|
script::Global<Function> callbackFunc;
|
|
if (args.size() >= 2)
|
|
callbackFunc = args[1].asFunction();
|
|
|
|
pool.enqueue([fp{&file}, lock{&lock}, data{std::move(data)}, isString,
|
|
callback{std::move(callbackFunc)}, engine{EngineScope::currentEngine()}]() {
|
|
if (LL::isServerStopping())
|
|
return;
|
|
if (!EngineManager::isValid(engine))
|
|
return;
|
|
|
|
lock->lock();
|
|
if (isString)
|
|
*fp << data;
|
|
else
|
|
fp->write(data.data(), data.size());
|
|
bool isOk = !fp->fail() && !fp->bad();
|
|
lock->unlock();
|
|
|
|
if (!callback.isEmpty()) {
|
|
EngineScope scope(engine);
|
|
try {
|
|
NewTimeout(callback.get(), {Boolean::newBoolean(isOk)}, 1);
|
|
}
|
|
CATCH_IN_CALLBACK("WriteFile")
|
|
}
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in write!");
|
|
}
|
|
|
|
Local<Value> FileClass::writeLine(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
if (args.size() >= 2)
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
|
|
|
|
try {
|
|
string data{std::move(args[0].toStr())};
|
|
|
|
script::Global<Function> callbackFunc;
|
|
if (args.size() >= 2)
|
|
callbackFunc = args[1].asFunction();
|
|
|
|
pool.enqueue([fp{&file}, lock{&lock}, data{std::move(data)},
|
|
callback{std::move(callbackFunc)}, engine{EngineScope::currentEngine()}]() {
|
|
if (LL::isServerStopping())
|
|
return;
|
|
if (!EngineManager::isValid(engine))
|
|
return;
|
|
|
|
lock->lock();
|
|
*fp << data << "\n";
|
|
bool isOk = !fp->fail() && !fp->bad();
|
|
lock->unlock();
|
|
|
|
if (!callback.isEmpty()) {
|
|
EngineScope scope(engine);
|
|
try {
|
|
NewTimeout(callback.get(), {Boolean::newBoolean(isOk)}, 1);
|
|
}
|
|
CATCH_IN_CALLBACK("FileWriteLine")
|
|
}
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in writeLine!");
|
|
}
|
|
|
|
Local<Value> FileClass::seekTo(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kBoolean);
|
|
|
|
try {
|
|
int pos = args[0].toInt();
|
|
if (args[1].asBoolean().value()) {
|
|
// relative
|
|
ios_base::seekdir way = ios_base::cur;
|
|
file.seekg(pos, way);
|
|
file.seekp(pos, way);
|
|
} else {
|
|
// absolute
|
|
if (pos >= 0) {
|
|
ios_base::seekdir way = ios_base::beg;
|
|
file.seekg(pos, way);
|
|
file.seekp(pos, way);
|
|
} else {
|
|
ios_base::seekdir way = ios_base::end;
|
|
file.seekg(0, way);
|
|
file.seekp(0, way);
|
|
}
|
|
}
|
|
return Boolean::newBoolean(!file.fail() && !file.bad());
|
|
}
|
|
CATCH("Fail in seekTo!");
|
|
}
|
|
|
|
Local<Value> FileClass::setSize(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return Boolean::newBoolean(_chsize_s((int)GetHANDLEfromFstream(file), args[0].asNumber().toInt64()) == 0);
|
|
}
|
|
CATCH("Fail in setSize!");
|
|
}
|
|
|
|
Local<Value> FileClass::close(const Arguments& args) {
|
|
try {
|
|
file.close();
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in flush!");
|
|
}
|
|
|
|
Local<Value> FileClass::isEOF(const Arguments& args) {
|
|
try {
|
|
return Boolean::newBoolean(file.eof());
|
|
}
|
|
CATCH("Fail in isEOF!");
|
|
}
|
|
|
|
Local<Value> FileClass::flush(const Arguments& args) {
|
|
try {
|
|
pool.enqueue([fp{&file}, lock{&lock}]() {
|
|
lock->lock();
|
|
fp->flush();
|
|
lock->unlock();
|
|
});
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in flush!");
|
|
}
|
|
|
|
Local<Value> FileClass::errorCode(const Arguments& args) {
|
|
try {
|
|
file.flush();
|
|
return Number::newNumber(errno);
|
|
}
|
|
CATCH("Fail in flush!");
|
|
}
|
|
|
|
Local<Value> FileClass::clear(const Arguments& args) {
|
|
try {
|
|
file.clear();
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in flush!");
|
|
}
|
|
|
|
|
|
//////////////////// APIs ////////////////////
|
|
|
|
Local<Value> DirCreate(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
return Boolean::newBoolean(CreateDirs(args[0].toStr()));
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Create Dir " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in CreateDir!");
|
|
}
|
|
|
|
Local<Value> PathDelete(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
return Boolean::newBoolean(remove_all(str2wstr(args[0].asString().toString())) > 0);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Delete " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in DeletePath!");
|
|
}
|
|
|
|
Local<Value> PathExists(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
return Boolean::newBoolean(filesystem::exists(str2wstr(args[0].asString().toString())));
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Check " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in ExistsPath!");
|
|
}
|
|
|
|
Local<Value> PathCopy(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
copy(str2wstr(args[0].asString().toString()), str2wstr(args[1].asString().toString()));
|
|
return Boolean::newBoolean(true);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Copy " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in CopyPath!");
|
|
}
|
|
|
|
Local<Value> PathRename(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
rename(str2wstr(args[0].asString().toString()), str2wstr(args[1].asString().toString()));
|
|
return Boolean::newBoolean(true);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Rename " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in RenamePath!");
|
|
}
|
|
|
|
Local<Value> PathMove(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
copy(str2wstr(args[0].asString().toString()), str2wstr(args[1].asString().toString()));
|
|
remove_all(str2wstr(args[0].asString().toString()));
|
|
return Boolean::newBoolean(true);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Move " + args[0].asString().toString() + "!\n");
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
CATCH("Fail in MovePath!");
|
|
}
|
|
|
|
Local<Value> CheckIsDir(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
path p(str2wstr(args[0].toStr()));
|
|
if (!exists(p))
|
|
return Boolean::newBoolean(false);
|
|
|
|
return Boolean::newBoolean(directory_entry(p).is_directory());
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Get Type of " + args[0].asString().toString() + "!\n");
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in GetFilesList!");
|
|
}
|
|
|
|
Local<Value> GetFileSize(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
path p(str2wstr(args[0].toStr()));
|
|
if (!exists(p))
|
|
return Number::newNumber(0);
|
|
if (directory_entry(p).is_directory())
|
|
return Number::newNumber(0);
|
|
|
|
auto sz = file_size(p);
|
|
return Number::newNumber((int64_t)sz);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Get Size of " + args[0].asString().toString() + "!\n");
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in GetFilesList!");
|
|
}
|
|
|
|
Local<Value> GetFilesList(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto fileList = GetFileNameList(args[0].toStr());
|
|
|
|
Local<Array> arr = Array::newArray();
|
|
for (auto& file : fileList)
|
|
arr.add(String::newString(file));
|
|
return arr;
|
|
}
|
|
CATCH("Fail in GetFilesList!");
|
|
}
|
|
|
|
Local<Value> FileReadFrom(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto content = ReadAllFile(args[0].toStr());
|
|
if (!content)
|
|
return Local<Value>(); // Null
|
|
return String::newString(*content);
|
|
}
|
|
CATCH("Fail in FileReadAll!");
|
|
}
|
|
|
|
Local<Value> FileWriteTo(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
string path = args[0].toStr();
|
|
CreateDirs(path);
|
|
return Boolean::newBoolean(WriteAllFile(path, args[1].toStr(), false));
|
|
}
|
|
CATCH("Fail in FileWriteAll!");
|
|
}
|
|
|
|
Local<Value> FileWriteLine(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
string path = args[0].toStr();
|
|
CreateDirs(path);
|
|
|
|
std::ofstream fileWrite(path, std::ios::app);
|
|
if (!fileWrite)
|
|
return Boolean::newBoolean(false);
|
|
fileWrite << args[1].toStr() << std::endl;
|
|
return Boolean::newBoolean(fileWrite.good());
|
|
}
|
|
CATCH("Fail in FileWriteLine!");
|
|
}
|
|
|
|
|
|
//////////////////// For Compatibility ////////////////////
|
|
|
|
Local<Value> OpenFile(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
if (args.size() >= 3)
|
|
CHECK_ARG_TYPE(args[2], ValueKind::kBoolean);
|
|
|
|
try {
|
|
string path = args[0].toStr();
|
|
CreateDirs(path);
|
|
|
|
FileOpenMode fMode = (FileOpenMode)(args[1].toInt());
|
|
ios_base::openmode mode = ios_base::in;
|
|
if (fMode == FileOpenMode::WriteMode) {
|
|
fstream tmp(str2wstr(path), ios_base::app);
|
|
tmp.flush();
|
|
tmp.close();
|
|
mode |= ios_base::out;
|
|
} else if (fMode == FileOpenMode::AppendMode)
|
|
mode |= ios_base::app;
|
|
|
|
bool isBinary = false;
|
|
if (args.size() >= 3 && args[2].asBoolean().value()) {
|
|
isBinary = true;
|
|
mode |= ios_base::binary;
|
|
}
|
|
|
|
fstream fs(str2wstr(path), mode);
|
|
if (!fs.is_open()) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Open File " + path + "!\n");
|
|
return Local<Value>();
|
|
}
|
|
return FileClass::newFile(std::move(fs), path, isBinary);
|
|
} catch (const filesystem_error& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Fail to Open File " + args[0].asString().toString() + "!\n");
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in OpenFile!");
|
|
}
|
|
|
|
Local<Object> FileClass::newFile(std::fstream&& f, const std::string& path, bool isBinary) {
|
|
auto newp = new FileClass(std::move(f), path, isBinary);
|
|
return newp->getScriptObject();
|
|
} |