forked from metin-server/m2dev-client-src
Full Unicode patch with RTL Support & BiDi logic.
This commit is well documented, so no need to tell you my life story. Full Unicode patch with RTL Support & BiDi logic. Removed the legacy codePage, normalised to UTF8 (65001). It also comes with: CTRL + A : select text (highlighted) CTRL + C : copy CTRL + V : paste CTRL + X : cut CTRL + Y : redo CTRL + Z : undo
This commit is contained in:
@@ -5,24 +5,43 @@
|
||||
#include <io.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <utf8.h>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "filedir.h"
|
||||
|
||||
char korean_tolower(const char c);
|
||||
|
||||
const char * CreateTempFileName(const char * c_pszPrefix)
|
||||
const char* CreateTempFileName(const char* c_pszPrefix)
|
||||
{
|
||||
char szTempPath[MAX_PATH + 1];
|
||||
static char szTempName[MAX_PATH + 1];
|
||||
static std::string s_utf8TempName; // safe static storage
|
||||
|
||||
GetTempPath(MAX_PATH, szTempPath);
|
||||
wchar_t wTempPath[MAX_PATH + 1]{};
|
||||
wchar_t wTempName[MAX_PATH + 1]{};
|
||||
|
||||
GetTempFileName(szTempPath, // directory for temp files
|
||||
c_pszPrefix ? c_pszPrefix : "etb", // temp file name prefix
|
||||
c_pszPrefix ? true : false, // create unique name
|
||||
szTempName); // buffer for name
|
||||
// Get temp directory
|
||||
if (!GetTempPathW(MAX_PATH, wTempPath))
|
||||
return "";
|
||||
|
||||
return (szTempName);
|
||||
// Prefix must be wide
|
||||
wchar_t wPrefix[4] = L"etb";
|
||||
if (c_pszPrefix && *c_pszPrefix)
|
||||
{
|
||||
std::wstring wp = Utf8ToWide(c_pszPrefix);
|
||||
wcsncpy_s(wPrefix, wp.c_str(), 3);
|
||||
}
|
||||
|
||||
// Create temp file name
|
||||
if (!GetTempFileNameW(
|
||||
wTempPath,
|
||||
wPrefix,
|
||||
0, // unique number generated by system
|
||||
wTempName))
|
||||
return "";
|
||||
|
||||
// Convert result to UTF-8 for engine
|
||||
s_utf8TempName = WideToUtf8(wTempName);
|
||||
return s_utf8TempName.c_str();
|
||||
}
|
||||
|
||||
void GetFilePathNameExtension(const char * c_szFile, int len, std::string * pstPath, std::string * pstName, std::string * pstExt)
|
||||
@@ -41,10 +60,10 @@ void GetFilePathNameExtension(const char * c_szFile, int len, std::string * pstP
|
||||
|
||||
if (ext == len && c == '.')
|
||||
{
|
||||
ext = pos;
|
||||
ext = pos;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (c == '/' || c == '\\')
|
||||
break;
|
||||
}
|
||||
@@ -83,7 +102,7 @@ void GetFileExtension(const char* c_szFile, int len, std::string* pstExt)
|
||||
char c=c_szFile[pos];
|
||||
if (ext==len && c=='.')
|
||||
{
|
||||
ext=pos;
|
||||
ext=pos;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -91,7 +110,7 @@ void GetFileExtension(const char* c_szFile, int len, std::string* pstExt)
|
||||
else if (c=='\\') break;
|
||||
}
|
||||
|
||||
++ext;
|
||||
++ext;
|
||||
if (len>ext)
|
||||
pstExt->append(c_szFile+ext, len-ext);
|
||||
}
|
||||
@@ -110,7 +129,7 @@ void GetFileNameParts(const char* c_szFile, int len, char* pszPath, char* pszNam
|
||||
char c=c_szFile[pos];
|
||||
if (ext==len && c=='.')
|
||||
{
|
||||
ext=pos;
|
||||
ext=pos;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -127,7 +146,7 @@ void GetFileNameParts(const char* c_szFile, int len, char* pszPath, char* pszNam
|
||||
else if (c=='\\') break;
|
||||
}
|
||||
|
||||
if (pos)
|
||||
if (pos)
|
||||
{
|
||||
++pos;
|
||||
for (int i = 0; i < pos; ++i)
|
||||
@@ -147,7 +166,7 @@ void GetFileNameParts(const char* c_szFile, int len, char* pszPath, char* pszNam
|
||||
pszName[count] = '\0';
|
||||
}
|
||||
|
||||
++ext;
|
||||
++ext;
|
||||
if (len > ext)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -163,10 +182,10 @@ void GetOldIndexingName(char * szName, int Index)
|
||||
{
|
||||
int dec, sign;
|
||||
char Temp[512];
|
||||
|
||||
|
||||
strcpy(Temp, _ecvt(Index, 256, &dec, &sign));
|
||||
Temp[dec] = '\0';
|
||||
|
||||
|
||||
strcat(szName, Temp);
|
||||
}
|
||||
|
||||
@@ -423,38 +442,40 @@ bool IsGlobalFileName(const char * c_szFileName)
|
||||
return strchr(c_szFileName, ':') != NULL;
|
||||
}
|
||||
|
||||
void MyCreateDirectory(const char* path)
|
||||
void MyCreateDirectory(const char* pathUtf8)
|
||||
{
|
||||
if (!path || !*path)
|
||||
if (!pathUtf8 || !*pathUtf8)
|
||||
return;
|
||||
|
||||
char * dir;
|
||||
const char * p;
|
||||
// Skip drive letter (C:\)
|
||||
const char* path = pathUtf8;
|
||||
if (strlen(path) >= 3 && path[1] == ':')
|
||||
path += 3;
|
||||
|
||||
if (strlen(path) >= 3)
|
||||
{
|
||||
if (*(path + 1) == ':') // C:, D: 같은 경우를 체크
|
||||
path += 3;
|
||||
}
|
||||
size_t len = strlen(pathUtf8) + 1;
|
||||
char* dirUtf8 = new char[len];
|
||||
|
||||
p = path;
|
||||
|
||||
int len = strlen(path) + 1;
|
||||
dir = new char[len];
|
||||
const char* p = path;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (*p == '/' || *p == '\\')
|
||||
{
|
||||
memset(dir, 0, len);
|
||||
strncpy(dir, path, p - path);
|
||||
CreateDirectory(dir, NULL);
|
||||
}
|
||||
memset(dirUtf8, 0, len);
|
||||
strncpy(dirUtf8, pathUtf8, p - path + (path - pathUtf8));
|
||||
|
||||
// UTF-8 → UTF-16 for WinAPI
|
||||
std::wstring wDir = Utf8ToWide(dirUtf8);
|
||||
CreateDirectoryW(wDir.c_str(), nullptr);
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
delete [] dir;
|
||||
// Create final directory too
|
||||
std::wstring wFinal = Utf8ToWide(pathUtf8);
|
||||
CreateDirectoryW(wFinal.c_str(), nullptr);
|
||||
|
||||
delete[] dirUtf8;
|
||||
}
|
||||
|
||||
class CDirRemover : public CDir
|
||||
@@ -484,22 +505,31 @@ class CDirRemover : public CDir
|
||||
ms_strDirectoryDeque.push_back(strWorkingFolder);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnFile(const char* c_szPathName, const char* c_szFileName)
|
||||
{
|
||||
std::string strFullPathName;
|
||||
strFullPathName = c_szPathName;
|
||||
strFullPathName += c_szFileName;
|
||||
_chmod(strFullPathName.c_str(), _S_IWRITE);
|
||||
DeleteFile(strFullPathName.c_str());
|
||||
strFullPathName += c_szFileName;
|
||||
|
||||
std::wstring wFullPath = Utf8ToWide(strFullPathName);
|
||||
|
||||
// Make writable (use wide version)
|
||||
_wchmod(wFullPath.c_str(), _S_IWRITE);
|
||||
|
||||
// Delete (use wide WinAPI)
|
||||
DeleteFileW(wFullPath.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RemoveAllDirectory()
|
||||
{
|
||||
for (std::deque<std::string>::iterator itor = ms_strDirectoryDeque.begin(); itor != ms_strDirectoryDeque.end(); ++itor)
|
||||
for (std::deque<std::string>::iterator itor = ms_strDirectoryDeque.begin();
|
||||
itor != ms_strDirectoryDeque.end(); ++itor)
|
||||
{
|
||||
const std::string & c_rstrDirectory = *itor;
|
||||
RemoveDirectory(c_rstrDirectory.c_str());
|
||||
const std::string& dirUtf8 = *itor;
|
||||
std::wstring wDir = Utf8ToWide(dirUtf8);
|
||||
RemoveDirectoryW(wDir.c_str());
|
||||
}
|
||||
|
||||
ms_strDirectoryDeque.clear();
|
||||
@@ -511,14 +541,19 @@ class CDirRemover : public CDir
|
||||
|
||||
std::deque<std::string> CDirRemover::ms_strDirectoryDeque;
|
||||
|
||||
void RemoveAllDirectory(const char * c_szDirectoryName)
|
||||
void RemoveAllDirectory(const char* c_szDirectoryName)
|
||||
{
|
||||
{
|
||||
CDirRemover remover;
|
||||
remover.Create("*.*", c_szDirectoryName);
|
||||
CDirRemover::RemoveAllDirectory();
|
||||
}
|
||||
RemoveDirectory(c_szDirectoryName);
|
||||
|
||||
if (c_szDirectoryName && *c_szDirectoryName)
|
||||
{
|
||||
std::wstring wDir = Utf8ToWide(c_szDirectoryName);
|
||||
RemoveDirectoryW(wDir.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void StringExceptCharacter(std::string * pstrString, const char * c_szCharacter)
|
||||
@@ -573,14 +608,15 @@ bool SplitLine(const char * c_szLine, const char * c_szDelimeter, std::vector<st
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetExcutedFileName(std::string & r_str)
|
||||
void GetExcutedFileName(std::string& r_str)
|
||||
{
|
||||
char szPath[MAX_PATH+1];
|
||||
wchar_t wPath[MAX_PATH + 1]{};
|
||||
|
||||
GetModuleFileName(NULL, szPath, MAX_PATH);
|
||||
szPath[MAX_PATH] = '\0';
|
||||
GetModuleFileNameW(nullptr, wPath, MAX_PATH);
|
||||
wPath[MAX_PATH] = L'\0';
|
||||
|
||||
r_str = szPath;
|
||||
// Convert UTF-16 → UTF-8 for engine use
|
||||
r_str = WideToUtf8(wPath);
|
||||
}
|
||||
|
||||
const char * _getf(const char* c_szFormat, ...)
|
||||
|
||||
Reference in New Issue
Block a user