diff --git a/GUI/host/textthread.cpp b/GUI/host/textthread.cpp index c047356..40be2d1 100644 --- a/GUI/host/textthread.cpp +++ b/GUI/host/textthread.cpp @@ -4,6 +4,16 @@ extern const wchar_t* INVALID_CODEPAGE; +// return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) +static bool RemoveRepetition(std::wstring& text) +{ + wchar_t* end = text.data() + text.size(); + for (int length = text.size() / 3; length > 6; --length) + if (memcmp(end - length * 3, end - length * 2, length * sizeof(wchar_t)) == 0 && memcmp(end - length * 3, end - length * 1, length * sizeof(wchar_t)) == 0) + return RemoveRepetition(text = std::wstring(end - length, length)), true; + return false; +} + TextThread::TextThread(ThreadParam tp, HookParam hp, std::optional name) : handle(threadCounter++), name(name.value_or(Util::StringToWideString(hp.name).value())), @@ -44,7 +54,7 @@ void TextThread::Push(BYTE* data, int length) if (filterRepetition) { if (std::all_of(buffer.begin(), buffer.end(), [&](auto ch) { return repeatingChars.find(ch) != repeatingChars.end(); })) buffer.clear(); - if (Util::RemoveRepetition(buffer)) // sentence repetition detected, which means the entire sentence has already been received + if (RemoveRepetition(buffer)) // sentence repetition detected, which means the entire sentence has already been received { repeatingChars = std::unordered_set(buffer.begin(), buffer.end()); AddSentence(std::move(buffer)); diff --git a/GUI/host/util.cpp b/GUI/host/util.cpp index 0a77833..f4d92ef 100644 --- a/GUI/host/util.cpp +++ b/GUI/host/util.cpp @@ -310,15 +310,6 @@ namespace Util return {}; } - bool RemoveRepetition(std::wstring& text) - { - wchar_t* end = text.data() + text.size(); - for (int length = text.size() / 3; length > 6; --length) - if (memcmp(end - length * 3, end - length * 2, length * sizeof(wchar_t)) == 0 && memcmp(end - length * 3, end - length * 1, length * sizeof(wchar_t)) == 0) - return RemoveRepetition(text = std::wstring(end - length, length)), true; - return false; - } - std::optional ParseCode(std::wstring code) { if (code[0] == L'/') code.erase(0, 1); // legacy/AGTH compatibility diff --git a/GUI/host/util.h b/GUI/host/util.h index 4a0c522..9ea63d6 100644 --- a/GUI/host/util.h +++ b/GUI/host/util.h @@ -10,8 +10,6 @@ namespace Util std::vector>> GetAllProcesses(); std::optional GetClipboardText(); std::optional StringToWideString(const std::string& text, UINT encoding = CP_UTF8); - // return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) - bool RemoveRepetition(std::wstring& text); std::optional ParseCode(std::wstring code); std::wstring GenerateCode(HookParam hp, DWORD processId); } diff --git a/extensions/extensionimpl.cpp b/extensions/extensionimpl.cpp index e333bd4..8decc99 100644 --- a/extensions/extensionimpl.cpp +++ b/extensions/extensionimpl.cpp @@ -2,15 +2,16 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo); -/** - * You shouldn't mess with this or even look at it unless you're certain you know what you're doing. - * Param sentence: pointer to sentence received by Textractor (UTF-16). - * This can be modified. Textractor uses the modified sentence for future processing and display. If empty (starts with null terminator), Textractor will destroy it. - * Textractor will display the sentence after all extensions have had a chance to process and/or modify it. - * The buffer is allocated using HeapAlloc(). If you want to make it larger, please use HeapReAlloc(). - * Param miscInfo: pointer to array containing misc info about the sentence. End of array is marked with name being nullptr. - * Return value: the buffer used for the sentence. Remember to return a new pointer if HeapReAlloc() gave you one. - * THIS FUNCTION MAY BE RUN SEVERAL TIMES CONCURRENTLY: PLEASE ENSURE THAT IT IS THREAD SAFE! +/* + You shouldn't mess with this or even look at it unless you're certain you know what you're doing. + Param sentence: pointer to sentence received by Textractor (UTF-16). + This can be modified. Textractor uses the modified sentence for future processing and display. If empty (starts with null terminator), Textractor will destroy it. + Textractor will display the sentence after all extensions have had a chance to process and/or modify it. + The buffer is allocated using HeapAlloc(). If you want to make it larger, please use HeapReAlloc(). + Param miscInfo: pointer to array containing misc info about the sentence. End of array is marked with name being nullptr. + Return value: the buffer used for the sentence. Remember to return a new pointer if HeapReAlloc() gave you one. + This function may be run concurrently with itself: please make sure it's thread safe. + It will not be run concurrently with DllMain. */ extern "C" __declspec(dllexport) wchar_t* OnNewSentence(wchar_t* sentence, const InfoForExtension* miscInfo) { diff --git a/include/common.h b/include/common.h index 7624635..2a73ec8 100644 --- a/include/common.h +++ b/include/common.h @@ -90,7 +90,7 @@ inline auto FormatArg(const std::basic_string& arg) { return arg.c_str(); } #pragma warning(push) #pragma warning(disable: 4996) template -inline std::string FormatString(const char* format, Args... args) +inline std::string FormatString(const char* format, const Args&... args) { std::string buffer(snprintf(nullptr, 0, format, FormatArg(args)...), '\0'); sprintf(buffer.data(), format, FormatArg(args)...); @@ -98,7 +98,7 @@ inline std::string FormatString(const char* format, Args... args) } template -inline std::wstring FormatString(const wchar_t* format, Args... args) +inline std::wstring FormatString(const wchar_t* format, const Args&... args) { std::wstring buffer(_snwprintf(nullptr, 0, format, FormatArg(args)...), L'\0'); _swprintf(buffer.data(), format, FormatArg(args)...);