/* * 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 #include #include #include #include #include #include #include #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; }