- attempt to get non ascii file paths working in megaglest (Japanese etc...)

This commit is contained in:
Mark Vejvoda
2011-05-18 21:49:11 +00:00
parent 727c7b33d9
commit 60b8093f5b
34 changed files with 519 additions and 110 deletions

View File

@@ -56,6 +56,7 @@
#include <map>
#include "randomgen.h"
#include <algorithm>
#include "platform_util.h"
#include "leak_dumper.h"
using namespace Shared::Platform;
@@ -290,7 +291,7 @@ void findAll(const vector<string> &paths, const string &fileFilter, vector<strin
findAll(path, current_results, cutExtension, errorOnNotFound);
if(current_results.size() > 0) {
for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
string &current_file = current_results[folder_index];
string current_file = current_results[folder_index];
if(keepDuplicates == true || std::find(results.begin(),results.end(),current_file) == results.end()) {
results.push_back(current_file);
}
@@ -319,16 +320,14 @@ void findAll(const string &path, vector<string> &results, bool cutExtension, boo
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0 && errorOnNotFound == true)
{
if(res < 0 && errorOnNotFound == true) {
if(errorOnNotFound) {
std::stringstream msg;
msg << "#1 Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
}
else
{
else {
for(int i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
const char* begin = p;
@@ -370,8 +369,13 @@ bool isdir(const char *path)
}
#endif
#ifdef WIN32
struct _stat64i32 stats;
int result = _wstat(utf8_decode(friendly_path).c_str(), &stats);
#else
struct stat stats;
int result = stat(friendly_path.c_str(), &stats);
#endif
bool ret = (result == 0);
if(ret == true) {
ret = S_ISDIR(stats.st_mode); // #define S_ISDIR(mode) ((mode) & _S_IFDIR)
@@ -423,7 +427,8 @@ void removeFolder(const string path) {
//printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
#ifdef WIN32
int result = _rmdir(item.c_str());
//int result = _rmdir(item.c_str());
int result = _wrmdir(utf8_decode(item).c_str());
#else
int result = rmdir(item.c_str());
#endif
@@ -437,7 +442,8 @@ void removeFolder(const string path) {
}
#ifdef WIN32
int result = _rmdir(path.c_str());
//int result = _rmdir(path.c_str());
int result = _wrmdir(utf8_decode(path).c_str());
#else
int result = rmdir(path.c_str());
#endif
@@ -555,7 +561,11 @@ pair<bool,time_t> hasCachedFileCRCValue(string crcCacheFile, int32 &value) {
//bool result = false;
pair<bool,time_t> result = make_pair(false,0);
if(fileExists(crcCacheFile) == true) {
#ifdef WIN32
FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"r");
#else
FILE *fp = fopen(crcCacheFile.c_str(),"r");
#endif
if(fp != NULL) {
time_t refreshDate = 0;
int32 crcValue = 0;
@@ -589,7 +599,11 @@ pair<bool,time_t> hasCachedFileCRCValue(string crcCacheFile, int32 &value) {
}
void writeCachedFileCRCValue(string crcCacheFile, int32 &crcValue) {
#ifdef WIN32
FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"w");
#else
FILE *fp = fopen(crcCacheFile.c_str(),"w");
#endif
if(fp != NULL) {
//RandomGen random;
//int offset = random.randRange(5, 15);
@@ -1258,7 +1272,8 @@ void createDirectoryPaths(string Path) {
if ('/' == *path) {
if(isdir(DirName) == false) {
#ifdef WIN32
int result = _mkdir(DirName);
int result = _wmkdir(utf8_decode(DirName).c_str());
//int result = _mkdir(DirName);
#elif defined(__GNUC__)
int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
#else
@@ -1271,12 +1286,14 @@ void createDirectoryPaths(string Path) {
*dirName = '\0';
}
#ifdef WIN32
_mkdir(DirName);
//int result = _mkdir(DirName);
int result = _wmkdir(utf8_decode(DirName).c_str());
#elif defined(__GNUC__)
mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
#else
#error "Your compiler needs to support mkdir!"
#endif
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno);
}
void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen) {
@@ -1653,7 +1670,7 @@ bool executeShellCommand(string cmd, int expectedResult) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to run [%s]", cmd.c_str());
#ifdef WIN32
FILE *file = _popen(cmd.c_str(),"r");
FILE *file = _wpopen(utf8_decode(cmd).c_str(),L"r");
#else
FILE *file = popen(cmd.c_str(),"r");
#endif
@@ -1699,8 +1716,13 @@ bool renameFile(string oldFile, string newFile) {
}
off_t getFileSize(string filename) {
#ifdef WIN32
struct _stat64i32 stbuf;
if(_wstat(utf8_decode(filename).c_str(), &stbuf) != -1) {
#else
struct stat stbuf;
if(stat(filename.c_str(), &stbuf) != -1) {
#endif
return stbuf.st_size;
}
return 0;
@@ -1710,7 +1732,7 @@ string executable_path(string exeName, bool includeExeNameInPath) {
string value = "";
#ifdef _WIN32
char path[MAX_PATH]="";
if( GetModuleFileName(NULL,path,MAX_PATH) == 0 ) {
if( GetModuleFileNameA(NULL,path,MAX_PATH) == 0 ) {
if(includeExeNameInPath == true) {
value = exeName;
}
@@ -1802,8 +1824,13 @@ bool searchAndReplaceTextInFile(string fileName, string findText, string replace
size_t find_len = findText.length();
string tempfileName = fileName + "_tmp";
#ifdef WIN32
fp1 = _wfopen(utf8_decode(fileName).c_str(), L"r");
fp2 = _wfopen(utf8_decode(tempfileName).c_str(), L"w");
#else
fp1 = fopen(fileName.c_str(),"r");
fp2 = fopen(tempfileName.c_str(),"w");
#endif
while(fgets(buffer,MAX_LEN_SINGLE_LINE + 2,fp1)) {
buff_ptr = buffer;
@@ -1839,8 +1866,15 @@ bool searchAndReplaceTextInFile(string fileName, string findText, string replace
void copyFileTo(string fromFileName, string toFileName) {
//Open an input and output stream in binary mode
#ifdef WIN32
FILE *fp1 = _wfopen(utf8_decode(fromFileName).c_str(), L"rb");
ifstream in(fp1);
FILE *fp2 = _wfopen(utf8_decode(toFileName).c_str(), L"wb");
ofstream out(fp2);
#else
ifstream in(fromFileName.c_str(),ios::binary);
ofstream out(toFileName.c_str(),ios::binary);
#endif
if(in.is_open() && out.is_open()) {
while(in.eof() == false) {
@@ -1851,6 +1885,11 @@ void copyFileTo(string fromFileName, string toFileName) {
//Close both files
in.close();
out.close();
#ifdef WIN32
fclose(fp1);
fclose(fp2);
#endif
}
// =====================================

View File

@@ -43,12 +43,12 @@ void addlog (const char * fmt, ...) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> IRC: %s\n", buf);
if(SystemFlags::VERBOSE_MODE_ENABLED == true) {
if ( (fp = fopen ("irctest.log", "ab")) != 0 ) {
fprintf (fp, "%s\n", buf);
fclose (fp);
}
}
//if(SystemFlags::VERBOSE_MODE_ENABLED == true) {
// if ( (fp = fopen ("irctest.log", "ab")) != 0 ) {
// fprintf (fp, "%s\n", buf);
// fclose (fp);
// }
//}
}
void dump_event (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) {

View File

@@ -19,6 +19,7 @@
#include <curl/easy.h>
#include <algorithm>
#include "conversion.h"
#include "platform_util.h"
using namespace Shared::Util;
using namespace Shared::PlatformCommon;
@@ -85,7 +86,11 @@ static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread opening file for writing [%s]\n",fullFilePath.c_str());
/* open file for writing */
#ifdef WIN32
out->stream= _wfopen(utf8_decode(fullFilePath).c_str(), L"wb");
#else
out->stream = fopen(fullFilePath.c_str(), "wb");
#endif
if(out->stream == NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str());
@@ -1164,7 +1169,11 @@ pair<FTP_Client_ResultType,string> FTPClientThread::getFileFromServer(FTP_Clien
ftpfile.stream = NULL;
}
#ifdef WIN32
FILE *fp = _wfopen(utf8_decode(destFileSaveAs).c_str(), L"rt");
#else
FILE *fp = fopen(destFileSaveAs.c_str(), "rt");
#endif
if(fp != NULL) {
char szBuf[4096]="";
while(feof(fp) == false) {

View File

@@ -19,13 +19,14 @@
#include "window.h"
#include <vector>
//#include <SDL_image.h>
#include "platform_util.h"
#include "leak_dumper.h"
using namespace Shared::Graphics::Gl;
using namespace Shared::Util;
namespace Shared{ namespace Platform{
// ======================================
@@ -43,11 +44,15 @@ namespace Shared{ namespace Platform{
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int charCount, FontMetrics &metrics) {
//return;
// -adecw-screen-medium-r-normal--18-180-75-75-m-160-gb2312.1980-1 this is a Chinese font
std::string useRealFontName = type;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] trying to load useRealFontName [%s], size = %d, width = %d\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),size,width);
DWORD dwErrorGL = 0;
HDC hDC = 0;
static std::vector<std::string> systemFontList;
if(systemFontList.size() == 0) {
LOGFONT lf;
@@ -56,7 +61,16 @@ namespace Shared{ namespace Platform{
lf.lfCharSet = (BYTE)charSet;
lf.lfFaceName[0]='\0';
HDC hDC = wglGetCurrentDC();
//HGLRC hdRC =wglGetCurrentContext();
//DWORD dwErrorGL = GetLastError();
//assertGl();
hDC = wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
//hDC = CreateCompatibleDC(0);
//dwErrorGL = GetLastError();
::EnumFontFamiliesEx(hDC,
&lf,
(FONTENUMPROC) EnumFontFamExProc,
@@ -79,17 +93,39 @@ namespace Shared{ namespace Platform{
}
}
}
LPWSTR wstr = Ansi2WideString(useRealFontName.c_str());
HFONT font= CreateFont(
size, 0, 0, 0, width, FALSE, FALSE, FALSE, charSet,
OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH| (useRealFontName.c_str() ? FF_DONTCARE:FF_SWISS), useRealFontName.c_str());
DEFAULT_PITCH| (useRealFontName.c_str() ? FF_DONTCARE:FF_SWISS), wstr);
delete [] wstr;
assert(font!=NULL);
HDC dc= wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
SelectObject(dc, font);
BOOL err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
assertGl();
BOOL err= 0;
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
/*
for(int glBugRetry = 0; glBugRetry <= 10; glBugRetry++) {
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
//assertGl();
GLenum error = glGetError();
if(error == 0) {
break;
}
}
*/
assertGl();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] wglUseFontBitmaps returned = %d, charCount = %d, base = %d\n",__FILE__,__FUNCTION__,__LINE__,err,charCount,base);
@@ -131,6 +167,10 @@ namespace Shared{ namespace Platform{
DeleteObject(font);
//if(hDC != 0) {
// DeleteDC(hDC);
//}
assert(err);
}

View File

@@ -47,21 +47,23 @@
#include <stdlib.h>
#define NOMINMAX
#include <windows.h>
#include "platform_util.h"
#define NUM_ELEMENTS(ar) (sizeof(ar) / sizeof(ar[0]))
using namespace Shared::Util;
/* /////////////////////////////////////////////////////////////////////////
* Helper functions
*/
static char const *strrpbrk(char const *string, char const *strCharSet)
{
char *part = NULL;
char const *part = NULL;
char const *pch;
for(pch = strCharSet; *pch; ++pch)
{
char *p = strrchr(string, *pch);
const char *p = strrchr(string, *pch);
if(NULL != p)
{
@@ -102,7 +104,7 @@ int glob( char const *pattern
int result;
char szRelative[1 + _MAX_PATH];
char const *file_part;
WIN32_FIND_DATAA find_data;
WIN32_FIND_DATAW find_data;
HANDLE hFind;
char *buffer;
char szPattern2[1 + _MAX_PATH];
@@ -167,7 +169,8 @@ int glob( char const *pattern
bMagic0 = (leafMost == strpbrk(leafMost, "?*"));
hFind = FindFirstFileA(effectivePattern, &find_data);
std::wstring wstr = utf8_decode(effectivePattern);
hFind = FindFirstFileW(wstr.c_str(), &find_data);
buffer = NULL;
pglob->gl_pathc = 0;
@@ -234,8 +237,8 @@ int glob( char const *pattern
GLOB_NODOTSDIRS == (flags & GLOB_NODOTSDIRS))
{
/* Pattern must begin with '.' to match either dots directory */
if( 0 == lstrcmpA(".", find_data.cFileName) ||
0 == lstrcmpA("..", find_data.cFileName))
if( 0 == lstrcmpW(L".", find_data.cFileName) ||
0 == lstrcmpW(L"..", find_data.cFileName))
{
continue;
}
@@ -246,7 +249,7 @@ int glob( char const *pattern
#if 0
if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M')
#endif /* 0 */
(void)lstrcatA(find_data.cFileName, "/");
(void)lstrcatW(find_data.cFileName, L"/");
}
}
else
@@ -261,7 +264,9 @@ int glob( char const *pattern
}
}
cch = lstrlenA(find_data.cFileName);
//cch = lstrlenW(find_data.cFileName);
string sFileName = utf8_encode(find_data.cFileName);
cch = sFileName.length();
if(NULL != file_part)
{
cch += (int)(file_part - effectivePattern);
@@ -291,12 +296,13 @@ int glob( char const *pattern
}
(void)lstrcpynA(buffer + cbCurr, szRelative, 1 + (int)(file_part - effectivePattern));
(void)lstrcatA(buffer + cbCurr, find_data.cFileName);
(void)lstrcatA(buffer + cbCurr, sFileName.c_str());
cbCurr += cch + 1;
++cMatches;
}
while(FindNextFile(hFind, &find_data) && cMatches != maxMatches);
//while(FindNextFileA(hFind, &find_data) && cMatches != maxMatches);
while(FindNextFileW(hFind, &find_data) && cMatches != maxMatches);
(void)FindClose(hFind);

View File

@@ -33,18 +33,63 @@ namespace Shared { namespace Platform {
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
// Constructs object and convert lpaszString to Unicode
LPWSTR Ansi2WideString(LPCSTR lpaszString) {
LPWSTR lpwszString(NULL);
int nLen = ::lstrlenA(lpaszString) + 1;
lpwszString = new WCHAR[nLen];
if (lpwszString == NULL) {
return lpwszString;
}
memset(lpwszString, 0, nLen * sizeof(WCHAR));
if (::MultiByteToWideChar(CP_ACP, 0, lpaszString, nLen, lpwszString, nLen) == 0) {
// Conversation failed
return lpwszString;
}
return lpwszString;
}
// Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr) {
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
replaceAll(strTo, "/", "\\");
replaceAll(strTo, "\\\\", "\\");
updatePathClimbingParts(strTo);
return strTo;
}
// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str) {
string friendly_path = str;
replaceAll(friendly_path, "/", "\\");
replaceAll(friendly_path, "\\\\", "\\");
updatePathClimbingParts(friendly_path);
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int)friendly_path.size(), NULL, 0);
std::wstring wstrTo( size_needed, 0 );
MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int)friendly_path.size(), &wstrTo[0], size_needed);
return wstrTo;
}
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
LPWSTR wstr = Ansi2WideString(thisPointer->dumpFileName.c_str());
HANDLE hFile = CreateFile(
thisPointer->dumpFileName.c_str(),
wstr,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
delete [] wstr;
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@@ -158,11 +203,16 @@ void message(string message){
std::cerr << " " << message << "\n";
std::cerr << "******************************************************\n";
MessageBox(NULL, message.c_str(), "Message", MB_OK);
LPWSTR wstr = Ansi2WideString(message.c_str());
MessageBox(NULL, wstr, L"Message", MB_OK);
delete [] wstr;
}
bool ask(string message){
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
LPWSTR wstr = Ansi2WideString(message.c_str());
bool result = MessageBox(NULL, wstr, L"Confirmation", MB_YESNO)==IDYES;
delete [] wstr;
return result;
}
void exceptionMessage(const exception &excp){
@@ -175,7 +225,11 @@ void exceptionMessage(const exception &excp){
title= "Error: Unhandled Exception";
printf("Error detected with text: %s\n",message.c_str());
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
LPWSTR wstr = Ansi2WideString(message.c_str());
LPWSTR wstr1 = Ansi2WideString(title.c_str());
MessageBox(NULL, wstr, wstr1, MB_ICONSTOP | MB_OK | MB_TASKMODAL);
delete [] wstr;
delete [] wstr1;
}
//int getScreenW(){
@@ -192,7 +246,7 @@ HICON icon;
void init_win32() {
HINSTANCE handle = ::GetModuleHandle(NULL);
icon = ::LoadIcon(handle, "IDI_ICON1");
icon = ::LoadIcon(handle, L"IDI_ICON1");
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version)