Browse Source

Added WString class.
Create as an Unicode application on Windows.

Lasse Öörni 14 years ago
parent
commit
bedf357c90

+ 1 - 0
CMakeLists.txt

@@ -38,6 +38,7 @@ endif ()
 # Compiler-specific options
 # Compiler-specific options
 if (MSVC)
 if (MSVC)
     add_definitions (-D_CRT_SECURE_NO_WARNINGS)
     add_definitions (-D_CRT_SECURE_NO_WARNINGS)
+    add_definitions (-DUNICODE -D_UNICODE)
     set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
     set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
     set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /MT /fp:fast /Zi /GS-")
     set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /MT /fp:fast /Zi /GS-")
     set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELWITHDEBINFO} /GL")
     set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELWITHDEBINFO} /GL")

+ 73 - 34
Engine/Container/Str.cpp

@@ -28,6 +28,14 @@
 
 
 char String::endZero = 0;
 char String::endZero = 0;
 
 
+String::String(const WString& str) :
+    length_(0),
+    capacity_(0),
+    buffer_(&endZero)
+{
+    SetUTF8FromWChar(str.CString());
+}
+
 String::String(int value) :
 String::String(int value) :
     length_(0),
     length_(0),
     capacity_(0),
     capacity_(0),
@@ -640,40 +648,6 @@ void String::SetUTF8FromWChar(const wchar_t* str)
     #endif
     #endif
 }
 }
 
 
-void String::WCharString(wchar_t* dest, unsigned maxLength) const
-{
-    if (!buffer_ || !dest || !maxLength)
-        return;
-    
-    const char* src = buffer_;
-    wchar_t* end = dest + maxLength;
-    
-    #ifdef WIN32
-    while (src < buffer_ + length_)
-    {
-        if (dest + 2 >= end)
-        {
-            *dest = 0;
-            return;
-        }
-        unsigned unicodeChar = DecodeUTF8(src);
-        EncodeUTF16(dest, unicodeChar);
-    }
-    *dest = 0;
-    #else
-    while (src < buffer_ + length)
-    {
-        if (dest + 1 >= end)
-        {
-            *dest = 0;
-            return;
-        }
-        *dest++ = DecodeUTF8(src);
-    }
-    *dest = 0;
-    #endif
-}
-
 unsigned String::LengthUTF8() const
 unsigned String::LengthUTF8() const
 {
 {
     unsigned ret = 0;
     unsigned ret = 0;
@@ -1026,3 +1000,68 @@ void String::Replace(unsigned pos, unsigned length, const char* srcStart, unsign
     
     
     CopyChars(buffer_ + pos, srcStart, srcLength);
     CopyChars(buffer_ + pos, srcStart, srcLength);
 }
 }
+
+WString::WString() :
+    length_(0),
+    buffer_(0)
+{
+}
+
+WString::WString(const String& str) :
+    length_(0),
+    buffer_(0)
+{
+    #ifdef WIN32
+    unsigned neededSize = 0;
+    wchar_t temp[3];
+    
+    unsigned byteOffset = 0;
+    while (byteOffset < str.Length())
+    {
+        wchar_t* dest = temp;
+        String::EncodeUTF16(dest, str.NextUTF8Char(byteOffset));
+        neededSize += dest - temp;
+    }
+    ++neededSize;
+    
+    Resize(neededSize);
+    
+    byteOffset = 0;
+    wchar_t* dest = buffer_;
+    while (byteOffset < str.Length())
+        String::EncodeUTF16(dest, str.NextUTF8Char(byteOffset));
+    
+    *dest = 0;
+    #else
+    Resize(str.LengthUTF8() + 1);
+    
+    unsigned byteOffset = 0;
+    wchar_t* dest = buffer_;
+    while (byteOffset < str.Length())
+        *dest++ = str.NextUTF8Char(byteOffset);
+    
+    *dest = 0;
+    #endif
+}
+
+WString::~WString()
+{
+    delete[] buffer_;
+}
+
+void WString::Resize(unsigned newSize)
+{
+    if (!newSize)
+    {
+        delete[] buffer_;
+        buffer_ = 0;
+    }
+    else
+    {
+        wchar_t* newBuffer = new wchar_t[newSize];
+        if (buffer_)
+            memcpy(newBuffer, buffer_, length_ * sizeof(wchar_t));
+        buffer_ = newBuffer;
+        length_ = newSize;
+    }
+}

+ 42 - 2
Engine/Container/Str.h

@@ -30,6 +30,8 @@
 
 
 static const int CONVERSION_BUFFER_LENGTH = 128;
 static const int CONVERSION_BUFFER_LENGTH = 128;
 
 
+class WString;
+
 /// %String class.
 /// %String class.
 class String
 class String
 {
 {
@@ -82,6 +84,18 @@ public:
         CopyChars(buffer_, str, length);
         CopyChars(buffer_, str, length);
     }
     }
     
     
+    /// Construct from a null-terminated wide character array.
+    String(const wchar_t* str) :
+        length_(0),
+        capacity_(0),
+        buffer_(&endZero)
+    {
+        SetUTF8FromWChar(str);
+    }
+    
+    /// Construct from a wide character string.
+    String(const WString& str);
+    
     /// Construct from an integer.
     /// Construct from an integer.
     explicit String(int value);
     explicit String(int value);
     /// Construct from a short integer.
     /// Construct from a short integer.
@@ -339,8 +353,6 @@ public:
     void SetUTF8FromLatin1(const char* str);
     void SetUTF8FromLatin1(const char* str);
     /// Construct UTF8 content from wide characters.
     /// Construct UTF8 content from wide characters.
     void SetUTF8FromWChar(const wchar_t* str);
     void SetUTF8FromWChar(const wchar_t* str);
-    /// Convert UTF8 content to wide characters.
-    void WCharString(wchar_t* dest, unsigned maxLength) const;
     /// Calculate number of characters in UTF8 content.
     /// Calculate number of characters in UTF8 content.
     unsigned LengthUTF8() const;
     unsigned LengthUTF8() const;
     /// Return byte offset for UTF8 index.
     /// Return byte offset for UTF8 index.
@@ -451,3 +463,31 @@ inline String operator + (const char* lhs, const String& rhs)
     ret += rhs;
     ret += rhs;
     return ret;
     return ret;
 }
 }
+
+/// Wide character string. Only meant for converting from UTF8 String and passing to the operating system where necessary.
+class WString
+{
+public:
+    /// Construct empty.
+    WString();
+    /// Construct from a string.
+    WString(const String& str);
+    /// Destruct.
+    ~WString();
+    
+    /// Resize string.
+    void Resize(unsigned newSize);
+    
+    /// Return whether the string is empty.
+    bool Empty() const { return length_ == 0; }
+    /// Return length.
+    unsigned Length() const { return length_; }
+    /// Return character data.
+    const wchar_t* CString() const { return buffer_; }
+    
+private:
+    /// String length.
+    unsigned length_;
+    /// String buffer, null if not allocated.
+    wchar_t* buffer_;
+};

+ 4 - 4
Engine/Core/MiniDump.cpp

@@ -60,15 +60,15 @@ int WriteMiniDump(const char* applicationName, void* exceptionPointers)
     dateTimeStr.Replace("/", "");
     dateTimeStr.Replace("/", "");
     dateTimeStr.Replace(' ', '_');
     dateTimeStr.Replace(' ', '_');
     
     
-    char pathName[MAX_PATH];
+    wchar_t pathName[MAX_PATH];
     pathName[0] = 0;
     pathName[0] = 0;
-    SHGetSpecialFolderPath(0, pathName, CSIDL_PERSONAL, 0);
+    SHGetSpecialFolderPathW(0, pathName, CSIDL_PERSONAL, 0);
     String applicationNameStr(applicationName);
     String applicationNameStr(applicationName);
     String miniDumpDir = String(pathName) + "\\" + applicationNameStr;
     String miniDumpDir = String(pathName) + "\\" + applicationNameStr;
     String miniDumpName = miniDumpDir + "\\" + applicationNameStr + "_" + dateTimeStr + ".dmp";
     String miniDumpName = miniDumpDir + "\\" + applicationNameStr + "_" + dateTimeStr + ".dmp";
     
     
-    CreateDirectory(miniDumpDir.CString(), 0);
-    HANDLE file = CreateFile(miniDumpName.CString(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ,
+    CreateDirectoryW(WString(miniDumpDir).CString(), 0);
+    HANDLE file = CreateFileW(WString(miniDumpName).CString(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ,
         0, CREATE_ALWAYS, 0, 0);
         0, CREATE_ALWAYS, 0, 0);
     
     
     BOOL success = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithDataSegs, &info, 0, 0);
     BOOL success = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithDataSegs, &info, 0, 0);

+ 1 - 1
Engine/Core/ProcessUtils.cpp

@@ -100,7 +100,7 @@ void InitFPU()
 void ErrorDialog(const String& title, const String& message)
 void ErrorDialog(const String& title, const String& message)
 {
 {
     #ifdef WIN32
     #ifdef WIN32
-    MessageBox(0, message.CString(), title.CString(), 0);
+    MessageBoxW(0, WString(message).CString(), WString(title).CString(), 0);
     #else
     #else
     printf("%s\n", message.CString());
     printf("%s\n", message.CString());
     #endif
     #endif

+ 3 - 3
Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -247,7 +247,7 @@ void Graphics::SetWindowTitle(const String& windowTitle)
 {
 {
     windowTitle_ = windowTitle;
     windowTitle_ = windowTitle;
     if (impl_->window_)
     if (impl_->window_)
-        SetWindowText(impl_->window_, windowTitle_.CString());
+        SetWindowTextW(impl_->window_, WString(windowTitle_).CString());
 }
 }
 
 
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool tripleBuffer, int multiSample)
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool tripleBuffer, int multiSample)
@@ -1891,13 +1891,13 @@ bool Graphics::OpenWindow(int width, int height)
     wc.hCursor       = LoadCursor(0, IDC_ARROW);
     wc.hCursor       = LoadCursor(0, IDC_ARROW);
     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
     wc.lpszMenuName  = 0;
     wc.lpszMenuName  = 0;
-    wc.lpszClassName = "D3DWindow";
+    wc.lpszClassName = L"D3DWindow";
     
     
     RegisterClass(&wc);
     RegisterClass(&wc);
     
     
     RECT rect = {0, 0, width, height};
     RECT rect = {0, 0, width, height};
     AdjustWindowRect(&rect, windowStyle, false);
     AdjustWindowRect(&rect, windowStyle, false);
-    impl_->window_ = CreateWindow("D3DWindow", windowTitle_.CString(), windowStyle, CW_USEDEFAULT, CW_USEDEFAULT,
+    impl_->window_ = CreateWindowW(L"D3DWindow", WString(windowTitle_).CString(), windowStyle, CW_USEDEFAULT, CW_USEDEFAULT,
         rect.right, rect.bottom, 0, 0, impl_->instance_, 0); 
         rect.right, rect.bottom, 0, 0, impl_->instance_, 0); 
     
     
     if (!impl_->window_)
     if (!impl_->window_)

+ 31 - 25
Engine/IO/FileSystem.cpp

@@ -71,7 +71,7 @@ bool FileSystem::SetCurrentDir(const String& pathName)
         return false;
         return false;
     }
     }
     #ifdef WIN32
     #ifdef WIN32
-    if (SetCurrentDirectory(GetNativePath(pathName).CString()) == FALSE)
+    if (SetCurrentDirectoryW(WString(GetNativePath(pathName)).CString()) == FALSE)
     {
     {
         LOGERROR("Failed to change directory to " + pathName);
         LOGERROR("Failed to change directory to " + pathName);
         return false;
         return false;
@@ -96,7 +96,7 @@ bool FileSystem::CreateDir(const String& pathName)
     }
     }
     
     
     #ifdef WIN32
     #ifdef WIN32
-    bool success = (CreateDirectory(GetNativePath(RemoveTrailingSlash(pathName)).CString(), 0) == TRUE) ||
+    bool success = (CreateDirectoryW(WString(GetNativePath(RemoveTrailingSlash(pathName))).CString(), 0) == TRUE) ||
         (GetLastError() == ERROR_ALREADY_EXISTS);
         (GetLastError() == ERROR_ALREADY_EXISTS);
     #else
     #else
     bool success = mkdir(GetNativePath(RemoveTrailingSlash(pathName)).CString(), S_IRWXU) == 0 || errno == EEXIST;
     bool success = mkdir(GetNativePath(RemoveTrailingSlash(pathName)).CString(), S_IRWXU) == 0 || errno == EEXIST;
@@ -179,8 +179,8 @@ bool FileSystem::SystemOpen(const String& fileName, const String& mode)
             return false;
             return false;
         }
         }
         
         
-        bool success = (int)ShellExecute(0, !mode.Empty() ? (char*)mode.CString() : 0,
-            (char*)GetNativePath(fileName).CString(), 0, 0, SW_SHOW) > 32;
+        bool success = (int)ShellExecuteW(0, !mode.Empty() ? WString(mode).CString() : 0,
+            WString(GetNativePath(fileName)).CString(), 0, 0, SW_SHOW) > 32;
         if (!success)
         if (!success)
             LOGERROR("Failed to open " + fileName + " externally");
             LOGERROR("Failed to open " + fileName + " externally");
         return success;
         return success;
@@ -253,16 +253,17 @@ bool FileSystem::Delete(const String& fileName)
 
 
 String FileSystem::GetCurrentDir()
 String FileSystem::GetCurrentDir()
 {
 {
-    char path[MAX_PATH];
-    path[0] = 0;
-    
     #ifdef WIN32
     #ifdef WIN32
-    GetCurrentDirectory(MAX_PATH, path);
+    wchar_t path[MAX_PATH];
+    path[0] = 0;
+    GetCurrentDirectoryW(MAX_PATH, path);
+    return AddTrailingSlash(String(path));
     #else
     #else
+    char path[MAX_PATH];
+    path[0] = 0;
     getcwd(path, MAX_PATH);
     getcwd(path, MAX_PATH);
-    #endif
-    
     return AddTrailingSlash(String(path));
     return AddTrailingSlash(String(path));
+    #endif
 }
 }
 
 
 bool FileSystem::CheckAccess(const String& pathName)
 bool FileSystem::CheckAccess(const String& pathName)
@@ -296,7 +297,7 @@ bool FileSystem::FileExists(const String& fileName)
     String fixedName = GetNativePath(RemoveTrailingSlash(fileName));
     String fixedName = GetNativePath(RemoveTrailingSlash(fileName));
     
     
     #ifdef WIN32
     #ifdef WIN32
-    DWORD attributes = GetFileAttributes(fixedName.CString());
+    DWORD attributes = GetFileAttributesW(WString(fixedName).CString());
     if (attributes == INVALID_FILE_ATTRIBUTES || attributes & FILE_ATTRIBUTE_DIRECTORY)
     if (attributes == INVALID_FILE_ATTRIBUTES || attributes & FILE_ATTRIBUTE_DIRECTORY)
         return false;
         return false;
     #else
     #else
@@ -316,7 +317,7 @@ bool FileSystem::DirExists(const String& pathName)
     String fixedName = GetNativePath(RemoveTrailingSlash(pathName));
     String fixedName = GetNativePath(RemoveTrailingSlash(pathName));
     
     
     #ifdef WIN32
     #ifdef WIN32
-    DWORD attributes = GetFileAttributes(fixedName.CString());
+    DWORD attributes = GetFileAttributes(WString(fixedName).CString());
     if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY))
     if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY))
         return false;
         return false;
     #else
     #else
@@ -341,37 +342,42 @@ void FileSystem::ScanDir(Vector<String>& result, const String& pathName, const S
 
 
 String FileSystem::GetProgramDir()
 String FileSystem::GetProgramDir()
 {
 {
-    char exeName[MAX_PATH];
-    memset(exeName, 0, MAX_PATH);
-    
     #ifdef WIN32
     #ifdef WIN32
-    GetModuleFileName(0, exeName, MAX_PATH);
+    wchar_t exeName[MAX_PATH];
+    exeName[0] = 0;
+    GetModuleFileNameW(0, exeName, MAX_PATH);
+    return GetPath(String(exeName));
     #endif
     #endif
     #ifdef __APPLE__
     #ifdef __APPLE__
+    char exeName[MAX_PATH];
+    memset(exeName, 0, MAX_PATH);
     unsigned size = MAX_PATH;
     unsigned size = MAX_PATH;
     _NSGetExecutablePath(exeName, &size);
     _NSGetExecutablePath(exeName, &size);
+    return GetPath(String(exeName));
     #endif
     #endif
     #ifdef __linux__
     #ifdef __linux__
+    char exeName[MAX_PATH];
+    memset(exeName, 0, MAX_PATH);
     pid_t pid = getpid();
     pid_t pid = getpid();
     String link = "/proc/" + String(pid) + "/exe";
     String link = "/proc/" + String(pid) + "/exe";
     readlink(link.CString(), exeName, MAX_PATH);
     readlink(link.CString(), exeName, MAX_PATH);
-    #endif
-
     return GetPath(String(exeName));
     return GetPath(String(exeName));
+    #endif
 }
 }
 
 
 String FileSystem::GetUserDocumentsDir()
 String FileSystem::GetUserDocumentsDir()
 {
 {
-    char pathName[MAX_PATH];
-    pathName[0] = 0;
-    
     #ifdef WIN32
     #ifdef WIN32
-    SHGetSpecialFolderPath(0, pathName, CSIDL_PERSONAL, 0);
+    wchar_t pathName[MAX_PATH];
+    pathName[0] = 0;
+    SHGetSpecialFolderPathW(0, pathName, CSIDL_PERSONAL, 0);
+    return AddTrailingSlash(String(pathName));
     #else
     #else
+    char pathName[MAX_PATH];
+    pathName[0] = 0;
     strcpy(pathName, getenv("HOME"));
     strcpy(pathName, getenv("HOME"));
-    #endif
-    
     return AddTrailingSlash(String(pathName));
     return AddTrailingSlash(String(pathName));
+    #endif
 }
 }
 
 
 void FileSystem::RegisterPath(const String& pathName)
 void FileSystem::RegisterPath(const String& pathName)
@@ -393,7 +399,7 @@ void FileSystem::ScanDirInternal(Vector<String>& result, String path, const Stri
     #ifdef WIN32
     #ifdef WIN32
     String pathAndFilter = GetNativePath(path + filter);
     String pathAndFilter = GetNativePath(path + filter);
     WIN32_FIND_DATA info;
     WIN32_FIND_DATA info;
-    HANDLE handle = FindFirstFile(pathAndFilter.CString(), &info);
+    HANDLE handle = FindFirstFileW(WString(pathAndFilter).CString(), &info);
     if (handle != INVALID_HANDLE_VALUE)
     if (handle != INVALID_HANDLE_VALUE)
     {
     {
         do
         do

+ 2 - 2
Engine/IO/FileWatcher.cpp

@@ -54,8 +54,8 @@ bool FileWatcher::StartWatching(const String& path, bool watchSubDirs)
 #if defined(WIN32) && defined(ENABLE_FILEWATCHER)
 #if defined(WIN32) && defined(ENABLE_FILEWATCHER)
     String nativePath = GetNativePath(RemoveTrailingSlash(path));
     String nativePath = GetNativePath(RemoveTrailingSlash(path));
     
     
-    dirHandle_ = (void*)CreateFile(
-        nativePath.CString(),
+    dirHandle_ = (void*)CreateFileW(
+        WString(nativePath).CString(),
         FILE_LIST_DIRECTORY,
         FILE_LIST_DIRECTORY,
         FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
         FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
         0,
         0,

+ 2 - 2
ThirdParty/ODE/ode/src/error.cpp

@@ -139,7 +139,7 @@ extern "C" void dError (int num, const char *msg, ...)
     _snprintf (title,sizeof(title),"ODE Error %d",num);
     _snprintf (title,sizeof(title),"ODE Error %d",num);
     _vsnprintf (s,sizeof(s),msg,ap);
     _vsnprintf (s,sizeof(s),msg,ap);
     s[sizeof(s)-1] = 0;
     s[sizeof(s)-1] = 0;
-    MessageBox(0,s,title,MB_OK | MB_ICONWARNING);
+    MessageBoxA(0,s,title,MB_OK | MB_ICONWARNING);
   }
   }
   exit (1);
   exit (1);
 }
 }
@@ -155,7 +155,7 @@ extern "C" void dDebug (int num, const char *msg, ...)
     _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num);
     _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num);
     _vsnprintf (s,sizeof(s),msg,ap);
     _vsnprintf (s,sizeof(s),msg,ap);
     s[sizeof(s)-1] = 0;
     s[sizeof(s)-1] = 0;
-    MessageBox(0,s,title,MB_OK | MB_ICONSTOP);
+    MessageBoxA(0,s,title,MB_OK | MB_ICONSTOP);
   }
   }
   abort();
   abort();
 }
 }