From f4ee380c68ab78486c06c2abfe775b4e7e324a58 Mon Sep 17 00:00:00 2001 From: MiranDMC Date: Mon, 24 Jun 2024 20:52:20 +0200 Subject: [PATCH] New get_file_write_time opcode (#162) New opcode get_file_write_time --- .../FileSystemOperations.cpp | 40 +++++++ .../cleo_tests/FilesystemOperations/2305.txt | 110 ++++++++++++++++++ tests/cleo_tests/cleo_tester.inc | 13 +++ 3 files changed, 163 insertions(+) create mode 100644 tests/cleo_tests/FilesystemOperations/2305.txt diff --git a/cleo_plugins/FileSystemOperations/FileSystemOperations.cpp b/cleo_plugins/FileSystemOperations/FileSystemOperations.cpp index 825465e2..93ea5f68 100644 --- a/cleo_plugins/FileSystemOperations/FileSystemOperations.cpp +++ b/cleo_plugins/FileSystemOperations/FileSystemOperations.cpp @@ -76,6 +76,7 @@ class FileSystemOperations CLEO_RegisterOpcode(0x2302, opcode_2302); // write_block_to_file CLEO_RegisterOpcode(0x2303, opcode_2303); // resolve_filepath CLEO_RegisterOpcode(0x2304, opcode_2304); // get_script_filename + CLEO_RegisterOpcode(0x2305, opcode_2305); // get_file_write_time // register event callbacks CLEO_RegisterCallback(eCallbackId::ScriptsFinalize, OnFinalizeScriptObjects); @@ -760,6 +761,45 @@ class FileSystemOperations OPCODE_CONDITION_RESULT(true); return OR_CONTINUE; } + + //2305=8, get_file_write_time %1s% year %2d% month %3d% day %3d% hour %4d% minute %5d% second %6d% milisecond %7d% // IF and SET + static OpcodeResult __stdcall opcode_2305(CRunningScript* thread) + { + OPCODE_READ_PARAM_FILEPATH(path); + + HANDLE file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (file == INVALID_HANDLE_VALUE) + { + OPCODE_SKIP_PARAMS(7); + OPCODE_CONDITION_RESULT(false); + return OR_CONTINUE; + } + + FILETIME writeTime; + if (!GetFileTime(file, nullptr, nullptr, &writeTime)) + { + CloseHandle(file); + OPCODE_SKIP_PARAMS(7); + OPCODE_CONDITION_RESULT(false); + return OR_CONTINUE; + } + CloseHandle(file); + + // convert to local time + SYSTEMTIME timeUTC, timeLocal; + FileTimeToSystemTime(&writeTime, &timeUTC); + SystemTimeToTzSpecificLocalTime(NULL, &timeUTC, &timeLocal); + + OPCODE_WRITE_PARAM_INT(timeLocal.wYear); + OPCODE_WRITE_PARAM_INT(timeLocal.wMonth); + OPCODE_WRITE_PARAM_INT(timeLocal.wDay); + OPCODE_WRITE_PARAM_INT(timeLocal.wHour); + OPCODE_WRITE_PARAM_INT(timeLocal.wMinute); + OPCODE_WRITE_PARAM_INT(timeLocal.wSecond); + OPCODE_WRITE_PARAM_INT(timeLocal.wMilliseconds); + OPCODE_CONDITION_RESULT(true); + return OR_CONTINUE; + } } fileSystemOperations; std::set FileSystemOperations::m_hFiles; diff --git a/tests/cleo_tests/FilesystemOperations/2305.txt b/tests/cleo_tests/FilesystemOperations/2305.txt new file mode 100644 index 00000000..f35e722f --- /dev/null +++ b/tests/cleo_tests/FilesystemOperations/2305.txt @@ -0,0 +1,110 @@ +{$CLEO .s} +{$INCLUDE_ONCE ../cleo_tester.inc} + +script_name "2305" // get_file_write_time +test("2305 (get_file_write_time)", tests) +terminate_this_custom_script + + +function tests + const Test_File_Path = ".\test_file.ini" + + before_each(@prepare) + after_each(@finalize) + + it("should fail", test1) + it("should return valid data", test2) + it("should work with already opened file", test3) + it("should return correct time", test4) + return + + :prepare + 1@ = 0x11111111 + 2@ = 0x22222222 + 3@ = 0x33333333 + 4@ = 0x44444444 + 5@ = 0x55555555 + 6@ = 0x66666666 + 7@ = 0x77777777 + write_int_to_ini_file {value} 1234 {path} Test_File_Path {section} "general" {key} "test" + return + + :finalize + delete_file {fileName} Test_File_Path + return + + function test1 + 1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} ".\not_existing.ini" + assert_result_false() + assert_eq(1@, 0x11111111) + assert_eq(2@, 0x22222222) + assert_eq(3@, 0x33333333) + assert_eq(4@, 0x44444444) + assert_eq(5@, 0x55555555) + assert_eq(6@, 0x66666666) + assert_eq(7@, 0x77777777) + end + + function test2 + 1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} Test_File_Path + assert_result_true() + assert_range(1@, 2000, 2100) // year + assert_range(2@, 1, 12) // month + assert_range(3@, 1, 31) // day + assert_range(4@, 0, 23) // hour + assert_range(5@, 0, 59) // minute + assert_range(6@, 0, 59) // second + assert_range(7@, 0, 999) // milisedond + trace "~g~~h~~h~Read time: %04d-%02d-%02d %02d:%02d:%02d.%03d" 1@ 2@ 3@ 4@ 5@ 6@ 7@ + end + + function test3 + 1@, 2@, 3@, 4@, 5@, 6@, 7@ = get_file_write_time {path} "root:\cleo.asi" + assert_result_true() + assert_range(1@, 2000, 2100) // year + assert_range(2@, 1, 12) // month + assert_range(3@, 1, 31) // day + assert_range(4@, 0, 23) // hour + assert_range(5@, 0, 59) // minute + assert_range(6@, 0, 59) // second + assert_range(7@, 0, 999) // milisecond + end + + function test4 + var 0@ : Integer + var 1@ : Integer + var 2@ : Integer + var 3@ : Integer + var 4@ : Integer + var 5@ : Integer + var 6@ : Integer + var 7@ : Integer + var 8@ : Integer + + 0@, 0@, 0@, 1@, 2@, 3@, 4@ = get_file_write_time {path} Test_File_Path + assert_result_true() + + // calculate small time stamp + 2@ *= 60000 // minutes to ms + 3@ *= 1000 // seconds to ms + 4@ += 2@ + 4@ += 3@ + + wait 500 + write_int_to_ini_file {value} 1234 {path} Test_File_Path {section} "general" {key} "test4" + + 0@, 0@, 0@, 5@, 6@, 7@, 8@ = get_file_write_time {path} Test_File_Path + assert_result_true() + assert_eq(5@, 1@) // hour did not changed meanwhile + + // calculate small time stamp + 6@ *= 60000 // minutes to ms + 7@ *= 1000 // seconds to ms + 8@ += 6@ + 8@ += 7@ + + // timestamps delta + 8@ -= 4@ + assert_range(8@, 450, 550) // expected 500 plus some margin + end +end diff --git a/tests/cleo_tests/cleo_tester.inc b/tests/cleo_tests/cleo_tester.inc index 7776815a..5dbe36ea 100644 --- a/tests/cleo_tests/cleo_tester.inc +++ b/tests/cleo_tests/cleo_tester.inc @@ -198,6 +198,19 @@ function assert_neq(actual: int, expected: int) end end +/// checks if int value is within specified range, otherwise stops the test execution +function assert_range(actual: int, expectedMin: int, expectedMax: int) + _cleo_tester_increment_assert() + if + actual < expectedMin + then + _cleo_tester_fail() + trace "%08X to %08X expected~n~%08X occured" expectedMin expectedMax actual + breakpoint + terminate_this_custom_script + end +end + /// checks if two float values are equal, otherwise stops the test execution function assert_eqf(actual: float, expected: float) _cleo_tester_increment_assert()