sneed
This commit is contained in:
45
src/log.cpp
45
src/log.cpp
@@ -1,7 +1,5 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <iterator>
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
#include "sdl.h"
|
#include "sdl.h"
|
||||||
@@ -11,37 +9,6 @@ using namespace anm2ed::util;
|
|||||||
|
|
||||||
namespace anm2ed
|
namespace anm2ed
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
bool ensure_utf8_bom(const std::filesystem::path& path)
|
|
||||||
{
|
|
||||||
std::error_code ec{};
|
|
||||||
if (!std::filesystem::exists(path, ec)) return false;
|
|
||||||
|
|
||||||
std::ifstream existing(path, std::ios::binary);
|
|
||||||
if (!existing) return false;
|
|
||||||
|
|
||||||
char bom[3]{};
|
|
||||||
existing.read(bom, sizeof(bom));
|
|
||||||
auto bytesRead = existing.gcount();
|
|
||||||
auto hasBom = bytesRead == sizeof(bom) && bom[0] == '\xEF' && bom[1] == '\xBB' && bom[2] == '\xBF';
|
|
||||||
if (hasBom) return true;
|
|
||||||
|
|
||||||
existing.clear();
|
|
||||||
existing.seekg(0, std::ios::beg);
|
|
||||||
std::string contents((std::istreambuf_iterator<char>(existing)), std::istreambuf_iterator<char>());
|
|
||||||
existing.close();
|
|
||||||
|
|
||||||
std::ofstream output(path, std::ios::binary | std::ios::trunc);
|
|
||||||
if (!output) return false;
|
|
||||||
output << "\xEF\xBB\xBF";
|
|
||||||
output.write(contents.data(), static_cast<std::streamsize>(contents.size()));
|
|
||||||
output.close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::write_raw(const std::string& message)
|
void Logger::write_raw(const std::string& message)
|
||||||
{
|
{
|
||||||
std::println("{}", message);
|
std::println("{}", message);
|
||||||
@@ -59,17 +26,7 @@ namespace anm2ed
|
|||||||
void Logger::error(const std::string& message) { write(ERROR, message); }
|
void Logger::error(const std::string& message) { write(ERROR, message); }
|
||||||
void Logger::fatal(const std::string& message) { write(FATAL, message); }
|
void Logger::fatal(const std::string& message) { write(FATAL, message); }
|
||||||
void Logger::command(const std::string& message) { write(COMMAND, message); }
|
void Logger::command(const std::string& message) { write(COMMAND, message); }
|
||||||
void Logger::open(const std::filesystem::path& path)
|
void Logger::open(const std::filesystem::path& path) { file.open(path, std::ios::out | std::ios::app); }
|
||||||
{
|
|
||||||
std::error_code ec{};
|
|
||||||
auto exists = std::filesystem::exists(path, ec);
|
|
||||||
if (exists) ensure_utf8_bom(path);
|
|
||||||
|
|
||||||
file.open(path, std::ios::out | std::ios::app);
|
|
||||||
if (!file.is_open()) return;
|
|
||||||
|
|
||||||
if (!exists) file << "\xEF\xBB\xBF";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::filesystem::path Logger::path() { return sdl::preferences_directory_get() / "log.txt"; }
|
std::filesystem::path Logger::path() { return sdl::preferences_directory_get() / "log.txt"; }
|
||||||
|
|
||||||
|
|||||||
101
src/render.cpp
101
src/render.cpp
@@ -1,17 +1,11 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "process_.h"
|
#include "process_.h"
|
||||||
#include "sdl.h"
|
#include "sdl.h"
|
||||||
@@ -34,31 +28,10 @@ namespace anm2ed
|
|||||||
auto loggerPath = Logger::path();
|
auto loggerPath = Logger::path();
|
||||||
auto loggerPathString = path::to_utf8(loggerPath);
|
auto loggerPathString = path::to_utf8(loggerPath);
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
auto ffmpegOutputPath = loggerPath.parent_path() / "ffmpeg-output.log";
|
auto ffmpegTempPath = loggerPath.parent_path() / "ffmpeg_log.temp.txt";
|
||||||
auto ffmpegOutputPathString = path::to_utf8(ffmpegOutputPath);
|
auto ffmpegTempPathString = path::to_utf8(ffmpegTempPath);
|
||||||
std::error_code ffmpegOutputRemoveError;
|
std::error_code ffmpegTempError;
|
||||||
std::filesystem::remove(ffmpegOutputPath, ffmpegOutputRemoveError);
|
std::filesystem::remove(ffmpegTempPath, ffmpegTempError);
|
||||||
auto flush_ffmpeg_output = [&]()
|
|
||||||
{
|
|
||||||
std::ifstream teeFile(ffmpegOutputPath, std::ios::binary);
|
|
||||||
if (!teeFile) return;
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
bool isFirstLine = true;
|
|
||||||
while (std::getline(teeFile, line))
|
|
||||||
{
|
|
||||||
if (isFirstLine && line.size() >= 3 && static_cast<unsigned char>(line[0]) == 0xEF &&
|
|
||||||
static_cast<unsigned char>(line[1]) == 0xBB && static_cast<unsigned char>(line[2]) == 0xBF)
|
|
||||||
line.erase(0, 3);
|
|
||||||
if (!line.empty() && line.back() == '\r') line.pop_back();
|
|
||||||
logger.write_raw(line);
|
|
||||||
isFirstLine = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
teeFile.close();
|
|
||||||
std::error_code removeEc;
|
|
||||||
std::filesystem::remove(ffmpegOutputPath, removeEc);
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::filesystem::path audioPath{};
|
std::filesystem::path audioPath{};
|
||||||
@@ -143,56 +116,14 @@ namespace anm2ed
|
|||||||
command += " 2>&1";
|
command += " 2>&1";
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
auto logCommand = std::string("& ") + command + " | Tee-Object -FilePath " + string::quote(ffmpegOutputPathString) +
|
command = "powershell -Command \"& " + command + " | Tee-Object -FilePath " +
|
||||||
" -Encoding UTF8 -Append";
|
string::quote(ffmpegTempPathString) + " -Append\"";
|
||||||
logger.command(logCommand);
|
|
||||||
|
|
||||||
auto utf8_to_wstring = [](const std::string& value)
|
|
||||||
{
|
|
||||||
if (value.empty()) return std::wstring{};
|
|
||||||
auto length = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, nullptr, 0);
|
|
||||||
if (length <= 0) return std::wstring{};
|
|
||||||
std::wstring wide(static_cast<std::size_t>(length - 1), L'\0');
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, wide.data(), length);
|
|
||||||
return wide;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto base64_encode_utf16 = [](const std::wstring& input)
|
|
||||||
{
|
|
||||||
const auto* bytes = reinterpret_cast<const unsigned char*>(input.c_str());
|
|
||||||
auto length = input.size() * sizeof(wchar_t);
|
|
||||||
static constexpr char alphabet[] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
std::string encoded{};
|
|
||||||
encoded.reserve(((length + 2) / 3) * 4);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < length;)
|
|
||||||
{
|
|
||||||
auto remaining = length - i;
|
|
||||||
auto octetA = bytes[i++];
|
|
||||||
auto octetB = remaining > 1 ? bytes[i++] : 0;
|
|
||||||
auto octetC = remaining > 2 ? bytes[i++] : 0;
|
|
||||||
|
|
||||||
auto triple = (static_cast<uint32_t>(octetA) << 16) | (static_cast<uint32_t>(octetB) << 8) |
|
|
||||||
static_cast<uint32_t>(octetC);
|
|
||||||
|
|
||||||
encoded.push_back(alphabet[(triple >> 18) & 0x3F]);
|
|
||||||
encoded.push_back(alphabet[(triple >> 12) & 0x3F]);
|
|
||||||
encoded.push_back(remaining > 1 ? alphabet[(triple >> 6) & 0x3F] : '=');
|
|
||||||
encoded.push_back(remaining > 2 ? alphabet[triple & 0x3F] : '=');
|
|
||||||
}
|
|
||||||
|
|
||||||
return encoded;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto script = std::wstring(L"& { ") + utf8_to_wstring(logCommand) + L" }";
|
|
||||||
auto encodedCommand = base64_encode_utf16(script);
|
|
||||||
command = "powershell -NoProfile -EncodedCommand " + string::quote(encodedCommand);
|
|
||||||
#else
|
#else
|
||||||
command += " | tee -a " + string::quote(loggerPathString);
|
command += " | tee -a " + string::quote(loggerPathString);
|
||||||
logger.command(command);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
logger.command(command);
|
||||||
|
|
||||||
Process process(command.c_str(), "w");
|
Process process(command.c_str(), "w");
|
||||||
|
|
||||||
if (!process.get())
|
if (!process.get())
|
||||||
@@ -214,7 +145,21 @@ namespace anm2ed
|
|||||||
|
|
||||||
process.close();
|
process.close();
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
flush_ffmpeg_output();
|
{
|
||||||
|
std::ifstream ffmpegLog(ffmpegTempPath, std::ios::binary);
|
||||||
|
if (ffmpegLog)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(ffmpegLog, line))
|
||||||
|
{
|
||||||
|
if (!line.empty() && line.back() == '\r') line.pop_back();
|
||||||
|
logger.write_raw(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffmpegLog.close();
|
||||||
|
std::error_code removeLogError;
|
||||||
|
std::filesystem::remove(ffmpegTempPath, removeLogError);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
audio_remove();
|
audio_remove();
|
||||||
|
|||||||
Reference in New Issue
Block a user