Mercurial > hg > orthanc
diff Core/Toolbox.cpp @ 2326:423d3b692bb9
Upgrade to Boost 1.64.0, and Toolbox::ToUpperCaseWithAccents
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 Jul 2017 15:53:04 +0200 |
parents | a3a65de1840f |
children | 9c7a80c87ae9 |
line wrap: on
line diff
--- a/Core/Toolbox.cpp Fri Jul 14 11:43:06 2017 +0200 +++ b/Core/Toolbox.cpp Fri Jul 14 15:53:04 2017 +0200 @@ -37,11 +37,12 @@ #include "OrthancException.h" #include "Logging.h" +#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/replace.hpp> #include <boost/lexical_cast.hpp> #include <boost/locale.hpp> #include <boost/uuid/sha1.hpp> - + #include <string> #include <stdint.h> #include <string.h> @@ -1251,4 +1252,84 @@ return IsUuid(str.substr(0, 36)); } + + + static std::auto_ptr<std::locale> globalLocale_; + + void Toolbox::InitializeGlobalLocale() + { + // Make Orthanc use English, United States locale + +#if defined(_WIN32) + // For Windows: use default locale (one might use "en-US" instead) + static const char* DEFAULT_LOCALE = NULL; +#else + // For Linux & cie + static const char* DEFAULT_LOCALE = "en_US.UTF-8"; +#endif + + try + { + if (DEFAULT_LOCALE == NULL) + { + globalLocale_.reset(new std::locale()); + } + else + { + globalLocale_.reset(new std::locale(DEFAULT_LOCALE)); + } + } + catch (std::runtime_error& e) + { + LOG(ERROR) << "Cannot initialize global locale as \"" << DEFAULT_LOCALE << "\""; + throw OrthancException(ErrorCode_InternalError); + } + } + + + void Toolbox::FinalizeGlobalLocale() + { + globalLocale_.reset(); + } + + + std::string Toolbox::ToUpperCaseWithAccents(const std::string& source) + { + if (globalLocale_.get() == NULL) + { + LOG(ERROR) << "No global locale was set, call Toolbox::InitializeGlobalLocale()"; + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + + /** + * A few notes about locales: + * + * (1) We don't use "case folding": + * http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/conversions.html + * + * Characters are made uppercase one by one. This is because, in + * static builds, we are using iconv, which is visibly not + * supported correctly (TODO: Understand why). Case folding seems + * to be working correctly if using the default backend under + * Linux (ICU or POSIX?). If one wishes to use case folding, one + * would use: + * + * boost::locale::generator gen; + * std::locale::global(gen(DEFAULT_LOCALE)); + * return boost::locale::to_upper(source); + * + * (2) The function "boost::algorithm::to_upper_copy" does not + * make use of the "std::locale::global()". We therefore create a + * global variable "globalLocale_". + * + * (3) The variant of "boost::algorithm::to_upper_copy()" that + * uses std::string does not work properly. We need to apply it + * one wide strings (std::wstring). This explains the two calls to + * "utf_to_utf" in order to convert to/from std::wstring. + **/ + + std::wstring w = boost::locale::conv::utf_to_utf<wchar_t>(source); + w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_); + return boost::locale::conv::utf_to_utf<char>(w); + } }