mirror of
https://github.com/taurusxin/ncmdump.git
synced 2025-09-14 13:56:49 +08:00
Add logger.hpp
This commit is contained in:
parent
c188a824ad
commit
e3aedd510f
103
src/include/logger.hpp
Normal file
103
src/include/logger.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
namespace cxxlog
|
||||
{
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
Logger():
|
||||
is_running_(true)
|
||||
{
|
||||
thread_ = std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
cv_.wait(lock, [&](){ return !is_running_ || !msg_queue_.empty(); });
|
||||
if (!is_running_ && msg_queue_.empty())
|
||||
return;
|
||||
else if (msg_queue_.empty())
|
||||
continue;
|
||||
std::function<void()> func = std::move(msg_queue_.front());
|
||||
msg_queue_.pop();
|
||||
lock.unlock();
|
||||
std::invoke(func);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
~Logger()
|
||||
{
|
||||
if (is_running_)
|
||||
join();
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void cerr(Args... args)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
msg_queue_.push(std::bind([](auto... args) {
|
||||
std::cerr << generateTimeFormatString();
|
||||
((std::cerr << args), ...);
|
||||
std::cerr << std::endl;
|
||||
}, std::move(args)...));
|
||||
lock.unlock();
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void cout(Args... args)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
msg_queue_.push(std::bind([](auto... args) {
|
||||
std::cout << generateTimeFormatString();
|
||||
((std::cout << args), ...);
|
||||
std::cout << std::endl;
|
||||
}, std::move(args)...));
|
||||
lock.unlock();
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
void join()
|
||||
{
|
||||
is_running_ = false;
|
||||
cv_.notify_all();
|
||||
|
||||
if (thread_.joinable())
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
bool joinable()
|
||||
{
|
||||
return is_running_;
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::string generateTimeFormatString()
|
||||
{
|
||||
auto t = std::chrono::system_clock::to_time_t(
|
||||
std::chrono::system_clock::now());
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), "[%H:%M:%S]");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::condition_variable cv_;
|
||||
std::mutex mutex_;
|
||||
std::atomic<bool> is_running_;
|
||||
std::queue<std::function<void()>> msg_queue_;
|
||||
std::thread thread_;
|
||||
};
|
||||
|
||||
} // namespace cxxlog
|
@ -41,6 +41,21 @@ public:
|
||||
}
|
||||
|
||||
~ThreadPool() noexcept
|
||||
{
|
||||
if (is_running_)
|
||||
join();
|
||||
}
|
||||
|
||||
template<class Func, class... Args>
|
||||
void submit(Func&& func, Args&&... args)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
queue_.push(std::bind(func, std::forward<Args>(args)...));
|
||||
lock.unlock();
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
void join()
|
||||
{
|
||||
is_running_ = false;
|
||||
cv_.notify_all();
|
||||
@ -52,13 +67,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<class Func, class... Args>
|
||||
void submit(Func&& func, Args&&... args)
|
||||
bool joinable()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
queue_.push(std::bind(func, std::forward<Args>(args)...));
|
||||
lock.unlock();
|
||||
cv_.notify_one();
|
||||
return is_running_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
77
src/main.cpp
77
src/main.cpp
@ -4,6 +4,7 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "platform.h"
|
||||
@ -13,45 +14,48 @@
|
||||
#include "version.h"
|
||||
#include "cxxopts.hpp"
|
||||
#include "thread_pool.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
cxxpool::ThreadPool thread_pool;
|
||||
cxxlog::Logger logger;
|
||||
|
||||
void processFileTask(fs::path filePath, fs::path outputFolder)
|
||||
{
|
||||
if (fs::exists(filePath) == false)
|
||||
{
|
||||
logger.cerr(BOLDRED, "[Error] ", RESET, "file '", filePath.u8string(), "' does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if not ending with ".ncm"
|
||||
if (!filePath.has_extension() || filePath.extension().u8string() != ".ncm")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NeteaseCrypt crypt(filePath.u8string());
|
||||
crypt.Dump(outputFolder.u8string());
|
||||
crypt.FixMetadata();
|
||||
|
||||
logger.cout(BOLDGREEN, "[Done] ", RESET, "'", filePath.u8string(), "' -> '", crypt.dumpFilepath().u8string(), "'");
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
logger.cerr(BOLDRED, "[Exception] ", RESET, RED, e.what(), RESET, " '", filePath.u8string(), "'");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
logger.cerr(BOLDRED, "[Error] Unexpected exception while processing file: ", RESET, filePath.u8string());
|
||||
}
|
||||
}
|
||||
|
||||
void processFile(const fs::path &filePath, const fs::path &outputFolder)
|
||||
{
|
||||
auto work_func = [](fs::path filePath, fs::path outputFolder) {
|
||||
if (fs::exists(filePath) == false)
|
||||
{
|
||||
std::cerr << BOLDRED << "[Error] " << RESET << "file '" << filePath.u8string() << "' does not exist." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if not ending with ".ncm"
|
||||
if (!filePath.has_extension() || filePath.extension().u8string() != ".ncm")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NeteaseCrypt crypt(filePath.u8string());
|
||||
crypt.Dump(outputFolder.u8string());
|
||||
crypt.FixMetadata();
|
||||
|
||||
std::cout << BOLDGREEN << "[Done] " << RESET << "'" << filePath.u8string() << "' -> '" << crypt.dumpFilepath().u8string() << "'" << std::endl;
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
std::cerr << BOLDRED << "[Exception] " << RESET << RED << e.what() << RESET << " '" << filePath.u8string() << "'" << std::endl;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << BOLDRED << "[Error] Unexpected exception while processing file: " << RESET << filePath.u8string() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
thread_pool.submit(work_func, filePath, outputFolder);
|
||||
thread_pool.submit(processFileTask, filePath, outputFolder);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -194,6 +198,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (thread_pool.joinable())
|
||||
thread_pool.join();
|
||||
if (logger.joinable())
|
||||
logger.join();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -218,6 +226,11 @@ int main(int argc, char **argv)
|
||||
processFile(filePathU8, "");
|
||||
}
|
||||
}
|
||||
if (thread_pool.joinable())
|
||||
thread_pool.join();
|
||||
if (logger.joinable())
|
||||
logger.join();
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user