Files
2025-09-03 09:34:30 +08:00

299 lines
7.3 KiB
C++

#include "libNPK_StdAfx.h"
#include "libNPK_Utils.h"
std::string sizeToString(int64_t s)
{
char temp[64] = { 0 };
static const int64_t KB = 1024;
static const int64_t MB = 1024 * 1024;
static const int64_t GB = 1024 * 1024 * 1024;
if (s < KB) {
std::snprintf(temp, 64, "%zu ", s);
}
else if (s < MB) {
std::snprintf(temp, 64, "%.2f KB", (float)s / (float)(KB));
}
else if (s < GB) {
std::snprintf(temp, 64, "%.2f MB", (float)s / (float)(MB));
}
else {
std::snprintf(temp, 64, "%.2f GB", (float)s / (float)(GB));
}
return std::string(temp);
}
int64_t sizeFromString(const char* sizeStr)
{
if (!sizeStr || !*sizeStr) {
return 0;
}
char* endPtr = nullptr;
int64_t size = strtoull(sizeStr, &endPtr, 10);
if (endPtr && *endPtr) {
switch (*endPtr) {
case 'k':
case 'K':
size *= 1024;
break;
case 'm':
case 'M':
size *= 1024 * 1024;
break;
case 'g':
case 'G':
size *= 1024 * 1024 * 1024;
break;
}
}
return size;
}
int compareTwoFileName(const char* szFileName1, const char* szFileName2)
{
char szTempFileName1[MAX_PATH] = { 0 };
char szTempFileName2[MAX_PATH] = { 0 };
StringCchPrintfA(szTempFileName1, MAX_PATH, "%s", szFileName1);
StringCchPrintfA(szTempFileName2, MAX_PATH, "%s", szFileName2);
PathRemoveBlanksA(szTempFileName1);
PathRemoveBlanksA(szTempFileName2);
PathRemoveBackslashA(szTempFileName1);
PathRemoveBackslashA(szTempFileName2);
int nRet = _stricmp(szTempFileName1, szTempFileName2);
if (nRet == 0) return 0;
char szShortFileName1[MAX_PATH] = { 0 };
char szShortFileName2[MAX_PATH] = { 0 };
if (GetShortPathNameA(szTempFileName1, szShortFileName1, MAX_PATH))
{
StringCchCopyA(szTempFileName1, MAX_PATH, szShortFileName1);
}
if (GetShortPathNameA(szTempFileName2, szShortFileName2, MAX_PATH))
{
StringCchCopyA(szTempFileName2, MAX_PATH, szShortFileName2);
}
return _stricmp(szTempFileName1, szTempFileName2);
}
// Convert a standard ANSI string to a wide string (UTF-16)
std::wstring convertAnsiStringToWide(const char* szSource)
{
const static int DEFAULT_WCHAR_BUF_SIZE = 1024;
wchar_t DEFAULT_WCHAR_BUF[DEFAULT_WCHAR_BUF_SIZE] = { 0 };
if (szSource == 0 || szSource[0] == 0) return std::wstring(L"");
int32_t sourceLen = (int32_t)strlen(szSource) + 1;
int32_t targetLen = sourceLen + 32;
wchar_t* wszTemp = 0;
if (targetLen >= DEFAULT_WCHAR_BUF_SIZE)
wszTemp = new wchar_t[targetLen];
else
wszTemp = DEFAULT_WCHAR_BUF;
::MultiByteToWideChar(CP_ACP, 0, szSource, sourceLen, wszTemp, targetLen);
std::wstring strReturn(wszTemp);
if (wszTemp != DEFAULT_WCHAR_BUF) delete[] wszTemp;
return strReturn;
}
std::string convertWideStringToUtf8(const wchar_t* source)
{
const static int DEFAULT_CHAR_BUF_SIZE = 1024;
char DEFAULT_CHAR_BUF[DEFAULT_CHAR_BUF_SIZE] = { 0 };
if(source==nullptr || source[0]==L'\0')
return std::string();
int targetLen = WideCharToMultiByte(CP_UTF8, 0, source, -1, nullptr, 0, nullptr, nullptr);
if (targetLen == 0)
return std::string();
char* szTemp = 0;
if (targetLen >= DEFAULT_CHAR_BUF_SIZE)
szTemp = new char[targetLen];
else
szTemp = DEFAULT_CHAR_BUF;
WideCharToMultiByte(CP_UTF8, 0, source, -1, szTemp, targetLen, nullptr, nullptr);
return std::string(szTemp);
}
std::wstring convertUtf8StringToWide(const char* source)
{
const static int DEFAULT_WCHAR_BUF_SIZE = 1024;
wchar_t DEFAULT_WCHAR_BUF[DEFAULT_WCHAR_BUF_SIZE] = { 0 };
if (source == nullptr || source[0] == '\0')
return std::wstring();
int targetLen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, source, -1, nullptr, 0);
if (targetLen == 0)
return std::wstring();
wchar_t* wszTemp = 0;
if (targetLen >= DEFAULT_WCHAR_BUF_SIZE)
wszTemp = new wchar_t[targetLen];
else
wszTemp = DEFAULT_WCHAR_BUF;
int result = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, source, -1, wszTemp, targetLen);
return std::wstring(wszTemp);
}
uint8_t* readFileToBuffer(const char* filename, int64_t& outSize)
{
FILE* file = nullptr;
fopen_s(&file, filename, "rb");
if (!file)
{
printf("Error: Could not open file %s\n", filename);
return nullptr; // Failed to open file
}
fseek(file, 0, SEEK_END);
outSize = (int64_t)ftell(file);
fseek(file, 0, SEEK_SET);
uint8_t* buffer = new uint8_t[outSize + 1];
if (outSize != fread(buffer, 1, outSize, file))
{
printf("Error: Failed to read file %s\n", filename);
delete[] buffer;
fclose(file);
return nullptr; // Failed to read file
}
fclose(file);
buffer[outSize] = '\0'; // Null-terminate the buffer
return buffer;
}
void freeFileBuffer(uint8_t* buffer)
{
if (buffer == nullptr) return;
delete[] buffer;
}
bool clearPath(const wchar_t* szPath, bool recursion, bool removeSelf)
{
wchar_t szTemp[MAX_PATH] = { 0 };
StringCbCopyW(szTemp, sizeof(szTemp)-1, szPath);
PathAppendW(szTemp, L"*.*");
SHFILEOPSTRUCTW shf;
SecureZeroMemory(&shf, sizeof(SHFILEOPSTRUCT));
shf.hwnd = NULL;
shf.pFrom = szTemp;
shf.wFunc = FO_DELETE;
shf.fFlags = FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
if (!recursion)
{
shf.fFlags |= FOF_NORECURSION;
}
if (0 != SHFileOperationW(&shf))
{
return false; // Failed to delete files
}
if (removeSelf)
{
if (!RemoveDirectoryW(szPath))
{
printf("Error: Failed to remove directory\n");
return false; // Failed to remove directory
}
}
return true; // Successfully cleared the path
}
bool createEmptyPath(const wchar_t* szPath)
{
if (!szPath || szPath[0] == 0)
{
printf("Error: Invalid path provided for directory creation.\n");
return false; // Invalid path
}
if (::PathFileExistsW(szPath))
{
if (::PathIsDirectoryW(szPath))
{
// Clear the directory
if (!clearPath(szPath, true, false))
{
printf("Failed to clear output directory\n");
return false; // Failed to clear output directory
}
return true; // Directory exists and is cleared
}
else
{
// If it exists but is not a directory, delete the file
if(!DeleteFileW(szPath) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
{
printf("Failed to delete existing file, Error=%d\n", ::GetLastError());
return false; // Failed to delete existing file
}
}
}
if (!::CreateDirectoryW(szPath, NULL) && ::GetLastError() != ERROR_ALREADY_EXISTS)
{
printf("Failed to create output directory, Error=%d\n", ::GetLastError());
return false; // Failed to create output directory
}
return true;
}
void getParentPath(wchar_t* szPath)
{
if (!szPath || szPath[0] == 0) return;
size_t length = wcslen(szPath);
std::replace(szPath, szPath+length, L'/', L'\\');
::PathRemoveFileSpecW(szPath);
}
bool forceCreatePath(const wchar_t* szPath)
{
wchar_t szCurrentPath[MAX_PATH] = { 0 };
StringCchCopyW(szCurrentPath, MAX_PATH, szPath);
size_t length = wcslen(szPath);
std::replace(szCurrentPath, szCurrentPath + length, L'/', L'\\');
//目录已经存在
if (::PathFileExistsW(szCurrentPath)) return true;
//能够直接创建
if (::CreateDirectoryW(szCurrentPath, 0)) return true;
//取得上一级目录
wchar_t szParentPath[MAX_PATH] = { 0 };
StringCchCopyW(szParentPath, MAX_PATH, szPath);
getParentPath(szParentPath);
//创建上一级目录
if (!forceCreatePath(szParentPath)) return false;
return TRUE == ::CreateDirectoryW(szCurrentPath, 0);
}
bool forceCreatePathForFile(const wchar_t* szFilePath)
{
wchar_t szPathForFile[MAX_PATH] = { 0 };
StringCchCopyW(szPathForFile, MAX_PATH, szFilePath);
getParentPath(szPathForFile);
return forceCreatePath(szPathForFile);
}