Files
2026-08-24 10:03:24 +08:00

635 lines
17 KiB
C++

/*
* Copyright (c) 2014 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in the
* file 'LICENSE' which is part of this source code package.
*
* Description: c++ file
*/
#define LOG_MODULE_TAG "PQ"
#define LOG_CLASS_TAG "CConfigFile"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <ubootenv.h>
#include <sys/stat.h>
#include <algorithm>
#include "CPQLog.h"
#include "CConfigFile.h"
CConfigFile *CConfigFile::mInstance = NULL;
CConfigFile *CConfigFile::GetInstance()
{
if (NULL == mInstance) {
mInstance = new CConfigFile();
}
return mInstance;
}
CConfigFile::CConfigFile() : mpFirstLine(nullptr), mpFirstSection(nullptr)
{
GetCustomerFilePath(PQ_INI_PATH);
int ret = -1;
if (isFileExist(PQ_INI_PATH.c_str())) {
ret = 0;
} else if (isFileExist(PQ_CONFIG_DEFAULT_PATH)) {
PQ_INI_PATH = PQ_CONFIG_DEFAULT_PATH;
ret = 0;
} else {
LOGE("no pq_default.ini in %s\n", PQ_CONFIG_DEFAULT_PATH);
}
if (ret == 0) {
LoadFromFile(PQ_INI_PATH.c_str());
}
}
CConfigFile::~CConfigFile()
{
LOGD("%s\n", __FUNCTION__);
FreeAllMem();
}
bool CConfigFile::isFileExist(const char *file_name)
{
struct stat tmp_st;
int ret = -1;
ret = stat(file_name, &tmp_st);
if (ret != 0 ) {
LOGE("%s don't exist!\n",file_name);
return false;
} else {
return true;
}
}
int CConfigFile::LoadFromFile(const char *filename)
{
char lineStr[MAX_CONFIG_FILE_LINE_LEN];
LINE *pCurLINE = NULL;
SECTION *pCurSection = NULL;
FreeAllMem();
if (filename == NULL) {
LOGE("%s: config file path is null!\n", __FUNCTION__);
return -1;
}
LOGD("LoadFromFile name = %s\n", filename);
if (strlen(filename) <= sizeof(mpFileName)/sizeof(char)) {
strcpy(mpFileName, filename);
}
if ((mpConfigFile = fopen (mpFileName, "r")) == NULL) {
LOGE("open %s fail!!!\n", filename);
return -1;
}
while (fgets (lineStr, MAX_CONFIG_FILE_LINE_LEN, mpConfigFile) != NULL) {
allTrim(lineStr);
LINE *pLINE = new LINE();
pLINE->pKeyStart = pLINE->Text;
pLINE->pKeyEnd = pLINE->Text;
pLINE->pValueStart = pLINE->Text;
pLINE->pValueEnd = pLINE->Text;
pLINE->pNext = NULL;
pLINE->type = getLineType(lineStr);
//LOGD("getline=%s len=%d type=%d", lineStr, strlen(lineStr), pLINE->type);
strcpy(pLINE->Text, lineStr);
pLINE->LineLen = strlen(pLINE->Text);
//head
if (mpFirstLine == NULL) {
mpFirstLine = pLINE;
} else {
pCurLINE->pNext = pLINE;
}
pCurLINE = pLINE;
switch (pCurLINE->type) {
case LINE_TYPE_SECTION: {
SECTION *pSec = new SECTION();
pSec->pLine = pLINE;
pSec->pNext = NULL;
if (mpFirstSection == NULL) { //first section
mpFirstSection = pSec;
} else {
pCurSection->pNext = pSec;
}
pCurSection = pSec;
break;
}
case LINE_TYPE_KEY: {
char *pM = strchr(pCurLINE->Text, '=');
pCurLINE->pKeyStart = pCurLINE->Text;
pCurLINE->pKeyEnd = pM - 1;
pCurLINE->pValueStart = pM + 1;
pCurLINE->pValueEnd = pCurLINE->Text + pCurLINE->LineLen - 1;
break;
}
case LINE_TYPE_COMMENT:
default:
break;
}
}
fclose (mpConfigFile);
mpConfigFile = NULL;
return 0;
}
int CConfigFile::SaveToFile(const char *filename)
{
const char *filepath = NULL;
FILE *pFile = NULL;
if (filename == NULL) {
if (strlen(mpFileName) == 0) {
LOGE("error save file is null.\n");
return -1;
} else {
filepath = mpFileName;
}
} else {
filepath = filename;
}
//LOGD("Save to file name = %s", file);
if ((pFile = fopen (filepath, "wb")) == NULL) {
LOGD("Save to file open error = %s", filepath);
return -1;
}
LINE *pCurLine = NULL;
for (pCurLine = mpFirstLine; pCurLine != NULL; pCurLine = pCurLine->pNext) {
fprintf (pFile, "%s\r\n", pCurLine->Text);
}
fflush(pFile);
fsync(fileno(pFile));
fclose(pFile);
return 0;
}
int CConfigFile::SetString(const char *section, const char *key, const char *value)
{
SECTION *pNewSec = NULL;
LINE *pNewSecLine = NULL;
LINE *pNewKeyLine = NULL;
SECTION *pSec = getSection(section);
if (pSec == NULL) {
pNewSec = new SECTION();
pNewSecLine = new LINE();
pNewKeyLine = new LINE();
pNewKeyLine->type = LINE_TYPE_KEY;
pNewSecLine->type = LINE_TYPE_SECTION;
sprintf(pNewSecLine->Text, "[%s]", section);
pNewSec->pLine = pNewSecLine;
InsertSection(pNewSec);
int keylen = strlen(key);
sprintf(pNewKeyLine->Text, "%s=%s", key, value);
pNewKeyLine->LineLen = strlen(pNewKeyLine->Text);
pNewKeyLine->pKeyStart = pNewKeyLine->Text;
pNewKeyLine->pKeyEnd = pNewKeyLine->pKeyStart + keylen - 1;
pNewKeyLine->pValueStart = pNewKeyLine->pKeyStart + keylen + 1;
pNewKeyLine->pValueEnd = pNewKeyLine->Text + pNewKeyLine->LineLen - 1;
InsertKeyLine(pNewSec, pNewKeyLine);
} else { //find section
LINE *pLine = getKeyLineAtSec(pSec, key);
if (pLine == NULL) { //, not find key
pNewKeyLine = new LINE();
pNewKeyLine->type = LINE_TYPE_KEY;
int keylen = strlen(key);
sprintf(pNewKeyLine->Text, "%s=%s", key, value);
pNewKeyLine->LineLen = strlen(pNewKeyLine->Text);
pNewKeyLine->pKeyStart = pNewKeyLine->Text;
pNewKeyLine->pKeyEnd = pNewKeyLine->pKeyStart + keylen - 1;
pNewKeyLine->pValueStart = pNewKeyLine->pKeyStart + keylen + 1;
pNewKeyLine->pValueEnd = pNewKeyLine->Text + pNewKeyLine->LineLen - 1;
InsertKeyLine(pSec, pNewKeyLine);
} else { //all find, change it
sprintf(pLine->Text, "%s=%s", key, value);
pLine->LineLen = strlen(pLine->Text);
pLine->pValueEnd = pLine->Text + pLine->LineLen - 1;
}
}
//save
SaveToFile(NULL);
return 0;
}
int CConfigFile::SetInt(const char *section, const char *key, int value)
{
char tmp[64];
sprintf(tmp, "%d", value);
SetString(section, key, tmp);
return 0;
}
const char *CConfigFile::GetString(const char *section, const char *key, const char *def_value)
{
SECTION *pSec = getSection(section);
if (pSec == NULL) {
return def_value;
}
LINE *pLine = getKeyLineAtSec(pSec, key);
if (pLine == NULL) {
return def_value;
}
return pLine->pValueStart;
}
int CConfigFile::GetInt(const char *section, const char *key, int def_value)
{
const char *num = GetString(section, key, NULL);
if (num != NULL) {
return atoi(num);
}
return def_value;
}
int CConfigFile::SetFloat(const char *section, const char *key, float value)
{
char tmp[64];
sprintf(tmp, "%.2f", value);
SetString(section, key, tmp);
return 0;
}
float CConfigFile::GetFloat(const char *section, const char *key, float def_value)
{
const char *num = GetString(section, key, NULL);
if (num != NULL) {
return atof(num);
}
return def_value;
}
LINE_TYPE CConfigFile::getLineType(char *Str)
{
LINE_TYPE type = LINE_TYPE_COMMENT;
if (strchr(Str, '#') != NULL) {
type = LINE_TYPE_COMMENT;
} else if ( (strstr (Str, "[") != NULL) && (strstr (Str, "]") != NULL) ) { /* Is Section */
type = LINE_TYPE_SECTION;
} else {
if (strstr (Str, "=") != NULL) {
type = LINE_TYPE_KEY;
} else {
type = LINE_TYPE_COMMENT;
}
}
return type;
}
void CConfigFile::FreeAllMem()
{
//line
LINE *pCurLine = NULL;
LINE *pNextLine = NULL;
for (pCurLine = mpFirstLine; pCurLine != NULL;) {
pNextLine = pCurLine->pNext;
delete pCurLine;
pCurLine = pNextLine;
}
mpFirstLine = NULL;
//section
SECTION *pCurSec = NULL;
SECTION *pNextSec = NULL;
for (pCurSec = mpFirstSection; pCurSec != NULL;) {
pNextSec = pCurSec->pNext;
delete pCurSec;
pCurSec = pNextSec;
}
mpFirstSection = NULL;
}
int CConfigFile::InsertSection(SECTION *pSec)
{
//insert it to sections list ,as first section
pSec->pNext = mpFirstSection;
mpFirstSection = pSec;
//insert it to lines list, at first
pSec->pLine->pNext = mpFirstLine;
mpFirstLine = pSec->pLine;
return 0;
}
int CConfigFile::InsertKeyLine(SECTION *pSec, LINE *line)
{
LINE *line1 = pSec->pLine;
LINE *line2 = line1->pNext;
line1->pNext = line;
line->pNext = line2;
return 0;
}
SECTION *CConfigFile::getSection(const char *section)
{
//section
for (SECTION *psec = mpFirstSection; psec != NULL; psec = psec->pNext) {
if (strncmp((psec->pLine->Text) + 1, section, strlen(section)) == 0)
return psec;
}
return NULL;
}
LINE *CConfigFile::getKeyLineAtSec(SECTION *pSec, const char *key)
{
//line
for (LINE *pline = pSec->pLine->pNext; (pline != NULL && pline->type != LINE_TYPE_SECTION); pline = pline->pNext) {
if (pline->type == LINE_TYPE_KEY) {
if (strncmp(pline->Text, key, strlen(key)) == 0) {
return pline;
}
}
}
return NULL;
}
void CConfigFile::allTrim(char *Str)
{
char *pStr;
pStr = strchr (Str, '\n');
if (pStr != NULL) {
*pStr = 0;
}
int Len = strlen(Str);
if ( Len > 0 ) {
if ( Str[Len - 1] == '\r' ) {
Str[Len - 1] = '\0';
}
}
pStr = Str;
while (*pStr != '\0') {
if (*pStr == ' ') {
char *pTmp = pStr;
while (*pTmp != '\0') {
*pTmp = *(pTmp + 1);
pTmp++;
}
} else {
pStr++;
}
}
return;
}
const char *CConfigFile::GetDatabaseFilePath(const char *section, const char *key, const char *def_value)
{
return GetString(section, key, def_value);
}
const char *CConfigFile::GetSettingDataFilePath(const char *section, const char *key, const char *def_value)
{
return GetString(section, key, def_value);
}
const char *CConfigFile::GetWhiteBalanceFilePath(const char *section, const char *key, const char *def_value)
{
return GetString(section, key, def_value);
}
const char *CConfigFile::GetFilePath(const char *section, const char *key, const char *def_value)
{
return GetString(section, key, def_value);
}
void CConfigFile::GetPqdbPath(char *file_path)
{
if (file_path == NULL)
return;
const char *config_value;
config_value = GetDatabaseFilePath(CFG_SECTION_PQ, CFG_PQ_DB_CONFIG_PATH, NULL);
if (!config_value) {
LOGD("%s: read pqconfig file path failed\n", __FUNCTION__);
snprintf(file_path, 128, "%s", PQ_DB_DEFAULT_PATH);
} else {
LOGD("%s: pqconfig file path is %s\n", __FUNCTION__, config_value);
snprintf(file_path, 128, "%s/pq.db", config_value);
}
return;
}
void CConfigFile::GetOverscandbPath(char *file_path)
{
if (file_path == NULL)
return;
const char *config_value;
config_value = GetDatabaseFilePath(CFG_SECTION_PQ, CFG_PQ_DB_CONFIG_PATH, NULL);
if (!config_value) {
LOGD("%s: read pqconfig file path failed\n", __FUNCTION__);
snprintf(file_path, 128, "%s", OVERSCAN_DB_DEFAULT_PATH);
} else {
LOGD("%s: pqconfig file path is %s\n", __FUNCTION__, config_value);
snprintf(file_path, 128, "%s/overscan.db", config_value);
}
return;
}
void CConfigFile::GetDvFilePath(char *bin_file_path, char *cfg_file_path)
{
//read dv file path from pq_default.ini
const char *pqdvbinPath = NULL;
pqdvbinPath = GetString(CFG_SECTION_PQ, CFG_PQ_DV_BIN_PATH, DV_BIN_FILE_DEFAULT_PATH);
if (isFileExist(pqdvbinPath)) {
strcpy(bin_file_path, pqdvbinPath);
} else if (isFileExist(DV_BIN_FILE_DEFAULT_PATH)) {
strcpy(bin_file_path, DV_BIN_FILE_DEFAULT_PATH);
} else {
LOGE("no dv_config.bin in %s\n", DV_BIN_FILE_DEFAULT_PATH);
}
LOGD("bin_file_path is %s\n", bin_file_path);
const char *pqdvcfgPath = NULL;
pqdvcfgPath = GetString(CFG_SECTION_PQ, CFG_PQ_DV_CFG_PATH, DV_CFG_FILE_DEFAULT_PATH);
if (isFileExist(pqdvcfgPath)) {
strcpy(cfg_file_path, pqdvcfgPath);
} else if (isFileExist(DV_CFG_FILE_DEFAULT_PATH)) {
strcpy(cfg_file_path, DV_CFG_FILE_DEFAULT_PATH);
} else {
LOGE("no Amlogic_dv.cfg in %s\n", DV_CFG_FILE_DEFAULT_PATH);
}
LOGD("pqdvcfgPath is %s\n", pqdvcfgPath);
}
void CConfigFile::GetLdimBinPath(char *file_path)
{
const char *ldimBinConfigPath = NULL;
if (!mLocalDimmingBinPth.empty()) {
ldimBinConfigPath = mLocalDimmingBinPth.c_str();
} else {
ldimBinConfigPath = GetString(CFG_SECTION_PQ, CFG_PQ_LDIM_BIN_PATH, LDIM_BIN_DEFAULT_PATH);
}
LOGE("ldimBinConfigPath %s\n", ldimBinConfigPath);
if (isFileExist(ldimBinConfigPath)) {
LOGI("Get ldimBinConfigPath %s!\n", ldimBinConfigPath);
} else if (isFileExist(LDIM_BIN_DEFAULT_PATH)) {
ldimBinConfigPath = LDIM_BIN_DEFAULT_PATH;
} else {
LOGE("no ldim.bin\n");
}
strcpy(file_path, ldimBinConfigPath);
if (!mLocalDimmingBinPth.empty()) {
mLocalDimmingBinPth.clear();
}
}
bool CConfigFile::get_panel_name(std::string& panel_id)
{
#if 1 //get uboot env by -lubootenv
if (bootenv_init() < 0) {
LOGE("%s bootenv_init fail\n", __FUNCTION__);
}
const char *model_name = bootenv_get(UBOOT_MODEL_NAME);
#else //get uboot env from recipes EnvironmentFile
const char* model_name = getenv(UBOOT_MODEL_NAME);
#endif
if (!model_name) {
LOGD("%s get env model_name fail, using default: %s\n", __FUNCTION__, MODEL_NAME_DEFAULT);
panel_id = MODEL_NAME_DEFAULT;
} else {
panel_id = model_name;
}
LOGD("get panel name from uboot env [model_name]: %s\n", panel_id.c_str());
return true;
}
bool CConfigFile::get_File_name(std::string& file_name, const std::string& panel_id)
{
if (panel_id.empty()) {
LOGE("panel_id is empty\n");
return false;
}
std::string file_path = std::string(PANEL_INI_PATH) + "/model_sum.ini";
if (!isFileExist(file_path.c_str())) {
LOGE("File: %s is not Exist\n", file_path.c_str());
return false;
}
if (LoadFromFile(file_path.c_str()) < 0) {
LOGE("LoadFromFile %s fail\n", file_path.c_str());
return false;
}
const char *ini_path = GetString(panel_id.c_str(), "PQINI_PATH", NULL);
if (ini_path == NULL) {
LOGE("can not get PQINI_PATH in item[%s]\n", panel_id.c_str());
return false;
}
file_name = ini_path;
//ldim
const char *ldim_path = GetString(panel_id.c_str(), "LDIMPQ_PATH", NULL);
if (ldim_path != NULL) {
mLocalDimmingBinPth = ldim_path;
LOGI("mLocalDimmingBinPth: %s!\n", mLocalDimmingBinPth.c_str());
} else {
mLocalDimmingBinPth.clear();
}
return true;
}
bool CConfigFile::get_File_name0(std::string& file_name, const std::string& panel_id)
{
if (panel_id.empty()) {
LOGE("panel_id is empty\n");
return false;
}
std::string file_path = std::string(PANEL_INI_PATH) + "/Project_index_" + panel_id + ".ini";
if (!isFileExist(file_path.c_str())) {
LOGE("File: %s is not Exist\n", file_path.c_str());
return false;
}
if (LoadFromFile(file_path.c_str()) < 0) {
LOGE("LoadFromFile %s fail\n", file_path.c_str());
return false;
}
const char *ini_path = GetString("GENERAL_CONFIG_FROM_MODEL_SUM", "PQINI_PATH", NULL);
if (ini_path == NULL) {
LOGE("can not get PQINI_PATH in item[%s]\n", "GENERAL_CONFIG_FROM_MODEL_SUM");
return false;
}
file_name = ini_path;
//ldim
const char *ldim_path = GetString(panel_id.c_str(), "LDIMPQ_PATH", NULL);
if (ldim_path != NULL) {
mLocalDimmingBinPth = ldim_path;
LOGI("mLocalDimmingBinPth: %s!\n", mLocalDimmingBinPth.c_str());
} else {
mLocalDimmingBinPth.clear();
}
return true;
}
bool CConfigFile::GetCustomerFilePath(std::string& file_path)
{
std::string model_name;
if (!get_panel_name(model_name)) {
LOGE("get_panel_name fail\n");
return false;
}
model_name.erase(std::remove_if(model_name.begin(), model_name.end(),
[](char c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\f';
}),
model_name.end());
std::string ini_file_name;
if (!get_File_name(ini_file_name, model_name)) {
if (!get_File_name0(ini_file_name, model_name)) {
LOGD("get_File_name: fail\n");
return false;
}
}
file_path = std::move(ini_file_name);
LOGE("get_File_name %s", file_path.c_str());
return true;
}