changeset 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 8198a9fa2553
children eedcddb42767
files CMakeLists.txt Core/Toolbox.cpp Core/Toolbox.h NEWS OrthancServer/OrthancInitialization.cpp Resources/CMake/BoostConfiguration.cmake Resources/CMake/BoostConfiguration.sh Resources/CMake/LibIconvConfiguration.cmake Resources/EncodingTests.h Resources/EncodingTests.py UnitTestsSources/FromDcmtkTests.cpp
diffstat 11 files changed, 133 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Fri Jul 14 11:43:06 2017 +0200
+++ b/CMakeLists.txt	Fri Jul 14 15:53:04 2017 +0200
@@ -69,6 +69,7 @@
 # Path to the root folder of the Orthanc distribution
 set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR})
 set(ENABLE_DCMTK_NETWORK ON)
+set(USE_BOOST_LOCALE_BACKEND OFF)
 
 # Some basic inclusions
 include(CheckIncludeFiles)
--- 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);
+  }
 }
--- a/Core/Toolbox.h	Fri Jul 14 11:43:06 2017 +0200
+++ b/Core/Toolbox.h	Fri Jul 14 15:53:04 2017 +0200
@@ -206,5 +206,11 @@
     bool IsUuid(const std::string& str);
 
     bool StartsWithUuid(const std::string& str);
+
+    void InitializeGlobalLocale();
+
+    void FinalizeGlobalLocale();
+
+    std::string ToUpperCaseWithAccents(const std::string& source);
   }
 }
--- a/NEWS	Fri Jul 14 11:43:06 2017 +0200
+++ b/NEWS	Fri Jul 14 15:53:04 2017 +0200
@@ -5,7 +5,13 @@
 -------
 
 * Orthanc now anonymizes according to Basic Profile of PS 3.15-2017c Table E.1-1
-
+* In the "DicomModalities" configuration:
+  - Manufacturer type MedInria is now obsolete
+  - Manufacturer types AgfaImpax and SyngoVia are obsolete too,
+    use GenericNoWildcardInDates instead
+  - Obsolete manufacturers are still accepted but might disappear in the future
+  - Added new manufacturer: GenericNoWidlcards to replace all '*' by '' in
+    outgoing C-Find requests
 
 REST API
 --------
@@ -28,13 +34,6 @@
 
 * Query/retrieve: Added button for "DR" modality
 
-Configuration file
-------------------
-* Manufacturer type MedInria is now obsolete
-  Manufacturer type AgfaImpax & SyngoVia are obsolete too, use GenericNoWildcardInDates instead
-  obsolete manufacturers are still accepted but might disappear in the future
-  added new manufacturer: GenericNoWidlcards to replace all '*' by '' in outgoing C-Find requests
-
 Maintenance
 -----------
 
@@ -51,6 +50,7 @@
 * Fix Debian #865606 (orthanc FTBFS with libdcmtk-dev 3.6.1~20170228-2)
 * Fix XSS inside DICOM in Orthanc Explorer (as reported by Victor Pasnkel, Morphus Labs)
 * Upgrade forthcoming DCMTK 3.6.1 to snapshot 20170228
+* Upgrade to Boost 1.64.0 for static builds
 
 
 Version 1.2.0 (2016/12/13)
--- a/OrthancServer/OrthancInitialization.cpp	Fri Jul 14 11:43:06 2017 +0200
+++ b/OrthancServer/OrthancInitialization.cpp	Fri Jul 14 15:53:04 2017 +0200
@@ -464,6 +464,7 @@
   {
     boost::recursive_mutex::scoped_lock lock(globalMutex_);
 
+    Toolbox::InitializeGlobalLocale();
     HttpClient::InitializeOpenSsl();
 
     InitializeServerEnumerations();
@@ -519,6 +520,7 @@
 #endif
 
     HttpClient::FinalizeOpenSsl();
+    Toolbox::FinalizeGlobalLocale();
   }
 
 
--- a/Resources/CMake/BoostConfiguration.cmake	Fri Jul 14 11:43:06 2017 +0200
+++ b/Resources/CMake/BoostConfiguration.cmake	Fri Jul 14 15:53:04 2017 +0200
@@ -39,10 +39,10 @@
 
 
 if (BOOST_STATIC)
-  # Parameters for Boost 1.60.0
-  set(BOOST_NAME boost_1_60_0)
-  set(BOOST_BCP_SUFFIX bcpdigest-1.0.1)
-  set(BOOST_MD5 "a789f8ec2056ad1c2d5f0cb64687cc7b")
+  # Parameters for Boost 1.64.0
+  set(BOOST_NAME boost_1_64_0)
+  set(BOOST_BCP_SUFFIX bcpdigest-1.2.1)
+  set(BOOST_MD5 "ecb266cf46adcc7f695ad12685871174")
   set(BOOST_URL "http://www.orthanc-server.com/downloads/third-party/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz")
   set(BOOST_FILESYSTEM_SOURCES_DIR "${BOOST_NAME}/libs/filesystem/src") 
   set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})
@@ -150,7 +150,7 @@
       )
   endif()
 
-  if (USE_BOOST_LOCALE_BACKENDS)
+  if (USE_BOOST_LOCALE_BACKEND)
     if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
         ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
         ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
--- a/Resources/CMake/BoostConfiguration.sh	Fri Jul 14 11:43:06 2017 +0200
+++ b/Resources/CMake/BoostConfiguration.sh	Fri Jul 14 15:53:04 2017 +0200
@@ -15,22 +15,23 @@
 ##   - Orthanc between 0.7.4 and 0.9.1: Boost 1.55.0
 ##   - Orthanc between 0.9.2 and 0.9.4: Boost 1.58.0
 ##   - Orthanc between 0.9.5 and 1.0.0: Boost 1.59.0
-##   - Orthanc >= 1.0.1: Boost 1.60.0
+##   - Orthanc between 1.1.0 and 1.2.0: Boost 1.60.0
+##   - Orthanc >= 1.2.1: Boost 1.64.0
 
-rm -rf /tmp/boost_1_60_0
-rm -rf /tmp/bcp/boost_1_60_0
+rm -rf /tmp/boost_1_64_0
+rm -rf /tmp/bcp/boost_1_64_0
 
 cd /tmp
-echo "Uncompressing the sources of Boost 1.60.0..."
-tar xfz ./boost_1_60_0.tar.gz 
+echo "Uncompressing the sources of Boost 1.64.0..."
+tar xfz ./boost_1_64_0.tar.gz 
 
 echo "Generating the subset..."
-mkdir -p /tmp/bcp/boost_1_60_0
-bcp --boost=/tmp/boost_1_60_0 thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas /tmp/bcp/boost_1_60_0
+mkdir -p /tmp/bcp/boost_1_64_0
+bcp --boost=/tmp/boost_1_64_0 thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas /tmp/bcp/boost_1_64_0
 cd /tmp/bcp
 
 echo "Compressing the subset..."
-tar cfz boost_1_60_0_bcpdigest-1.0.1.tar.gz boost_1_60_0
-ls -l boost_1_60_0_bcpdigest-1.0.1.tar.gz
-md5sum boost_1_60_0_bcpdigest-1.0.1.tar.gz
-readlink -f boost_1_60_0_bcpdigest-1.0.1.tar.gz
+tar cfz boost_1_64_0_bcpdigest-1.2.1.tar.gz boost_1_64_0
+ls -l boost_1_64_0_bcpdigest-1.2.1.tar.gz
+md5sum boost_1_64_0_bcpdigest-1.2.1.tar.gz
+readlink -f boost_1_64_0_bcpdigest-1.2.1.tar.gz
--- a/Resources/CMake/LibIconvConfiguration.cmake	Fri Jul 14 11:43:06 2017 +0200
+++ b/Resources/CMake/LibIconvConfiguration.cmake	Fri Jul 14 15:53:04 2017 +0200
@@ -1,6 +1,6 @@
-set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.14)
-set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.14.tar.gz")
-set(LIBICONV_MD5 "e34509b1623cec449dfeb73d7ce9c6c6")
+set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.15)
+set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.15.tar.gz")
+set(LIBICONV_MD5 "ace8b5f2db42f7b3b3057585e80d9808")
 
 DownloadPackage(${LIBICONV_MD5} ${LIBICONV_URL} "${LIBICONV_SOURCES_DIR}")
 
--- a/Resources/EncodingTests.h	Fri Jul 14 11:43:06 2017 +0200
+++ b/Resources/EncodingTests.h	Fri Jul 14 15:53:04 2017 +0200
@@ -59,3 +59,5 @@
   "\xd0\xa2\xd0\xb0\xd0\xb7",
   "\xd0\x9f\xd1\x80\xd1\x8f\xd0\xbc\xd0\xb0\xd1\x8f"
 };
+static const char *toUpperSource = "\x67\x72\xc3\xbc\xc3\x9f\x45\x4e\x20\x53\xc3\xa9\x62\x61\x73\x54\x49\x65\x6e\x20\x54\x65\x73\x74\xc3\xa9\xc3\xa4\xc3\xb6\xc3\xb2\xd0\x94\xce\x98\xc4\x9d\xd7\x93\xd8\xb5\xc4\xb7\xd1\x9b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0";
+static const char *toUpperResult = "\x47\x52\xc3\x9c\xc3\x9f\x45\x4e\x20\x53\xc3\x89\x42\x41\x53\x54\x49\x45\x4e\x20\x54\x45\x53\x54\xc3\x89\xc3\x84\xc3\x96\xc3\x92\xd0\x94\xce\x98\xc4\x9c\xd7\x93\xd8\xb5\xc4\xb6\xd0\x8b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0";
--- a/Resources/EncodingTests.py	Fri Jul 14 11:43:06 2017 +0200
+++ b/Resources/EncodingTests.py	Fri Jul 14 15:53:04 2017 +0200
@@ -72,3 +72,9 @@
     for i in range(len(expected)):
         print expected[i]
         #print '%s: %s' % (expected[i], l[i])
+
+
+
+u = (u'grüßEN SébasTIen %s' % source)
+print 'static const char *toUpperSource = %s;' % ToArray(u.encode('utf-8'))
+print 'static const char *toUpperResult = %s;' % ToArray(u.upper().encode('utf-8'))
--- a/UnitTestsSources/FromDcmtkTests.cpp	Fri Jul 14 11:43:06 2017 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Fri Jul 14 15:53:04 2017 +0200
@@ -1217,3 +1217,9 @@
     }
   }
 }
+
+
+TEST(Toolbox, CaseWithAccents)
+{
+  ASSERT_EQ(toUpperResult, Toolbox::ToUpperCaseWithAccents(toUpperSource));
+}