code_app/base/HGUtility.cpp

730 lines
15 KiB
C++
Raw Normal View History

2022-05-03 10:25:52 +00:00
#include "HGUtility.h"
#include "HGInc.h"
#if defined(HG_CMP_MSC)
#include <shlobj.h>
#include <atlstr.h>
#else
#include <uuid/uuid.h>
#endif
#include <vector>
#include <string>
HGResult HGAPI HGBase_GetTmpPath(HGChar* path, HGUInt maxLen)
{
if (NULL == path || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
char tmpPath[512] = {0};
strcpy(tmpPath, "/tmp/");
#else
CHAR tmpPath[MAX_PATH] = { 0 };
DWORD len = GetTempPathA(MAX_PATH, tmpPath);
if (0 == len)
return HGBASE_ERR_FAIL;
if (tmpPath[strlen(tmpPath) - 1] != '\\')
strcat(tmpPath, "\\");
#endif
if (maxLen < strlen(tmpPath) + 1)
return HGBASE_ERR_FAIL;
strcpy(path, tmpPath);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetCurrentDir(HGChar* dir, HGUInt maxLen)
{
if (NULL == dir || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
char buffer[512] = { 0 };
char* p = getcwd(buffer, 512);
if (NULL == p)
return HGBASE_ERR_FAIL;
if (buffer[strlen(buffer) - 1] != '/')
strcat(buffer, "/");
#else
CHAR buffer[MAX_PATH] = { 0 };
DWORD len = GetCurrentDirectoryA(MAX_PATH, buffer);
if (0 == len)
return HGBASE_ERR_FAIL;
if (buffer[strlen(buffer) - 1] != '\\')
strcat(buffer, "\\");
#endif
if (maxLen < strlen(buffer) + 1)
return HGBASE_ERR_FAIL;
strcpy(dir, buffer);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_SetCurrentDir(const HGChar* dir)
{
if (NULL == dir)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
if (0 != chdir(dir))
return HGBASE_ERR_FAIL;
#else
if (!SetCurrentDirectoryA(dir))
return HGBASE_ERR_FAIL;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CreateDir(const HGChar* dir)
{
if (NULL == dir)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
bool ret = true;
char muldir[512] = { 0 };
strcpy(muldir, dir);
for (size_t i = 0; i < strlen(muldir); ++i)
{
if ('/' == muldir[i])
{
muldir[i] = '\0';
if ('\0' != *muldir && 0 != access(muldir, 0))
{
if (0 != mkdir(muldir, 0777))
{
ret = false;
break;
}
}
muldir[i] = '/';
}
}
if (ret)
{
if ('\0' != *muldir && 0 != access(muldir, 0))
{
if (0 != mkdir(muldir, 0777))
{
ret = false;
}
}
}
if (!ret)
return HGBASE_ERR_FAIL;
#else
if (ERROR_SUCCESS != SHCreateDirectoryExA(NULL, dir, NULL))
return HGBASE_ERR_FAIL;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_DeleteDir(const HGChar* dir)
{
if (NULL == dir)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
if (0 != rmdir(dir))
return HGBASE_ERR_FAIL;
#else
if (!RemoveDirectoryA(dir))
return HGBASE_ERR_FAIL;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_DeleteFile(const HGChar* fileName)
{
if (NULL == fileName)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
if (0 != unlink(fileName))
return HGBASE_ERR_FAIL;
#else
if (!DeleteFileA(fileName))
return HGBASE_ERR_FAIL;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetModuleName(HGPointer addr, HGChar* name, HGUInt maxLen)
{
if (NULL == name || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
Dl_info dlinfo;
if (0 == dladdr(addr, &dlinfo))
return HGBASE_ERR_FAIL;
if (maxLen < strlen(dlinfo.dli_fname) + 1)
return HGBASE_ERR_FAIL;
strcpy(name, dlinfo.dli_fname);
#else
HMODULE hModule = NULL;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)addr, &hModule);
if (NULL == hModule)
return HGBASE_ERR_FAIL;
CHAR moduleName[MAX_PATH] = { 0 };
DWORD len = GetModuleFileNameA(hModule, moduleName, MAX_PATH);
if (0 == len || maxLen < strlen(moduleName) + 1)
return HGBASE_ERR_FAIL;
strcpy(name, moduleName);
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetUuid(HGChar* uuid, HGUInt maxLen)
{
if (NULL == uuid || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
uuid_t id;
uuid_generate(id);
char str[128] = {0};
uuid_unparse(id, str);
if (maxLen < strlen(str) + 1)
return HGBASE_ERR_FAIL;
strcpy(uuid, str);
#else
GUID guid;
if (S_OK != CoCreateGuid(&guid))
return HGBASE_ERR_FAIL;
char str[128] = {0};
sprintf(str, "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
if (maxLen < strlen(str) + 1)
return HGBASE_ERR_FAIL;
strcpy(uuid, str);
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetTmpFileName(HGChar* fileName, HGUInt maxLen)
{
if (NULL == fileName || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
HGChar path[256] = { 0 }, uuid[128] = {0};
HGBase_GetTmpPath(path, 256);
HGBase_GetUuid(uuid, 128);
strcat(path, uuid);
if (maxLen < strlen(path) + 1)
return HGBASE_ERR_FAIL;
strcpy(fileName, path);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetConfigPath(HGChar* configPath, HGUInt maxLen)
{
if (NULL == configPath || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
CHAR cfgPath[MAX_PATH] = { 0 };
BOOL ret = SHGetSpecialFolderPathA(NULL, cfgPath, CSIDL_APPDATA, FALSE);
if (!ret)
return HGBASE_ERR_FAIL;
if (cfgPath[strlen(cfgPath) - 1] != '\\')
strcat(cfgPath, "\\");
strcat(cfgPath, "HuaGo\\Cfg\\");
#else
char cfgPath[512] = { 0 };
strcpy(cfgPath, getenv("HOME"));
if (cfgPath[strlen(cfgPath) - 1] != '/')
strcat(cfgPath, "/");
strcat(cfgPath, ".HuaGo/Cfg/");
#endif
if (maxLen < strlen(cfgPath) + 1)
return HGBASE_ERR_FAIL;
strcpy(configPath, cfgPath);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetLogFilePath(HGChar* logFilePath, HGUInt maxLen)
{
if (NULL == logFilePath || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
CHAR logPath[MAX_PATH] = { 0 };
BOOL ret = SHGetSpecialFolderPathA(NULL, logPath, CSIDL_APPDATA, FALSE);
if (!ret)
return HGBASE_ERR_FAIL;
if (logPath[strlen(logPath) - 1] != '\\')
strcat(logPath, "\\");
strcat(logPath, "HuaGo\\Log\\");
#else
char logPath[512] = { 0 };
strcpy(logPath, getenv("HOME"));
if (logPath[strlen(logPath) - 1] != '/')
strcat(logPath, "/");
strcat(logPath, ".HuaGo/Log/");
#endif
if (maxLen < strlen(logPath) + 1)
return HGBASE_ERR_FAIL;
strcpy(logFilePath, logPath);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetDocumentsPath(HGChar* documentsPath, HGUInt maxLen)
{
if (NULL == documentsPath || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
CHAR docPath[MAX_PATH] = { 0 };
BOOL ret = SHGetSpecialFolderPathA(NULL, docPath, CSIDL_MYDOCUMENTS, FALSE);
if (!ret)
return HGBASE_ERR_FAIL;
if (docPath[strlen(docPath) - 1] != '\\')
strcat(docPath, "\\");
#else
char docPath[512] = { 0 };
strcpy(docPath, getenv("HOME"));
if (docPath[strlen(docPath) - 1] != '/')
strcat(docPath, "/");
strcat(docPath, "Documents/");
#endif
if (maxLen < strlen(docPath) + 1)
return HGBASE_ERR_FAIL;
strcpy(documentsPath, docPath);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetProcessName(HGChar* name, HGUInt maxLen)
{
if (NULL == name || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
CHAR moduleName[MAX_PATH] = { 0 };
DWORD len = GetModuleFileNameA(NULL, moduleName, MAX_PATH);
if (0 == len)
return HGBASE_ERR_FAIL;
CStringA strModuleName(moduleName);
strModuleName = strModuleName.Right(strModuleName.GetLength() - strModuleName.ReverseFind('\\') - 1);
strModuleName = strModuleName.Left(strModuleName.ReverseFind('.'));
if (maxLen < (HGUInt)strModuleName.GetLength() + 1)
return HGBASE_ERR_FAIL;
strcpy(name, strModuleName);
#else
char aucPathBuf[1024] = { 0 };
if (readlink("/proc/self/exe", aucPathBuf, 1024) <= 0)
return HGBASE_ERR_FAIL;
const char* pcName = strrchr(aucPathBuf, '/');
if (NULL == pcName)
return HGBASE_ERR_FAIL;
++pcName;
if (maxLen < strlen(pcName) + 1)
return HGBASE_ERR_FAIL;
strcpy(name, pcName);
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetFileName(const HGChar* filePath, HGChar* name, HGUInt maxLen)
{
if (NULL == filePath || NULL == name || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
const char* pcName = strrchr(filePath, '\\');
if (NULL == pcName)
{
pcName = strrchr(filePath, '/');
if (NULL == pcName)
return HGBASE_ERR_FAIL;
}
#else
const char* pcName = strrchr(filePath, '/');
if (NULL == pcName)
return HGBASE_ERR_FAIL;
#endif
++pcName;
if (maxLen < strlen(pcName) + 1)
return HGBASE_ERR_FAIL;
strcpy(name, pcName);
return HGBASE_ERR_OK;
}
static int IniWriteValue(const char* section, const char* key, const char* val, const char* file)
{
typedef std::vector<std::pair<std::string, std::string> > KeyList;
typedef std::vector<std::pair<std::string, KeyList> > SectionList;
SectionList sectList;
FILE* fp = fopen(file, "r");
if (fp != NULL)
{
KeyList* pCurKeyList = NULL;
while (feof(fp) == 0)
{
char lineContent[256] = { 0 };
if (NULL == fgets(lineContent, 256, fp))
{
continue;
}
if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
{
continue;
}
for (size_t i = 0; i < strlen(lineContent); ++i)
{
if (lineContent[i] == '\r' || lineContent[i] == '\n')
{
lineContent[i] = '\0';
break;
}
}
if (lineContent[0] == '[')
{
std::pair<std::string, KeyList> pr;
pr.first = lineContent;
sectList.push_back(pr);
pCurKeyList = &sectList[sectList.size() - 1].second;
}
else
{
int pos = -1;
for (int i = 0; i < (int)strlen(lineContent); ++i)
{
if (lineContent[i] == '=')
{
pos = i;
break;
}
}
if (NULL != pCurKeyList)
{
std::pair<std::string, std::string> pr;
if (-1 != pos)
{
pr.first.assign(lineContent, pos);
pr.second.assign(lineContent + pos + 1);
}
else
{
pr.first = lineContent;
}
pCurKeyList->push_back(pr);
}
}
}
fclose(fp);
}
bool bFindSect = false;
for (size_t i = 0; i < sectList.size(); ++i)
{
if (strncmp(sectList[i].first.c_str(), section, strlen(section)) == 0)
{
bool bFindKey = false;
for (size_t j = 0; j < sectList[i].second.size(); ++j)
{
if (strncmp(sectList[i].second[j].first.c_str(), key, strlen(key)) == 0)
{
sectList[i].second[j].second = val;
bFindKey = true;
break;
}
}
if (!bFindKey)
{
std::pair<std::string, std::string> pr;
pr.first = key;
pr.second = val;
sectList[i].second.push_back(pr);
}
bFindSect = true;
break;
}
}
if (!bFindSect)
{
std::pair<std::string, KeyList> pr;
pr.first = section;
std::pair<std::string, std::string> pr2;
pr2.first = key;
pr2.second = val;
pr.second.push_back(pr2);
sectList.push_back(pr);
}
fp = fopen(file, "w");
if (fp == NULL)
{
return -1;
}
for (size_t i = 0; i < sectList.size(); ++i)
{
fputs(sectList[i].first.c_str(), fp);
fputs("\n", fp);
for (size_t j = 0; j < sectList[i].second.size(); ++j)
{
fputs(sectList[i].second[j].first.c_str(), fp);
fputs("=", fp);
fputs(sectList[i].second[j].second.c_str(), fp);
fputs("\n", fp);
}
}
fclose(fp);
return 0;
}
static int writeStringValue(const char* section, const char* key, const char* val, const char* file)
{
if (section == NULL || key == NULL || val == NULL || file == NULL)
{
return -1;
}
char sect[256];
sprintf(sect, "[%s]", section);
return IniWriteValue(sect, key, val, file);
}
HGResult HGAPI HGBase_SetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt value)
{
if (NULL == fileName || NULL == appName || NULL == keyName)
{
return HGBASE_ERR_INVALIDARG;
}
char str[8];
sprintf(str, "%d", value);
if (0 != writeStringValue(appName, keyName, str, fileName))
return HGBASE_ERR_FAIL;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_SetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar* value)
{
if (NULL == fileName || NULL == appName || NULL == keyName)
{
return HGBASE_ERR_INVALIDARG;
}
if (0 != writeStringValue(appName, keyName, value, fileName))
return HGBASE_ERR_FAIL;
return HGBASE_ERR_OK;
}
static int IniReadValue(const char* section, const char* key, char* val, const char* def, const char* file)
{
FILE* fp = fopen(file, "r");
if (fp == NULL)
{
strcpy(val, def);
return -1;
}
bool ret = false;
while (feof(fp) == 0)
{
char lineContent[256] = { 0 };
if (NULL == fgets(lineContent, 256, fp))
{
continue;
}
if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
{
continue;
}
//check section
if (strncmp(lineContent, section, strlen(section)) == 0)
{
while (feof(fp) == 0)
{
char lineContent[256] = { 0 };
if (NULL == fgets(lineContent, 256, fp))
{
continue;
}
//check key
if (strncmp(lineContent, key, strlen(key)) == 0)
{
size_t pos = 0;
for (pos = strlen(key); pos < strlen(lineContent); ++pos)
{
if (lineContent[pos] == '=')
{
break;
}
}
if (pos >= strlen(lineContent))
{
break;
}
strcpy(val, lineContent + pos + 1);
for (size_t j = 0; j < strlen(val); ++j)
{
if ((val[j] == '\r') || (val[j] == '\n'))
{
val[j] = '\0';
break;
}
}
ret = true;
}
else if (lineContent[0] == '[')
{
break;
}
}
break;
}
}
if (!ret)
{
strcpy(val, def);
}
fclose(fp);
return 0;
}
static int readStringValue(const char* section, const char* key, char* val, const char* def, const char* file)
{
if (section == NULL || key == NULL || val == NULL || def == NULL || file == NULL)
{
return -1;
}
char sect[256];
sprintf(sect, "[%s]", section);
return IniReadValue(sect, key, val, def, file);
}
HGResult HGAPI HGBase_GetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt def, HGInt* value)
{
if (NULL == appName || NULL == keyName || NULL == value)
{
return HGBASE_ERR_INVALIDARG;
}
char strRet[256] = { 0 };
char strDef[32];
sprintf(strDef, "%d", def);
readStringValue(appName, keyName, strRet, strDef, fileName);
*value = atoi(strRet);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_GetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar* def, HGChar* value, HGUInt maxLen)
{
if (NULL == appName || NULL == keyName || NULL == value)
{
return HGBASE_ERR_INVALIDARG;
}
readStringValue(appName, keyName, value, def, fileName);
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_StandardiseFileName(const HGChar* fileName, HGChar* result, HGUInt maxLen)
{
if (NULL == fileName || NULL == result || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
CStringA strResult;
bool separator = false;
for (const HGChar* p = fileName; *p != 0; ++p)
{
if (*p == '\\' || *p == '/')
{
if (!separator)
{
strResult.AppendChar('\\');
separator = true;
}
}
else
{
strResult.AppendChar(tolower(*p));
separator = false;
}
}
if (maxLen < (HGUInt)strResult.GetLength() + 1)
return HGBASE_ERR_FAIL;
strcpy(result, strResult);
#else
if (maxLen < (HGUInt)strlen(fileName) + 1)
return HGBASE_ERR_FAIL;
strcpy(result, fileName);
#endif
return HGBASE_ERR_OK;
}