Add multibyteToWString wrapper functions around mbstowcs which work with Irrlicht string class.

I had to add a few forward declarations in core::string because I didn't want to add another source-file for this now. If anyone decides to create a irrString.cpp those can be removed again by making multibyteToWString extern instead of static (in VS it would already be possible to avoid them, but gcc does more exact checks for friend linkage specifiers).

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5212 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2015-12-13 15:34:17 +00:00
parent cfa84f1683
commit 6fd8d82d4c
5 changed files with 61 additions and 32 deletions

View File

@ -1,6 +1,7 @@
--------------------------
Changes in 1.9 (not yet released)
- Add multibyteToWString wrapper functions around mbstowcs which work with Irrlicht string class.
- Fix: addFileArchive now grab()'s the archive when you pass one in by pointer.
- Fix: Prevent division by 0 in CGUIScrollBar::setPos
- Fix: Add missing serialization to CSceneNodeAnimatorCameraFPS and CSceneNodeAnimatorCameraMaya

View File

@ -32,6 +32,11 @@ Helper functions for converting between UTF-8 and wchar_t are provided
outside the string class for explicit use.
*/
// forward declarations
template <typename T, typename TAlloc = irrAllocator<T> >
class string;
static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
enum eLocaleID
{
IRR_LOCALE_ANSI = 0,
@ -84,7 +89,7 @@ IRRLICHT_API void utf8ToWchar(const char *in, wchar_t *out, const u64 len);
IRRLICHT_API void wcharToUtf8(const wchar_t *in, char *out, const u64 len);
template <typename T, typename TAlloc = irrAllocator<T> >
template <typename T, typename TAlloc>
class string
{
public:
@ -1340,6 +1345,8 @@ public:
return ret.size()-oldSize;
}
friend size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
private:
//! Reallocate the array, make it bigger or smaller
@ -1375,6 +1382,51 @@ typedef string<c8> stringc;
//! Typedef for wide character strings
typedef string<wchar_t> stringw;
//! Convert multibyte string to wide-character string
/** Wrapper around mbstowcs from standard library, but directly using Irrlicht string class.
What the function does exactly depends on the LC_CTYPE of the current c locale.
\param destination Wide-character string receiving the converted source
\param source multibyte string
\return The number of wide characters written to destination, not including the eventual terminating null character. */
static inline size_t multibyteToWString(string<wchar_t>& destination, const core::string<c8>& source)
{
return multibyteToWString(destination, source.c_str(), (u32)source.size());
}
//! Convert multibyte string to wide-character string
/** Wrapper around mbstowcs from standard library, but directly writing to Irrlicht string class.
What the function does exactly depends on the LC_CTYPE of the current c locale.
\param destination Wide-character string receiving the converted source
\param source multibyte string
\return The number of wide characters written to destination, not including the eventual terminating null character. */
static inline size_t multibyteToWString(string<wchar_t>& destination, const char* source)
{
u32 s = source ? (u32)strlen(source) : 0;
return multibyteToWString(destination, source, s);
}
//! Internally used by the other multibyteToWString functions
static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize)
{
if ( sourceSize )
{
destination.reserve(sourceSize+1);
#if defined(_MSC_VER)
#pragma warning(suppress: 4996) // 'mbstowcs': This function or variable may be unsafe. Consider using mbstowcs_s instead.
#endif
size_t written = mbstowcs(destination.array, source, (size_t)sourceSize);
destination.used = (u32)written;
destination.array[destination.used] = 0;
return written;
}
else
{
destination.empty();
return 0;
}
}
} // end namespace core
} // end namespace irr

View File

@ -341,13 +341,8 @@ bool CGUIEditBox::processKey(const SEvent& event)
const c8* p = Operator->getTextFromClipboard();
if (p)
{
// TODO: we should have such a function in core::string
size_t lenOld = strlen(p);
wchar_t *ws = new wchar_t[lenOld + 1];
size_t len = mbstowcs(ws,p,lenOld);
ws[len] = 0;
irr::core::stringw widep(ws);
delete[] ws;
irr::core::stringw widep;
core::multibyteToWString(widep, p);
if (MarkBegin == MarkEnd)
{

View File

@ -377,7 +377,7 @@ void CGUIFileOpenDialog::fillListBox()
#ifndef _IRR_WCHAR_FILESYSTEM
char* oldLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL,""); // mbstowcs is affected by LC_CTYPE. Filenames seem to need the system-locale.
setlocale(LC_ALL,""); // multibyteToWString is affected by LC_CTYPE. Filenames seem to need the system-locale.
#endif
if (FileList)
@ -385,13 +385,7 @@ void CGUIFileOpenDialog::fillListBox()
for (u32 i=0; i < FileList->getFileCount(); ++i)
{
#ifndef _IRR_WCHAR_FILESYSTEM
const c8 *cs = (const c8 *)FileList->getFileName(i).c_str();
size_t lencs = strlen(cs);
wchar_t *ws = new wchar_t[lencs + 1];
size_t len = mbstowcs(ws, cs, lencs);
ws[len] = 0;
s = ws;
delete [] ws;
core::multibyteToWString(s, FileList->getFileName(i));
#else
s = FileList->getFileName(i).c_str();
#endif
@ -402,13 +396,7 @@ void CGUIFileOpenDialog::fillListBox()
if (FileNameText)
{
#ifndef _IRR_WCHAR_FILESYSTEM
const c8 *cs = (const c8 *)FileSystem->getWorkingDirectory().c_str();
size_t lencs = strlen(cs);
wchar_t *ws = new wchar_t[lencs + 1];
size_t len = mbstowcs(ws, cs, lencs);
ws[len] = 0;
s = ws;
delete [] ws;
core::multibyteToWString(s, FileSystem->getWorkingDirectory());
#else
s = FileSystem->getWorkingDirectory();
#endif

View File

@ -876,15 +876,8 @@ void CGUIEditWorkspace::PasteXMLToSelectedElement()
{
// get clipboard data
const char * p = Environment->getOSOperator()->getTextFromClipboard();
// convert to stringw
// TODO: we should have such a function in core::string
size_t lenOld = strlen(p);
wchar_t *ws = new wchar_t[lenOld + 1];
size_t len = mbstowcs(ws,p,lenOld);
ws[len] = 0;
irr::core::stringw wXMLText(ws);
delete[] ws;
irr::core::stringw wXMLText;
core::multibyteToWString(wXMLText, p);
io::CMemoryReadWriteFile* memWrite = new io::CMemoryReadWriteFile("#Clipboard#");