299 lines
7.3 KiB
C++
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);
|
|
} |