wip: ini parse baseline
This commit is contained in:
parent
8e93120555
commit
8e07b1efdd
9 changed files with 356 additions and 27 deletions
|
|
@ -2,7 +2,7 @@ QMAKE_CXXFLAGS += --target=x86_64-w64-mingw32 -g -gcodeview -O0 -Werror=return-t
|
|||
QMAKE_LFLAGS += --target=x86_64-w64-mingw32 -g -Wl,-pdb= -v
|
||||
LIBS += -LC:/capybara/libclang/x86_64-w64-mingw32/lib -lWinmm -lodbc32 -lodbccp32 -luuid -loleaut32 -lole32 -lshell32 -ladvapi32 -lcomdlg32 -lwinspool -lgdi32 -luser32 -lkernel32 -lpropsys -static -stdlib=libc++ -lunwind
|
||||
#"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" -luuid -loleaut32 -lole32 -lshell32 -ladvapi32 -lcomdlg32 -lwinspool -lgdi32 -luser32 -lkernel32
|
||||
DEFINES += DEBUG QT_LOGGING_TO_CONSOLE=1 WIN32_LEAN_AND_MEAN
|
||||
DEFINES += DEBUG QT_LOGGING_TO_CONSOLE=1 WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602
|
||||
CONFIG += debug
|
||||
|
||||
QT += widgets network
|
||||
|
|
@ -10,8 +10,8 @@ INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimp
|
|||
DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont"
|
||||
VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont"
|
||||
|
||||
SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp backsessionclasses.cpp contclasses.cpp contsessionclasses.cpp
|
||||
HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h meterslider.h qtvisuals.h
|
||||
SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp backsessionclasses.cpp contclasses.cpp contsessionclasses.cpp settings.cpp
|
||||
HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h meterslider.h qtvisuals.h settings.h
|
||||
RESOURCES = assets.qrc
|
||||
RC_ICONS += assets/logo.ico
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "global.h"
|
||||
#include "contclasses.h"
|
||||
|
||||
#include <thread>
|
||||
class Endpoint;
|
||||
|
||||
class SessionStateCallback : public IAudioSessionEvents {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define _WIN32_WINNT 0x0A00
|
||||
|
||||
#include <sdkddkver.h>
|
||||
|
||||
//done by qt by def #define UNICODE
|
||||
|
|
@ -9,6 +7,8 @@
|
|||
#include <Windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <Shobjidl.h>
|
||||
#include <Shlobj.h>
|
||||
#include <fileapi.h>
|
||||
#include <appmodel.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <mmdeviceapi.h>
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <stringapiset.h>
|
||||
#include <Mmreg.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <Knownfolders.h>
|
||||
|
||||
#include "ipolicyconfig.h"
|
||||
#include "audiometerinfo.h"
|
||||
|
|
|
|||
11
src/global.h
11
src/global.h
|
|
@ -10,8 +10,10 @@
|
|||
#include <string>
|
||||
#include <bitset>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
|
||||
#include "debug.h"
|
||||
//#include "settings.h"
|
||||
|
||||
//TODO: Use tr();? QTranslator
|
||||
#define STRING_MUTE "Mute"
|
||||
|
|
@ -30,12 +32,17 @@
|
|||
#define STRING_CP "Open Control Panel"
|
||||
#define STRING_ABOUT "About"
|
||||
#define STRING_STARTUP "Run at startup"
|
||||
#define STRING_CHANNELS "Show endpoint channels"
|
||||
|
||||
#define STRING_NOENDPOINT "No active endpoints"
|
||||
|
||||
#define LSTRING_UNNAMED_SESSION L"Unnamed session"
|
||||
|
||||
|
||||
//INIT BACK
|
||||
|
||||
|
||||
|
||||
enum ProcessedNativeEvent {
|
||||
NONE = 0,
|
||||
COLORS = (1 << 0),
|
||||
|
|
@ -92,7 +99,11 @@ struct NGuid {
|
|||
/* }while (i < 8); */
|
||||
/* } */
|
||||
};
|
||||
namespace ini {
|
||||
class UserSettings;
|
||||
}
|
||||
|
||||
extern ini::UserSettings *set;
|
||||
class OverseerHandler;
|
||||
extern OverseerHandler *osh;
|
||||
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void MainWindow::compose() {
|
|||
this->mainMenuBar->setMaximumWidth((int)windowWidth);
|
||||
for (auto *epw : ews) {
|
||||
if (!epw) continue;
|
||||
|
||||
epw->updateChannelsVisibility();
|
||||
epw->calculateSize(windowWidth - scrollArea->verticalScrollBar()->sizeHint().width()
|
||||
- widgetLayout->contentsMargins().left()
|
||||
, screenHeight);
|
||||
|
|
@ -605,8 +605,12 @@ EndpointWidget::EndpointWidget(EndpointHandler* eph, QWidget *parent, uint64_t i
|
|||
if(epChannelCount > 1) {
|
||||
cw = new ChannelWidget(epChannelCount, eph, nullptr);
|
||||
cw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
//cw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
widgetLayout->addWidget(cw, row++, 0, 1, 4 /*colmax*/, Qt::AlignTop);
|
||||
cw->setVisible(false);
|
||||
char* const channelSettings = set->getValue("show_channels");
|
||||
if(channelSettings && !(strcmp(channelSettings, "true"))){
|
||||
cw->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -889,6 +893,13 @@ void EndpointWidget::updateMainVolume(int newValue){
|
|||
* }
|
||||
*/
|
||||
|
||||
void EndpointWidget::updateChannelsVisibility() {
|
||||
char* const channelSettings = set->getValue("show_channels");
|
||||
if(channelSettings && !(strcmp(channelSettings, "true"))){
|
||||
cw->setVisible(true);
|
||||
} else cw->setVisible(false);
|
||||
}
|
||||
|
||||
EndpointHandler* EndpointWidget::getEndpointHandler(){
|
||||
return this->eph;
|
||||
}
|
||||
|
|
@ -915,19 +926,36 @@ std::map<Roles, ExtendedCheckBox*> EndpointWidget::getDefaultRolesWidgets() {
|
|||
HeaderWidget::HeaderWidget(QWidget *parent) : QWidget(parent) {
|
||||
widgetLayout = new QGridLayout(this);
|
||||
|
||||
QString text = "&" STRING_ABOUT;
|
||||
about = new QPushButton(text, this);
|
||||
QString text; //= "&" STRING_ABOUT;
|
||||
//about = new QPushButton(text, this);
|
||||
#ifdef WIN32
|
||||
text = "&" STRING_CP;
|
||||
openCP = new QPushButton(text, this);
|
||||
connect(openCP, &QPushButton::clicked, [](){ osh->openControlPanel(); });
|
||||
text = "&" STRING_STARTUP;
|
||||
startup = new QPushButton(text, this);
|
||||
|
||||
widgetLayout->addWidget(openCP , 0, 0);
|
||||
widgetLayout->addWidget(startup, 0, 1);
|
||||
text = "&" STRING_CHANNELS;
|
||||
channels = new QCheckBox(text, this);
|
||||
char* const channelSettings = set->getValue("show_channels");
|
||||
if(channelSettings && !(strcmp(channelSettings, "true"))){
|
||||
channels->setChecked(true);
|
||||
}
|
||||
connect(channels, &QCheckBox::stateChanged, [this, parent](){
|
||||
set->setValue("show_channels", channels->isChecked(), sizeof("show_channels"));
|
||||
if(parent)
|
||||
QCoreApplication::instance()->postEvent
|
||||
(parent, new QEvent((QEvent::Type)CustomQEvent::RecomposeMainWindow));
|
||||
});
|
||||
|
||||
|
||||
text = "&" STRING_STARTUP;
|
||||
startup = new QCheckBox(text, this);
|
||||
//connect(openCP, &QPushButton::clicked, [](){ osh->openControlPanel(); });
|
||||
|
||||
widgetLayout->addWidget(openCP , 0, 0, 2, 2);
|
||||
widgetLayout->addWidget(channels, 0, 2, 1, 2);
|
||||
widgetLayout->addWidget(startup , 1, 2, 1, 2);
|
||||
#endif
|
||||
widgetLayout->addWidget(about , 0, 2);
|
||||
//widgetLayout->addWidget(about , 0, 2);
|
||||
this->setLayout(widgetLayout);
|
||||
}
|
||||
|
||||
|
|
@ -1034,19 +1062,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
|||
* Menu bar code
|
||||
*/
|
||||
mainMenuBar = new QToolBar(this);
|
||||
/*
|
||||
* QPalette pal;
|
||||
* pal.setColor(QPalette::Window, Qt::transparent);
|
||||
* mainMenuBar->setPalette(pal);
|
||||
*/
|
||||
hw = new HeaderWidget(this);
|
||||
mainMenuBar->addWidget(hw);
|
||||
mainMenuBar->setMovable(false);
|
||||
this->addToolBar(Qt::BottomToolBarArea, mainMenuBar);
|
||||
|
||||
reloadEndpointWidgets();
|
||||
//scrollArea->setMinimumWidth(ews.at(0)->minimumWidth());
|
||||
log_debugcpp(std::to_string(scrollArea->minimumWidth()));
|
||||
|
||||
/*
|
||||
* Tray Icon code
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "qtcommon.h"
|
||||
#include "contclasses.h"
|
||||
#include "settings.h"
|
||||
|
||||
class MeterSlider;
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ public:
|
|||
EndpointWidget(EndpointHandler* eph, QWidget *parent = nullptr, uint64_t idx = INT_MAX);
|
||||
//QSize minimumSizeHint() const override;
|
||||
//void setMinimum(uint64_t height, double heightRatio);
|
||||
|
||||
void updateChannelsVisibility();
|
||||
EndpointHandler* getEndpointHandler();
|
||||
std::map<Roles, ExtendedCheckBox*> getDefaultRolesWidgets();
|
||||
|
||||
|
|
@ -167,10 +168,11 @@ public:
|
|||
|
||||
private:
|
||||
QGridLayout *widgetLayout;
|
||||
QPushButton *about;
|
||||
//QPushButton *about;
|
||||
#ifdef WIN32
|
||||
QPushButton *openCP;
|
||||
QPushButton *startup;
|
||||
QCheckBox *startup;
|
||||
QCheckBox *channels;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
#include "qtcommon.h"
|
||||
#include "qtclasses.h"
|
||||
#include "qtvisuals.h"
|
||||
#include "settings.h"
|
||||
//#include "global.h"
|
||||
|
||||
OverseerHandler *osh = nullptr;
|
||||
ini::UserSettings *set = nullptr;
|
||||
|
||||
QApplication* createApplication(int &argc, char *argv[])
|
||||
{
|
||||
|
|
@ -31,6 +33,14 @@ void closeDebugFileLog() {
|
|||
close_file_log_buffer();
|
||||
}
|
||||
|
||||
char* parseCmdArgs(int argc, char* argv[]) {
|
||||
if(argc == 1) return nullptr;
|
||||
char arg[] = "--config-path=";
|
||||
if(strstr(argv[1], arg)) {
|
||||
return argv[1] + (sizeof(arg) / sizeof(arg[0])) - 1;
|
||||
} else return nullptr;
|
||||
}
|
||||
|
||||
/* set_terminate
|
||||
* void closeDebugFileLog2() {
|
||||
* close_file_log_buffer();
|
||||
|
|
@ -46,6 +56,8 @@ int main (int argc, char* argv[]) {
|
|||
* log_debugcpp(a.toStdString());
|
||||
* }
|
||||
*/
|
||||
//std::map<const char*, cha>* values = new std::map<const char*, int>{ {"show_channels", false}, {"test", 7} };
|
||||
set = new ini::UserSettings(parseCmdArgs(argc, argv));
|
||||
initialize_file_log();
|
||||
atexit(closeDebugFileLog);
|
||||
|
||||
|
|
|
|||
208
src/settings.cpp
Normal file
208
src/settings.cpp
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
#include "settings.h"
|
||||
#include "msinclude.h"
|
||||
|
||||
namespace ini {
|
||||
|
||||
UserSettings::UserSettings(char* path) {
|
||||
wchar_t* settingsPath = nullptr;
|
||||
wchar_t settingsFile[] = L"\\settings.ini";
|
||||
uint32_t settingsFileLen = (sizeof(settingsFile) / sizeof(wchar_t)) - 1;
|
||||
wchar_t maxPathBypass[] = L"\\\\?\\";
|
||||
log_wdebugcpp(L"Bypass size: " + std::to_wstring((sizeof(maxPathBypass)/sizeof(maxPathBypass[0]))));
|
||||
|
||||
//Executable dir
|
||||
settingsPath = (wchar_t*)calloc(UNICODE_STRING_MAX_CHARS, sizeof(wchar_t));
|
||||
uint32_t exePathLength = GetModuleFileNameW(
|
||||
NULL,
|
||||
settingsPath,
|
||||
UNICODE_STRING_MAX_CHARS
|
||||
);
|
||||
//reverse wcsstr
|
||||
while(exePathLength >= 0) {
|
||||
if(settingsPath[exePathLength] == '\\') {
|
||||
memset(settingsPath + exePathLength,
|
||||
0,
|
||||
(UNICODE_STRING_MAX_CHARS - exePathLength) * sizeof(wchar_t));
|
||||
break;
|
||||
} else exePathLength--;
|
||||
}
|
||||
log_wdebugcpp(L"Exe folder: " + std::wstring(settingsPath));
|
||||
|
||||
HANDLE settingsHandle = nullptr;
|
||||
if((UNICODE_STRING_MAX_CHARS - exePathLength) > (settingsFileLen + 1)) {
|
||||
memcpy(settingsPath + exePathLength, settingsFile, sizeof(wchar_t) * settingsFileLen);
|
||||
settingsHandle = CreateFile2(
|
||||
settingsPath,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
OPEN_ALWAYS,
|
||||
NULL);
|
||||
if(settingsHandle != INVALID_HANDLE_VALUE) { log_debugcpp("Filecreated!"); }
|
||||
else { CloseHandle(settingsHandle); settingsHandle = nullptr; return; }
|
||||
}
|
||||
|
||||
//Calculating file size and reading file
|
||||
if(settingsHandle) {
|
||||
uint64_t fileSize;
|
||||
LARGE_INTEGER fileSizeStruct;
|
||||
if(!GetFileSizeEx(settingsHandle, &fileSizeStruct)) return;
|
||||
fileSize = fileSizeStruct.QuadPart;
|
||||
|
||||
uint32_t bytesRead = 0;
|
||||
textContentsSize = fileSize + 1;
|
||||
textContents = (char*)calloc(textContentsSize, sizeof(char));
|
||||
if (ReadFile(settingsHandle, textContents, fileSize,
|
||||
(LPDWORD)&bytesRead, NULL) != TRUE) {
|
||||
free(textContents);
|
||||
return;
|
||||
}
|
||||
//textContents.assign(tempTextContents);
|
||||
//free(tempTextContents);
|
||||
|
||||
//Parsing values
|
||||
bool isCRLF = false;
|
||||
char *curLine = textContents;
|
||||
char *separator = nullptr, *key = nullptr, *value = nullptr;
|
||||
while(curLine) {
|
||||
char* nextLine = strchr(curLine, '\n');
|
||||
if(nextLine == curLine + 1 || nextLine == curLine + 2) goto nextIteration;
|
||||
if (nextLine && (isCRLF || *(nextLine - 1) == '\r')) {
|
||||
isCRLF = true;
|
||||
*(nextLine - 1) = '\0';
|
||||
} else if (nextLine) *nextLine = '\0'; // temporarily terminate the current line
|
||||
log_debugcpp("curLine: " + std::string(curLine) + " ");
|
||||
|
||||
separator = strchr(curLine, '=');
|
||||
if(!separator) goto nextIteration;
|
||||
*separator = '\0';
|
||||
key = trimAndAllocate(curLine);
|
||||
value = trimAndAllocate(separator + 1);
|
||||
values.try_emplace(key, value);
|
||||
log_debugcpp("ini Map size: " + std::to_string(values.size()));
|
||||
*separator = '=';
|
||||
|
||||
nextIteration:
|
||||
if (nextLine) { // then restore newline-char, just to be tidy
|
||||
if (isCRLF)
|
||||
*(nextLine - 1) = '\r';
|
||||
else *nextLine = '\n';
|
||||
}
|
||||
curLine = nextLine ? (nextLine + 1) : NULL;
|
||||
}
|
||||
/*
|
||||
* for(const std::pair<char[], int> keyVal : defaultValues) {
|
||||
* if (textContents.find(keyVal.first) {
|
||||
* if (keyVal.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
//todo: buffer overflow. poc
|
||||
char* const UserSettings::getValue(char* key, uint64_t len) {
|
||||
if (auto search = values.find(key); search != values.end())
|
||||
return (char* const) search->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UserSettings::setValue(char* key, char* value, uint64_t valueSize, uint64_t keySize) {
|
||||
char *newValue, *newKey;
|
||||
if (auto search = values.find(key); search != values.end()) {
|
||||
if(!(strcmp(value, search->second))) return;
|
||||
newValue = (char*)calloc(valueSize, sizeof(char));
|
||||
if (!(search->second == pos || search->second == neg)) {
|
||||
free(search->second);
|
||||
}
|
||||
search->second = newValue;
|
||||
return;
|
||||
}
|
||||
|
||||
newValue = (char*)calloc(valueSize, sizeof(char));
|
||||
newKey = (char*)calloc(keySize, sizeof(char));
|
||||
values.insert(std::make_pair(newKey, newValue));
|
||||
return;
|
||||
}
|
||||
|
||||
void UserSettings::setValue(char* key, bool value, uint64_t keySize) {
|
||||
char *newKey;
|
||||
log_debugcpp("Pos value: " + std::to_string((intptr_t)pos));
|
||||
log_debugcpp("Neg value: " + std::to_string((intptr_t)neg));
|
||||
if (auto search = values.find(key); search != values.end()) {
|
||||
log_debugcpp("Previous value: " + std::to_string((intptr_t)values[key]));
|
||||
if (!(search->second == pos || search->second == neg)) {
|
||||
free(search->second);
|
||||
}
|
||||
if (value)
|
||||
search->second = pos;
|
||||
else search->second = neg;
|
||||
return;
|
||||
}
|
||||
|
||||
newKey = (char*)calloc(keySize, sizeof(char));
|
||||
values.insert(std::make_pair(newKey, value ? pos : neg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//AppData path
|
||||
/*
|
||||
* wchar_t folderPath[] = L"\\mixerq";
|
||||
*
|
||||
* wchar_t* roamingPath = nullptr;
|
||||
* if(SHGetKnownFolderPath(
|
||||
* FOLDERID_RoamingAppData,
|
||||
* 0,
|
||||
* NULL,
|
||||
* &roamingPath)
|
||||
* == S_OK) {
|
||||
* uint32_t pathLen = 0;
|
||||
* wchar_t currentChar = roamingPath[pathLen];
|
||||
* while(currentChar != '\0') {
|
||||
* pathLen++;
|
||||
* currentChar = roamingPath[pathLen];
|
||||
* }
|
||||
*
|
||||
* uint32_t maxPathBypassLen = (sizeof(maxPathBypass)/ sizeof(wchar_t)) - 1;
|
||||
* uint32_t folderPathLen = (sizeof(folderPath) / sizeof(wchar_t)) - 1;
|
||||
* settingsPath = (wchar_t*)calloc(pathLen +
|
||||
* maxPathBypassLen +
|
||||
* folderPathLen +
|
||||
* settingsFileLen,
|
||||
* sizeof(wchar_t));
|
||||
* memcpy(settingsPath, maxPathBypass, sizeof(wchar_t) * maxPathBypassLen);
|
||||
* memcpy(settingsPath + (maxPathBypassLen), roamingPath, sizeof(wchar_t) * pathLen);
|
||||
* CoTaskMemFree(roamingPath);
|
||||
* memcpy(settingsPath + (maxPathBypassLen + pathLen),
|
||||
* folderPath, sizeof(wchar_t) * folderPathLen);
|
||||
* log_wdebugcpp(L"Settings folder path: " + std::wstring(settingsPath));
|
||||
*
|
||||
* if(CreateDirectoryW(settingsPath, NULL) || GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
* memcpy(settingsPath + (maxPathBypassLen + pathLen + folderPathLen),
|
||||
* settingsFile, sizeof(wchar_t) * settingsFileLen);
|
||||
*
|
||||
* HANDLE settingsHandle = CreateFile2(
|
||||
* settingsPath,
|
||||
* GENERIC_READ | GENERIC_WRITE,
|
||||
* 0,
|
||||
* OPEN_ALWAYS,
|
||||
* NULL);
|
||||
* if(settingsHandle != INVALID_HANDLE_VALUE) log_debugcpp("Filecreated!");
|
||||
*
|
||||
* }
|
||||
* //End AppData
|
||||
*/
|
||||
|
||||
|
||||
|
||||
UserSettings::~UserSettings() {
|
||||
if(textContents) free(textContents);
|
||||
for(std::pair<char*, char*> entry : values) {
|
||||
free(entry.first);
|
||||
free(entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
75
src/settings.h
Normal file
75
src/settings.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#pragma once
|
||||
#include "global.h"
|
||||
|
||||
namespace ini {
|
||||
|
||||
//Trims spaces, LF and CRLF
|
||||
static inline char* trimAndAllocate(const char* in, uint64_t len = 0) {
|
||||
if (!in) return nullptr;
|
||||
|
||||
uint64_t startingPos = 0, lastPos = 0;
|
||||
bool foundStart = false;
|
||||
for(int i = 0; ;i++) {
|
||||
char c = in[i];
|
||||
if ((len > 0 && startingPos == (len - 1)) || (len > 0 && lastPos == (len - 1))) return nullptr;
|
||||
if ((c != ' ' || c != '\r' || c != '\n') && !foundStart) {
|
||||
foundStart = true;
|
||||
lastPos = startingPos;
|
||||
}
|
||||
if (foundStart && (c == ' ' || c == '\r' || c == '\n')) {
|
||||
break;
|
||||
}
|
||||
if(!foundStart)
|
||||
startingPos++;
|
||||
else lastPos++;
|
||||
}
|
||||
if(!(lastPos - startingPos)) return nullptr;
|
||||
|
||||
char* trimmedString = (char*)calloc(lastPos - startingPos + 1, sizeof(char));
|
||||
memcpy(trimmedString, in + startingPos, lastPos - startingPos);
|
||||
return trimmedString;
|
||||
}
|
||||
|
||||
struct Djb12Hasher {
|
||||
size_t operator()(char* str) const {
|
||||
unsigned long hash = 5381;
|
||||
int c;
|
||||
|
||||
while (c = *str++)
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
struct StrcmpEqual {
|
||||
bool operator()(char* key1, char* key2) const {
|
||||
return (!strcmp(key1, key2));
|
||||
}
|
||||
};
|
||||
|
||||
class UserSettings {
|
||||
|
||||
public:
|
||||
UserSettings(char* path = nullptr);
|
||||
~UserSettings();
|
||||
|
||||
char* const getValue(char* key, uint64_t len = 0);
|
||||
void setValue(char* key, char* value, uint64_t valueSize, uint64_t keySize); //'\0' included
|
||||
void setValue(char* key, bool value, uint64_t keySize); //'\0' included
|
||||
//void setValue(char* key, uint64_t value, uint64_t valueSize, uint64_t keySize); //'\0' included
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
//void* returnValue();
|
||||
|
||||
//std::map<const char*, int> values{ {"show_channels", false}, {"test", 7} };
|
||||
std::unordered_map<char*, char*, Djb12Hasher, StrcmpEqual> values;
|
||||
char* textContents = nullptr;
|
||||
uint64_t textContentsSize = 0;
|
||||
char* pos = "true";
|
||||
char* neg = "false";
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue