Files
hardware_samsung-extra_inte…/aidl/battery/default/JSONParser.cpp

137 lines
3.8 KiB
C++

#include "JSONParser.hpp"
#include <android-base/logging.h>
#include <initializer_list>
#include <fstream>
#include <functional>
#include <map>
#include <string>
#include <vector>
void ConfigParser::handler_OpenFile(const std::string &node,
const std::string &data) {
LOG(DEBUG) << "Opening file: " << data;
std::ifstream file(node);
std::string line;
if (file) {
file >> line;
} else {
PLOG(ERROR) << "Failed to read file";
}
}
void ConfigParser::handler_WriteFile(const std::string &node,
const std::string &data) {
LOG(DEBUG) << "Writing to file: " << data;
std::ofstream file(node);
if (file) {
file << data;
} else {
PLOG(ERROR) << "Failed to write to file";
}
}
// Returns a pair with the matching device and its match quality.
std::pair<Json::Value, ConfigParser::MatchQuality>
ConfigParser::lookupEntry(const SearchEntry &search) {
std::pair<Json::Value, MatchQuality> current = {root, MatchQuality::NO_MATCH};
for (const auto &devices : root) {
if (devices["codename"].asString() == search.codename) {
current = {devices, MatchQuality::EXACT};
break;
}
if (devices["vendor"].asString() == search.vendor) {
current = {devices, MatchQuality::MATCHES_VENDOR};
}
}
if (current.second == MatchQuality::NO_MATCH) {
LOG(ERROR) << "No matching device found";
return current;
}
LOG(DEBUG) << "Found a match with quality: ";
switch (current.second) {
case MatchQuality::EXACT:
LOG(DEBUG) << "EXACT";
break;
case MatchQuality::MATCHES_VENDOR:
LOG(DEBUG) << "MATCHES_VENDOR";
break;
case MatchQuality::NO_MATCH:
break;
};
return current;
}
ConfigParser::ConfigParser(const std::string &path) {
std::ifstream file(path);
if (!file.is_open()) {
PLOG(ERROR) << "Failed to open file";
return;
}
file >> root;
}
std::function<void(bool)> ConfigParser::findEntry(const SearchEntry &search) {
constexpr int ENABLE_FN_INDEX = 0;
constexpr int DISABLE_FN_INDEX = 1;
std::array<std::function<void(void)>, 2> handlers;
const auto current = lookupEntry(search);
if (current.second == MatchQuality::NO_MATCH) {
return [](bool) {};
}
for (const auto &action : current.first["actions"]) {
if (!action["action"].isString()) {
LOG(ERROR) << "Invalid action type";
return [](bool) {};
}
const std::string actionType = action["action"].asString();
const std::string node = action["node"].asString();
const std::string handlerName = action["handler"].asString();
const std::string handlerData = action["handler_data"].asString();
if (actionType == "enable") {
for (const auto &handler : m_handlers) {
if (handler.first == handlerName) {
handlers[ENABLE_FN_INDEX] = [callback = handler.second, node,
handlerData]() {
callback(node, handlerData);
};
break;
}
}
if (!handlers[ENABLE_FN_INDEX]) {
LOG(ERROR) << "No handlers found for enable action";
return [](bool) {};
}
} else if (actionType == "disable") {
for (const auto &handler : m_handlers) {
if (handler.first == handlerName) {
handlers[DISABLE_FN_INDEX] = [callback = handler.second, node,
handlerData]() {
callback(node, handlerData);
};
break;
}
}
if (!handlers[DISABLE_FN_INDEX]) {
LOG(ERROR) << "No handlers found for disable action";
return [](bool) {};
}
} else {
LOG(ERROR) << "Invalid action type";
return [](bool) {};
}
}
return [handlers](bool enable) {
if (enable) {
handlers[ENABLE_FN_INDEX]();
} else {
handlers[DISABLE_FN_INDEX]();
}
};
}