comparison 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
comparison
equal deleted inserted replaced
2325:8198a9fa2553 2326:423d3b692bb9
35 #include "Toolbox.h" 35 #include "Toolbox.h"
36 36
37 #include "OrthancException.h" 37 #include "OrthancException.h"
38 #include "Logging.h" 38 #include "Logging.h"
39 39
40 #include <boost/algorithm/string/case_conv.hpp>
40 #include <boost/algorithm/string/replace.hpp> 41 #include <boost/algorithm/string/replace.hpp>
41 #include <boost/lexical_cast.hpp> 42 #include <boost/lexical_cast.hpp>
42 #include <boost/locale.hpp> 43 #include <boost/locale.hpp>
43 #include <boost/uuid/sha1.hpp> 44 #include <boost/uuid/sha1.hpp>
44 45
45 #include <string> 46 #include <string>
46 #include <stdint.h> 47 #include <stdint.h>
47 #include <string.h> 48 #include <string.h>
48 #include <algorithm> 49 #include <algorithm>
49 #include <ctype.h> 50 #include <ctype.h>
1249 return false; 1250 return false;
1250 } 1251 }
1251 1252
1252 return IsUuid(str.substr(0, 36)); 1253 return IsUuid(str.substr(0, 36));
1253 } 1254 }
1255
1256
1257 static std::auto_ptr<std::locale> globalLocale_;
1258
1259 void Toolbox::InitializeGlobalLocale()
1260 {
1261 // Make Orthanc use English, United States locale
1262
1263 #if defined(_WIN32)
1264 // For Windows: use default locale (one might use "en-US" instead)
1265 static const char* DEFAULT_LOCALE = NULL;
1266 #else
1267 // For Linux & cie
1268 static const char* DEFAULT_LOCALE = "en_US.UTF-8";
1269 #endif
1270
1271 try
1272 {
1273 if (DEFAULT_LOCALE == NULL)
1274 {
1275 globalLocale_.reset(new std::locale());
1276 }
1277 else
1278 {
1279 globalLocale_.reset(new std::locale(DEFAULT_LOCALE));
1280 }
1281 }
1282 catch (std::runtime_error& e)
1283 {
1284 LOG(ERROR) << "Cannot initialize global locale as \"" << DEFAULT_LOCALE << "\"";
1285 throw OrthancException(ErrorCode_InternalError);
1286 }
1287 }
1288
1289
1290 void Toolbox::FinalizeGlobalLocale()
1291 {
1292 globalLocale_.reset();
1293 }
1294
1295
1296 std::string Toolbox::ToUpperCaseWithAccents(const std::string& source)
1297 {
1298 if (globalLocale_.get() == NULL)
1299 {
1300 LOG(ERROR) << "No global locale was set, call Toolbox::InitializeGlobalLocale()";
1301 throw OrthancException(ErrorCode_BadSequenceOfCalls);
1302 }
1303
1304 /**
1305 * A few notes about locales:
1306 *
1307 * (1) We don't use "case folding":
1308 * http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/conversions.html
1309 *
1310 * Characters are made uppercase one by one. This is because, in
1311 * static builds, we are using iconv, which is visibly not
1312 * supported correctly (TODO: Understand why). Case folding seems
1313 * to be working correctly if using the default backend under
1314 * Linux (ICU or POSIX?). If one wishes to use case folding, one
1315 * would use:
1316 *
1317 * boost::locale::generator gen;
1318 * std::locale::global(gen(DEFAULT_LOCALE));
1319 * return boost::locale::to_upper(source);
1320 *
1321 * (2) The function "boost::algorithm::to_upper_copy" does not
1322 * make use of the "std::locale::global()". We therefore create a
1323 * global variable "globalLocale_".
1324 *
1325 * (3) The variant of "boost::algorithm::to_upper_copy()" that
1326 * uses std::string does not work properly. We need to apply it
1327 * one wide strings (std::wstring). This explains the two calls to
1328 * "utf_to_utf" in order to convert to/from std::wstring.
1329 **/
1330
1331 std::wstring w = boost::locale::conv::utf_to_utf<wchar_t>(source);
1332 w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_);
1333 return boost::locale::conv::utf_to_utf<char>(w);
1334 }
1254 } 1335 }