From a67263fa2772397f3afb588613c531a02c7c70f8 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 7 Oct 2021 14:49:49 +0200 Subject: [PATCH] patterns: Added basic file i/o functions --- .../source/content/pl_builtin_functions.cpp | 130 ++++++++++++++++++ plugins/libimhex/source/helpers/file.cpp | 4 +- 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/plugins/builtin/source/content/pl_builtin_functions.cpp b/plugins/builtin/source/content/pl_builtin_functions.cpp index e320e6afc..9f4aaba3e 100644 --- a/plugins/builtin/source/content/pl_builtin_functions.cpp +++ b/plugins/builtin/source/content/pl_builtin_functions.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -240,6 +241,135 @@ namespace hex::plugin::builtin { return net.getString(url).get().body; }); } + + + ContentRegistry::PatternLanguageFunctions::Namespace nsStdFile = { "std", "file" }; + { + + static u32 fileCounter = 0; + static std::map openFiles; + + /* open(path, mode) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "open", 2, [](Evaluator *ctx, auto params) -> std::optional { + const auto path = Token::literalToString(params[0], false); + const auto modeEnum = Token::literalToUnsigned(params[1]); + + File::Mode mode; + switch (modeEnum) { + case 1: mode = File::Mode::Read; break; + case 2: mode = File::Mode::Write; break; + case 3: mode = File::Mode::Create; break; + default: + LogConsole::abortEvaluation("invalid file open mode"); + } + + auto file = File(path, mode); + + if (!file.isValid()) + LogConsole::abortEvaluation(hex::format("failed to open file {}", path)); + + fileCounter++; + openFiles.emplace(std::pair{ fileCounter, std::move(file) }); + + return u128(fileCounter); + }); + + /* close(file) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "close", 1, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles.erase(file); + + return { }; + }); + + /* read(file, size) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "read", 2, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + const auto size = Token::literalToUnsigned(params[1]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + return openFiles[file].readString(size); + }); + + /* write(file, data) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "write", 2, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + const auto data = Token::literalToString(params[1], true); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles[file].write(data); + + return { }; + }); + + /* seek(file, offset) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "seek", 2, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + const auto offset = Token::literalToUnsigned(params[1]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles[file].seek(offset); + + return { }; + }); + + /* size(file) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "size", 1, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + return u128(openFiles[file].getSize()); + }); + + /* resize(file, size) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "resize", 2, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + const auto size = Token::literalToUnsigned(params[1]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles[file].setSize(size); + + return { }; + }); + + /* flush(file) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "flush", 1, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles[file].flush(); + + return { }; + }); + + /* remove(file) */ + ContentRegistry::PatternLanguageFunctions::add(nsStdFile, "remove", 1, [](Evaluator *ctx, auto params) -> std::optional { + const auto file = Token::literalToUnsigned(params[0]); + + if (!openFiles.contains(file)) + LogConsole::abortEvaluation("failed to access invalid file"); + + openFiles[file].remove(); + + return { }; + }); + } } } diff --git a/plugins/libimhex/source/helpers/file.cpp b/plugins/libimhex/source/helpers/file.cpp index 0a533827e..85d18f279 100644 --- a/plugins/libimhex/source/helpers/file.cpp +++ b/plugins/libimhex/source/helpers/file.cpp @@ -59,7 +59,9 @@ namespace hex { if (getSize() == 0) return { }; - return reinterpret_cast(readBytes(numBytes).data()); + auto bytes = readBytes(numBytes); + + return { reinterpret_cast(bytes.data()), bytes.size() }; } void File::write(const u8 *buffer, size_t size) {