+ utf8 to/from utf16 implementation

This commit is contained in:
artemp 2013-05-20 12:05:22 +01:00
parent 4c05d3a617
commit 6412b43d6c

View file

@ -31,6 +31,7 @@
#endif #endif
// stl // stl
#include <string>
#include <stdexcept> #include <stdexcept>
#include <cstdlib> #include <cstdlib>
#include <limits> #include <limits>
@ -40,6 +41,7 @@
namespace mapnik namespace mapnik
{ {
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
using boost::mutex; using boost::mutex;
#endif #endif
@ -84,10 +86,10 @@ public:
return new(&staticMemory) T; return new(&staticMemory) T;
} }
#ifdef __SUNPRO_CC #ifdef __SUNPRO_CC
// Sun C++ Compiler doesn't handle `volatile` keyword same as GCC. // Sun C++ Compiler doesn't handle `volatile` keyword same as GCC.
static void destroy(T* obj) static void destroy(T* obj)
#else #else
static void destroy(volatile T* obj) static void destroy(volatile T* obj)
#endif #endif
{ {
obj->~T(); obj->~T();
@ -99,78 +101,113 @@ template <typename T,
template <typename U> class CreatePolicy=CreateStatic> class MAPNIK_DECL singleton template <typename U> class CreatePolicy=CreateStatic> class MAPNIK_DECL singleton
{ {
#else #else
template <typename T, template <typename T,
template <typename U> class CreatePolicy=CreateStatic> class singleton template <typename U> class CreatePolicy=CreateStatic> class singleton
{ {
#endif #endif
#ifdef __SUNPRO_CC #ifdef __SUNPRO_CC
/* Sun's C++ compiler will issue the following errors if CreatePolicy<T> is used: /* Sun's C++ compiler will issue the following errors if CreatePolicy<T> is used:
Error: A class template name was expected instead of mapnik::CreatePolicy<mapnik::T> Error: A class template name was expected instead of mapnik::CreatePolicy<mapnik::T>
Error: A "friend" declaration must specify a class or function. Error: A "friend" declaration must specify a class or function.
*/ */
friend class CreatePolicy; friend class CreatePolicy;
#else #else
friend class CreatePolicy<T>; friend class CreatePolicy<T>;
#endif #endif
static T* pInstance_; static T* pInstance_;
static bool destroyed_; static bool destroyed_;
singleton(const singleton &rhs); singleton(const singleton &rhs);
singleton& operator=(const singleton&); singleton& operator=(const singleton&);
static void onDeadReference() static void onDeadReference()
{
throw std::runtime_error("dead reference!");
}
static void DestroySingleton()
{
CreatePolicy<T>::destroy(pInstance_);
pInstance_ = 0;
destroyed_ = true;
}
protected:
#ifdef MAPNIK_THREADSAFE
static mutex mutex_;
#endif
singleton() {}
public:
static T& instance()
{
if (! pInstance_)
{ {
throw std::runtime_error("dead reference!");
}
static void DestroySingleton()
{
CreatePolicy<T>::destroy(pInstance_);
pInstance_ = 0;
destroyed_ = true;
}
protected:
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
mutex::scoped_lock lock(mutex_); static mutex mutex_;
#endif #endif
singleton() {}
public:
static T& instance()
{
if (! pInstance_) if (! pInstance_)
{ {
if (destroyed_) #ifdef MAPNIK_THREADSAFE
mutex::scoped_lock lock(mutex_);
#endif
if (! pInstance_)
{ {
destroyed_ = false; if (destroyed_)
onDeadReference(); {
} destroyed_ = false;
else onDeadReference();
{ }
pInstance_ = CreatePolicy<T>::create(); else
{
pInstance_ = CreatePolicy<T>::create();
// register destruction // register destruction
std::atexit(&DestroySingleton); std::atexit(&DestroySingleton);
}
} }
} }
return *pInstance_;
} }
return *pInstance_; };
}
};
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
template <typename T, template <typename T,
template <typename U> class CreatePolicy> mutex singleton<T,CreatePolicy>::mutex_; template <typename U> class CreatePolicy> mutex singleton<T,CreatePolicy>::mutex_;
#endif #endif
template <typename T, template <typename T,
template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0; template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
template <typename T, template <typename T,
template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false; template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
#ifdef _WINDOWS
#include <windows.h>
// UTF8 <--> UTF16 conversion routines
std::string utf16_to_utf8(std::wstring const& wstr)
{
std::string str;
int size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0);
if(size > 0)
{
std::vector<char> buffer(size);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], size, 0, 0);
str.assign(buffer.begin(), buffer.end() - 1);
}
return str;
}
std::wstring utf8_to_utf16 (std::string const& str)
{
std::wstring wstr;
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
if (size > 0)
{
std::vector<wchar_t> buffer(size);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], size);
wstr.assign(buffer.begin(), buffer.end() - 1);
}
return wstr;
}
#endif // _WINDOWS
} }