add extension class and refactor extensions using it

This commit is contained in:
Akash Mozumdar 2018-10-10 07:03:15 -04:00
parent ec1bd5622e
commit effb005376
6 changed files with 52 additions and 36 deletions

View File

@ -2,28 +2,34 @@
#include <shared_mutex>
#include <QDir>
std::shared_mutex extenMutex;
std::map<int, ExtensionFunction> extensions;
std::map<int, QString> LoadExtensions()
std::optional<Extension> LoadExtension(QString file)
{
std::map<int, ExtensionFunction> newExtensions;
std::map<int, QString> extensionNames;
// Extension file format: {NUMBER}_{NAME}.dll and exports "OnNewSentence"
QRegularExpressionMatch parsedFile = QRegularExpression("^(\\d+)_(.+).dll$").match(file);
if (!parsedFile.hasMatch()) return {};
HMODULE module = GetModuleHandleW(file.toStdWString().c_str());
if (!module) module = LoadLibraryW(file.toStdWString().c_str());
if (!module) return {};
auto callback = (wchar_t*(*)(const wchar_t*, const InfoForExtension*))GetProcAddress(module, "OnNewSentence");
if (!callback) return {};
return Extension{ parsedFile.captured(1).toInt(), parsedFile.captured(2), callback };
}
std::shared_mutex extenMutex;
std::set<Extension> extensions;
std::set<Extension> LoadExtensions()
{
std::set<Extension> newExtensions;
QStringList files = QDir().entryList();
for (auto file : files)
if (file.split("_").size() > 1 && file.split("_")[0].toInt() && file.endsWith(".dll"))
if (GetProcAddress(GetModuleHandleW(file.toStdWString().c_str()), "OnNewSentence") ||
GetProcAddress(LoadLibraryW(file.toStdWString().c_str()), "OnNewSentence"))
{
int extensionNumber = file.split("_")[0].toInt();
newExtensions[extensionNumber] = (ExtensionFunction)GetProcAddress(GetModuleHandleW(file.toStdWString().c_str()), "OnNewSentence");
file.chop(sizeof("dll"));
file.remove(0, file.indexOf("_") + 1);
extensionNames[extensionNumber] = file;
}
if (auto extension = LoadExtension(file)) newExtensions.insert(extension.value());
std::unique_lock<std::shared_mutex> extenLock(extenMutex);
extensions = newExtensions;
return extensionNames;
return extensions = newExtensions;
}
bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo)
@ -31,19 +37,21 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std
bool success = true;
wchar_t* sentenceBuffer = (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (sentence.size() + 1) * sizeof(wchar_t));
wcscpy_s(sentenceBuffer, sentence.size() + 1, sentence.c_str());
InfoForExtension* miscInfoLinkedList = new InfoForExtension;
InfoForExtension* miscInfoTraverser = miscInfoLinkedList;
for (auto& i : miscInfo) miscInfoTraverser = miscInfoTraverser->nextProperty = new InfoForExtension{ i.first.c_str(), i.second, nullptr };
InfoForExtension miscInfoLinkedList{ "", 0, nullptr };
InfoForExtension* miscInfoTraverser = &miscInfoLinkedList;
for (auto& i : miscInfo) miscInfoTraverser = miscInfoTraverser->next = new InfoForExtension{ i.first.c_str(), i.second, nullptr };
std::shared_lock<std::shared_mutex> extenLock(extenMutex);
for (auto i : extensions)
for (auto extension : extensions)
{
wchar_t* nextBuffer = i.second(sentenceBuffer, miscInfoLinkedList);
wchar_t* nextBuffer = extension.callback(sentenceBuffer, &miscInfoLinkedList);
if (nextBuffer == nullptr) { success = false; break; }
if (nextBuffer != sentenceBuffer) HeapFree(GetProcessHeap(), 0, sentenceBuffer);
sentenceBuffer = nextBuffer;
}
sentence = std::wstring(sentenceBuffer);
HeapFree(GetProcessHeap(), 0, sentenceBuffer);
delete miscInfoLinkedList;
return success;
}

View File

@ -2,17 +2,25 @@
#define EXTENSIONS_H
#include "qtcommon.h"
#include <map>
#include <set>
std::map<int, QString> LoadExtensions();
bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo);
struct InfoForExtension
{
~InfoForExtension() { if (nextProperty) delete nextProperty; };
const char* propertyName = "";
int64_t propertyValue = 0;
InfoForExtension* nextProperty = nullptr;
const char* name;
int64_t value;
InfoForExtension* next;
~InfoForExtension() { if (next) delete next; };
};
typedef wchar_t*(*ExtensionFunction)(const wchar_t*, const InfoForExtension*);
struct Extension
{
int number;
QString name;
wchar_t*(*callback)(const wchar_t*, const InfoForExtension*);
bool operator<(const Extension& other) const { return number < other.number; }
};
std::set<Extension> LoadExtensions();
bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo);
#endif // EXTENSIONS_H

View File

@ -141,8 +141,7 @@ DWORD MainWindow::GetSelectedProcessId()
void MainWindow::ReloadExtensions()
{
extenCombo->clear();
std::map<int, QString> extensions = LoadExtensions();
for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ": " + i.second);
for (auto extension : LoadExtensions()) extenCombo->addItem(QString::number(extension.number) + ": " + extension.name);
}
std::unordered_map<std::string, int64_t> MainWindow::GetInfoForExtensions(TextThread* thread)

View File

@ -4,7 +4,6 @@
#include "qtcommon.h"
#include "types.h"
#include <QHash>
#include <optional>
QString GetFullModuleName(DWORD processId, HMODULE module = NULL);
QString GetModuleName(DWORD processId, HMODULE module = NULL);

View File

@ -3,4 +3,5 @@
#include "common.h"
#include <QString>
#include <QStringList>
#include <QVector>
#include <QVector>
#include <QRegularExpression>

View File

@ -6,6 +6,7 @@
#include <vector>
#include <unordered_map>
#include <functional>
#include <optional>
#include <thread>
#include <mutex>
#include <cstdint>