mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-09-19 20:47:14 +00:00
98 lines
2.8 KiB
C++
98 lines
2.8 KiB
C++
#include "DynamicConfigSerializer.h"
|
|
#include <Utils.h>
|
|
|
|
#define PROP_SEP_CHAR '|'
|
|
#define PROP_SEP_STR "|"
|
|
#define KEY_SEP_CHAR ':'
|
|
#define KEY_SEP_STR ":"
|
|
|
|
bool DynamicConfigSerializer::setByKeyPrv(const char* key, const char* value) {
|
|
if (_fallback && _fallback->setByKey(key, value)) return true;
|
|
|
|
// TODO: guard for bad chars (':' or '|')
|
|
char tmp[MAX_DYNAMIC_CONFG];
|
|
strcpy(tmp, _config); // make a (modifiable) copy
|
|
|
|
const char* parts[8];
|
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
|
|
|
// add/replace in _config[]
|
|
char new_config[MAX_DYNAMIC_CONFG];
|
|
new_config[0] = 0;
|
|
|
|
int keylen = strlen(key);
|
|
for (int i = 0; i < n; i++) {
|
|
const char* item = parts[i];
|
|
if (item[keylen] == KEY_SEP_CHAR && memcmp(item, key, keylen) == 0) {
|
|
// key exists, so omit old value from this pass (will append new value at end)
|
|
} else {
|
|
if (new_config[0]) {
|
|
strcat(new_config, PROP_SEP_STR);
|
|
}
|
|
strcat(new_config, item);
|
|
}
|
|
}
|
|
// now append new key/value (if it fits)
|
|
if (strlen(new_config) + strlen(key) + strlen(value) + 2 < sizeof(_config)-1) {
|
|
if (new_config[0]) {
|
|
strcat(new_config, PROP_SEP_STR);
|
|
}
|
|
strcat(new_config, key);
|
|
strcat(new_config, KEY_SEP_STR);
|
|
strcat(new_config, value);
|
|
strcpy(_config, new_config); // commit new serialized string
|
|
return true;
|
|
}
|
|
return false; // didn't fit in _config[]
|
|
}
|
|
|
|
bool DynamicConfigSerializer::setByKey(const char* key, const char* value) {
|
|
if (setByKeyPrv(key, value)) {
|
|
markDirty();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DynamicConfigSerializer::getByKey(const char* key, char* value, size_t max_len) {
|
|
if (_fallback && _fallback->getByKey(key, value, max_len)) return true;
|
|
|
|
char tmp[MAX_DYNAMIC_CONFG];
|
|
strcpy(tmp, _config); // make a (modifiable) copy
|
|
|
|
const char* parts[8];
|
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
|
|
|
int keylen = strlen(key);
|
|
for (int i = 0; i < n; i++) {
|
|
const char* item = parts[i];
|
|
if (item[keylen] == KEY_SEP_CHAR && memcmp(item, key, keylen) == 0) {
|
|
strncpy(value, &item[keylen+1], max_len);
|
|
value[max_len] = 0;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DynamicConfigSerializer::structure() {
|
|
if (_context->op() == OP::WRITE) {
|
|
char tmp[MAX_DYNAMIC_CONFG];
|
|
strcpy(tmp, _config); // make a (modifiable) copy
|
|
|
|
const char* parts[8];
|
|
int n = mesh::Utils::parseTextParts(tmp, parts, 8, PROP_SEP_CHAR);
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
char* item = (char *) parts[i];
|
|
char* eq = strchr(item, KEY_SEP_CHAR);
|
|
if (eq) {
|
|
*eq = 0; // replace separator with null terminator
|
|
def(item, eq + 1, MAX_DYNAMIC_CONFG/2);
|
|
}
|
|
}
|
|
} else {
|
|
setByKeyPrv(_context->getKey(getDepth()), _context->getToken());
|
|
}
|
|
}
|