Mercurial > hg > orthanc
changeset 3339:d59521c395d9
Merged in TomasZubiri/orthanc/TomasZubiri/minor-typo-in-comments-1553026669603 (pull request #9)
minor: typo in comments
author | Sébastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 04 Apr 2019 14:02:55 +0000 |
parents | 9c8e119d0c5b (diff) d00db444a3a3 (current diff) |
children | ca65e3dcce72 |
files | |
diffstat | 16 files changed, 421 insertions(+), 97 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Tue Mar 19 20:17:58 2019 +0000 +++ b/.hgignore Thu Apr 04 14:02:55 2019 +0000 @@ -4,4 +4,5 @@ *.cpp.orig *.h.orig .vs/ +.vscode/ *~
--- a/CMakeLists.txt Tue Mar 19 20:17:58 2019 +0000 +++ b/CMakeLists.txt Thu Apr 04 14:02:55 2019 +0000 @@ -123,6 +123,7 @@ UnitTestsSources/SQLiteTests.cpp UnitTestsSources/ServerIndexTests.cpp UnitTestsSources/StreamTests.cpp + UnitTestsSources/ToolboxTests.cpp UnitTestsSources/UnitTestsMain.cpp UnitTestsSources/VersionsTests.cpp UnitTestsSources/ZipTests.cpp @@ -192,6 +193,7 @@ ${ORTHANC_EMBEDDED_FILES} ORTHANC_EXPLORER ${CMAKE_CURRENT_SOURCE_DIR}/OrthancExplorer ${DCMTK_DICTIONARIES} + ${LIBICU_RESOURCES} ) else() add_definitions( @@ -200,6 +202,7 @@ ) EmbedResources( ${ORTHANC_EMBEDDED_FILES} + ${LIBICU_RESOURCES} ) endif() @@ -332,6 +335,7 @@ ${GOOGLE_TEST_SOURCES} ${ORTHANC_UNIT_TESTS_PCH} ${ORTHANC_UNIT_TESTS_SOURCES} + ${BOOST_EXTENDED_SOURCES} ) target_link_libraries(UnitTests
--- a/Core/DicomNetworking/DicomServer.cpp Tue Mar 19 20:17:58 2019 +0000 +++ b/Core/DicomNetworking/DicomServer.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -328,7 +328,7 @@ if (cond.bad()) { throw OrthancException(ErrorCode_DicomPortInUse, - "cannot create network: " + std::string(cond.text())); + " (port = " + boost::lexical_cast<std::string>(port_) + ") cannot create network: " + std::string(cond.text())); } continue_ = true;
--- a/Core/HttpServer/HttpServer.cpp Tue Mar 19 20:17:58 2019 +0000 +++ b/Core/HttpServer/HttpServer.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -1056,7 +1056,8 @@ if (!pimpl_->context_) { - throw OrthancException(ErrorCode_HttpPortInUse); + throw OrthancException(ErrorCode_HttpPortInUse, + " (port = " + boost::lexical_cast<std::string>(port_) + ")"); } LOG(WARNING) << "HTTP server listening on port: " << GetPortNumber()
--- a/Core/Toolbox.cpp Tue Mar 19 20:17:58 2019 +0000 +++ b/Core/Toolbox.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -115,6 +115,36 @@ } +#if defined(ORTHANC_STATIC_ICU) +# if (ORTHANC_STATIC_ICU == 1 && ORTHANC_ENABLE_LOCALE == 1) +# include <EmbeddedResources.h> +# include <unicode/udata.h> +# include <unicode/uloc.h> +# include "Compression/GzipCompressor.h" + +static std::string globalIcuData_; + +extern "C" +{ + // This is dummy content for the "icudt58_dat" (resp. "icudt63_dat") + // global variable from the autogenerated "icudt58l_dat.c" + // (resp. "icudt63l_dat.c") file that contains a huge C array. In + // Orthanc, this array is compressed using gzip and attached as a + // resource, then uncompressed during the launch of Orthanc by + // static function "InitializeIcu()". + struct + { + double bogus; + uint8_t *bytes; + } U_ICUDATA_ENTRY_POINT = { 0.0, NULL }; +} + +# endif +#endif + + + + namespace Orthanc { @@ -398,7 +428,8 @@ void Toolbox::EncodeBase64(std::string& result, const std::string& data) { - result = base64_encode(data); + result.clear(); + base64_encode(result, data); } void Toolbox::DecodeBase64(std::string& result, @@ -416,7 +447,8 @@ } } - result = base64_decode(data); + result.clear(); + base64_decode(result, data); } @@ -445,7 +477,8 @@ const std::string& mime, const std::string& content) { - result = "data:" + mime + ";base64," + base64_encode(content); + result = "data:" + mime + ";base64,"; + base64_encode(result, content); } #endif @@ -527,6 +560,14 @@ Encoding sourceEncoding, bool hasCodeExtensions) { +#if ORTHANC_STATIC_ICU == 1 + if (globalIcuData_.empty()) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls, + "Call Toolbox::InitializeGlobalLocale()"); + } +#endif + // The "::skip" flag makes boost skip invalid UTF-8 // characters. This can occur in badly-encoded DICOM files. @@ -578,6 +619,14 @@ std::string Toolbox::ConvertFromUtf8(const std::string& source, Encoding targetEncoding) { +#if ORTHANC_STATIC_ICU == 1 + if (globalIcuData_.empty()) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls, + "Call Toolbox::InitializeGlobalLocale()"); + } +#endif + // The "::skip" flag makes boost skip invalid UTF-8 // characters. This can occur in badly-encoded DICOM files. @@ -1377,9 +1426,107 @@ return (globalLocale_.get() != NULL); } + + + static void InitializeIcu() + { +#if ORTHANC_STATIC_ICU == 1 + if (globalIcuData_.empty()) + { + LOG(INFO) << "Setting up the ICU common data"; + + GzipCompressor compressor; + compressor.Uncompress(globalIcuData_, + EmbeddedResources::GetFileResourceBuffer(EmbeddedResources::LIBICU_DATA), + EmbeddedResources::GetFileResourceSize(EmbeddedResources::LIBICU_DATA)); + + std::string md5; + Toolbox::ComputeMD5(md5, globalIcuData_); + + if (md5 != ORTHANC_ICU_DATA_MD5 || + globalIcuData_.empty()) + { + throw OrthancException(ErrorCode_InternalError, + "Cannot decode the ICU common data"); + } + + // "ICU data is designed to be 16-aligned" + // http://userguide.icu-project.org/icudata#TOC-Alignment + + { + static const size_t ALIGN = 16; + + UErrorCode status = U_ZERO_ERROR; + + if (reinterpret_cast<intptr_t>(globalIcuData_.c_str()) % ALIGN == 0) + { + // Data is already properly aligned + udata_setCommonData(globalIcuData_.c_str(), &status); + } + else + { + std::string aligned; + aligned.resize(globalIcuData_.size() + ALIGN - 1); + + intptr_t offset = reinterpret_cast<intptr_t>(aligned.c_str()) % ALIGN; + if (offset != 0) + { + offset = ALIGN - offset; + } + + if (offset + globalIcuData_.size() > aligned.size()) + { + throw OrthancException(ErrorCode_InternalError, "Cannot align on 16-bytes boundary"); + } + + // We don't use "memcpy()", as it expects its data to be aligned + const uint8_t* p = reinterpret_cast<uint8_t*>(&globalIcuData_[0]); + uint8_t* q = reinterpret_cast<uint8_t*>(&aligned[0]) + offset; + for (size_t i = 0; i < globalIcuData_.size(); i++, p++, q++) + { + *q = *p; + } + + globalIcuData_.swap(aligned); + + const uint8_t* data = reinterpret_cast<const uint8_t*>(globalIcuData_.c_str()) + offset; + + if (reinterpret_cast<intptr_t>(data) % ALIGN != 0) + { + throw OrthancException(ErrorCode_InternalError, "Cannot align on 16-bytes boundary"); + } + else + { + udata_setCommonData(data, &status); + } + } + + if (status != U_ZERO_ERROR) + { + throw OrthancException(ErrorCode_InternalError, "Cannot initialize ICU"); + } + } + + if (Toolbox::DetectEndianness() != Endianness_Little) + { + // TODO - The data table must be swapped (uint16_t) + throw OrthancException(ErrorCode_NotImplemented); + } + + // "First-use of ICU from a single thread before the + // multi-threaded use of ICU begins", to make sure everything is + // properly initialized (should not be mandatory in our + // case). We let boost handle calls to "u_init()" and "u_cleanup()". + // http://userguide.icu-project.org/design#TOC-ICU-Initialization-and-Termination + uloc_getDefault(); + } +#endif + } void Toolbox::InitializeGlobalLocale(const char* locale) { + InitializeIcu(); + // Make Orthanc use English, United States locale // Linux: use "en_US.UTF-8" // Windows: use "" @@ -1431,7 +1578,16 @@ std::string Toolbox::ToUpperCaseWithAccents(const std::string& source) { - if (globalLocale_.get() == NULL) + bool error = (globalLocale_.get() == NULL); + +#if ORTHANC_STATIC_ICU == 1 + if (globalIcuData_.empty()) + { + error = true; + } +#endif + + if (error) { throw OrthancException(ErrorCode_BadSequenceOfCalls, "No global locale was set, call Toolbox::InitializeGlobalLocale()"); @@ -1818,7 +1974,8 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - const uint8_t* buffer = reinterpret_cast<const uint8_t*>(utf8.c_str()); + assert(sizeof(uint8_t) == sizeof(char)); + const uint8_t* buffer = reinterpret_cast<const uint8_t*>(utf8.c_str()) + position; if ((buffer[0] & MASK_IS_1_BYTE) == TEST_IS_1_BYTE) { @@ -1861,7 +2018,7 @@ else { // This is not a valid UTF-8 encoding - throw OrthancException(ErrorCode_BadFileFormat); + throw OrthancException(ErrorCode_BadFileFormat, "Invalid UTF-8 string"); } } }
--- a/NEWS Tue Mar 19 20:17:58 2019 +0000 +++ b/NEWS Thu Apr 04 14:02:55 2019 +0000 @@ -1,6 +1,8 @@ Pending changes in the mainline =============================== +* Size of the Orthanc static binaries are reduced by compressing ICU data + Version 1.5.6 (2019-03-01) ==========================
--- a/OrthancExplorer/explorer.html Tue Mar 19 20:17:58 2019 +0000 +++ b/OrthancExplorer/explorer.html Thu Apr 04 14:02:55 2019 +0000 @@ -508,6 +508,7 @@ <input type="checkbox" name="XA" id="qr-xa" class="custom" /> <label for="qr-xa">XA</label> <input type="checkbox" name="DR" id="qr-dr" class="custom" /> <label for="qr-dr">DR</label> <input type="checkbox" name="DX" id="qr-dx" class="custom" /> <label for="qr-dx">DX</label> + <input type="checkbox" name="MG" id="qr-mg" class="custom" /> <label for="qr-mg">MG</label> </fieldset> </div> </div>
--- a/Resources/CMake/LibIcuConfiguration.cmake Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/CMake/LibIcuConfiguration.cmake Thu Apr 04 14:02:55 2019 +0000 @@ -10,31 +10,17 @@ include(${CMAKE_CURRENT_LIST_DIR}/../ThirdParty/icu/Version.cmake) DownloadPackage(${LIBICU_MD5} ${LIBICU_URL} "${LIBICU_SOURCES_DIR}") - if (MSVC AND - CMAKE_SIZEOF_VOID_P EQUAL 8) - # In Visual Studio 2015 64bit, we get the following error if using - # the plain C version of the ICU data: "icudt58l_dat.c(1638339): - # fatal error C1060: compiler is out of heap space" => we use a - # precompiled binary generated using MinGW on Linux - DownloadCompressedFile(${LIBICU_DATA_WIN64_MD5} ${LIBICU_DATA_WIN64_URL} ${LIBICU_DATA_WIN64}) + # Use the gzip-compressed data + DownloadFile(${LIBICU_DATA_COMPRESSED_MD5} ${LIBICU_DATA_URL}) + set(LIBICU_RESOURCES + LIBICU_DATA ${CMAKE_SOURCE_DIR}/ThirdPartyDownloads/${LIBICU_DATA} + ) - set(LIBICU_LIBRARIES - ${CMAKE_BINARY_DIR}/${LIBICU_DATA_WIN64} - ) - else() - # Use plain C data library - DownloadCompressedFile(${LIBICU_DATA_MD5} ${LIBICU_DATA_URL} ${LIBICU_DATA}) + set_source_files_properties( + ${CMAKE_BINARY_DIR}/${LIBICU_DATA} + PROPERTIES COMPILE_DEFINITIONS "char16_t=uint16_t" + ) - set_source_files_properties( - ${CMAKE_BINARY_DIR}/${LIBICU_DATA} - PROPERTIES COMPILE_DEFINITIONS "char16_t=uint16_t" - ) - - set(LIBICU_SOURCES - ${CMAKE_BINARY_DIR}/${LIBICU_DATA} - ) - endif() - include_directories(BEFORE ${LIBICU_SOURCES_DIR}/source/common ${LIBICU_SOURCES_DIR}/source/i18n @@ -50,6 +36,7 @@ #-DUCONFIG_NO_SERVICE=1 -DU_COMMON_IMPLEMENTATION + -DU_STATIC_IMPLEMENTATION -DU_ENABLE_DYLOAD=0 -DU_HAVE_STD_STRING=1 -DU_I18N_IMPLEMENTATION @@ -57,6 +44,9 @@ -DU_STATIC_IMPLEMENTATION=1 #-DU_CHARSET_IS_UTF8 -DUNISTR_FROM_STRING_EXPLICIT= + + -DORTHANC_STATIC_ICU=1 + -DORTHANC_ICU_DATA_MD5="${LIBICU_DATA_UNCOMPRESSED_MD5}" ) if (CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -83,4 +73,8 @@ else() link_libraries(icuuc icui18n) endif() + + add_definitions( + -DORTHANC_STATIC_ICU=0 + ) endif()
--- a/Resources/CMake/LuaConfiguration.cmake Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/CMake/LuaConfiguration.cmake Thu Apr 04 14:02:55 2019 +0000 @@ -101,9 +101,9 @@ source_group(ThirdParty\\Lua REGULAR_EXPRESSION ${LUA_SOURCES_DIR}/.*) else() - include(FindLua51) + include(FindLua) - if (NOT LUA51_FOUND) + if (NOT LUA_FOUND) message(FATAL_ERROR "Please install the liblua-dev package") endif()
--- a/Resources/CMake/UuidConfiguration.cmake Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/CMake/UuidConfiguration.cmake Thu Apr 04 14:02:55 2019 +0000 @@ -114,12 +114,18 @@ message(FATAL_ERROR "Please install uuid-dev, e2fsprogs (OpenBSD) or e2fsprogs-libuuid (FreeBSD)") endif() - check_library_exists(uuid uuid_generate_random "" HAVE_UUID_LIB) - if (NOT HAVE_UUID_LIB) + find_library(LIBUUID uuid + PATHS + /usr/lib + /usr/local/lib + ) + + check_library_exists(${LIBUUID} uuid_generate_random "" HAVE_LIBUUID) + if (NOT HAVE_LIBUUID) message(FATAL_ERROR "Unable to find the uuid library") endif() - link_libraries(uuid) + link_libraries(${LIBUUID}) endif() endif()
--- a/Resources/ThirdParty/base64/base64.cpp Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/ThirdParty/base64/base64.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -23,28 +23,32 @@ René Nyffenegger rene.nyffenegger@adp-gmbh.ch + ------------------------------ + This version has been modified (changed the interface + use another decoding algorithm + inspired from https://stackoverflow.com/a/34571089 which was faster) */ #include "base64.h" #include <string.h> +#include <vector> static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } -std::string base64_encode(const std::string& stringToEncode) +void base64_encode(std::string& result, const std::string& stringToEncode) { const unsigned char* bytes_to_encode = reinterpret_cast<const unsigned char*> - (stringToEncode.size() > 0 ? &stringToEncode[0] : NULL); - unsigned int in_len = stringToEncode.size(); + (stringToEncode.size() > 0 ? &stringToEncode[0] : NULL); + size_t in_len = stringToEncode.size(); - std::string ret; + result.reserve(result.size() + in_len * 4 / 3 + 10); + int i = 0; int j = 0; unsigned char char_array_3[3]; @@ -59,7 +63,7 @@ char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; + result += base64_chars[char_array_4[i]]; i = 0; } } @@ -75,24 +79,23 @@ char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; + result += base64_chars[char_array_4[j]]; while((i++ < 3)) - ret += '='; + result += '='; } - - return ret; } - -std::string base64_decode(const std::string& encoded_string) { - int in_len = encoded_string.size(); +// old code from René Nyffenegger. This code is slower +void base64_decode_old(std::string& result, const std::string& encoded_string) { + size_t in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; - std::string ret; + + result.reserve(result.size() + in_len * 3 / 4 + 10); while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; @@ -105,7 +108,7 @@ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) - ret += char_array_3[i]; + result += char_array_3[i]; i = 0; } } @@ -121,8 +124,56 @@ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + for (j = 0; (j < i - 1); j++) + result += char_array_3[j]; } +} + + +// new code from https://stackoverflow.com/a/34571089 +// note that the encoding algorithm from this page was slower (and bugged !) +// this code is not using std::vector::find + +// static init equivalent to: +// decode_indexes.assign(256, -1); +// for (int i=0; i<64; ++i) +// decode_indexes[base64_chars[i]] = i; - return ret; +static const int decode_indexes[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + + +void base64_decode(std::string& result, const std::string &stringToDecode) { + + result.reserve(result.size() + stringToDecode.size() * 3 / 4 + 10); + + int val=0, valb=-8; + for (std::string::const_iterator c = stringToDecode.begin(); c != stringToDecode.end(); ++c) + { + size_t index = static_cast<size_t>(*c); + if (decode_indexes[index] == -1) + break; + val = (val<<6) + decode_indexes[index]; + valb += 6; + if (valb>=0) { + result.push_back(char((val>>valb)&0xFF)); + valb-=8; + } + } }
--- a/Resources/ThirdParty/base64/base64.h Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/ThirdParty/base64/base64.h Thu Apr 04 14:02:55 2019 +0000 @@ -1,4 +1,4 @@ #include <string> -std::string base64_encode(const std::string& stringToEncode); -std::string base64_decode(const std::string& s); +void base64_encode(std::string& result, const std::string& stringToEncode); +void base64_decode(std::string& result, const std::string& s);
--- a/Resources/ThirdParty/icu/Version.cmake Tue Mar 19 20:17:58 2019 +0000 +++ b/Resources/ThirdParty/icu/Version.cmake Thu Apr 04 14:02:55 2019 +0000 @@ -14,24 +14,21 @@ set(LIBICU_BASE_URL "http://orthanc.osimis.io/ThirdPartyDownloads") if (USE_LEGACY_LIBICU) - # This is the last version of icu that compiles with C++11 - # support. It can be used for Linux Standard Base and Visual Studio 2008. + # This is the latest version of icu that compiles without C++11 + # support. It is used for Linux Standard Base and Visual Studio 2008. set(LIBICU_URL "${LIBICU_BASE_URL}/icu4c-58_2-src.tgz") set(LIBICU_MD5 "fac212b32b7ec7ab007a12dff1f3aea1") set(LIBICU_DATA_VERSION "icudt58") - set(LIBICU_DATA_MD5 "ce2c7791ab637898553c121633155fb6") - set(LIBICU_DATA_WIN64_MD5 "8f7edfce3bff7edb0e5714cb66f891cb") + set(LIBICU_DATA_COMPRESSED_MD5 "a39b07b38195158c6c3070332cef2173") + set(LIBICU_DATA_UNCOMPRESSED_MD5 "54d2593cec5c6a4469373231658153ce") else() set(LIBICU_URL "${LIBICU_BASE_URL}/icu4c-63_1-src.tgz") set(LIBICU_MD5 "9e40f6055294284df958200e308bce50") set(LIBICU_DATA_VERSION "icudt63") - set(LIBICU_DATA_MD5 "92b5c73a1accd8ecf8c20c89bc6925a9") - set(LIBICU_DATA_WIN64_MD5 "edc00315f042c802547d8e4bd95b09f7") + set(LIBICU_DATA_COMPRESSED_MD5 "be495c0830de5f377fdfa8301a5faf3d") + set(LIBICU_DATA_UNCOMPRESSED_MD5 "99613c3f2ca9426c45dc554ad28cfb79") endif() set(LIBICU_SOURCES_DIR ${CMAKE_BINARY_DIR}/icu) -set(LIBICU_DATA "${LIBICU_DATA_VERSION}${LIBICU_SUFFIX}_dat.c") -set(LIBICU_DATA_URL "${LIBICU_BASE_URL}/${LIBICU_DATA}.gz") - -set(LIBICU_DATA_WIN64 "${LIBICU_DATA_VERSION}_dat-x86_64-mingw32.lib") -set(LIBICU_DATA_WIN64_URL "${LIBICU_BASE_URL}/${LIBICU_DATA_WIN64}.gz") +set(LIBICU_DATA "${LIBICU_DATA_VERSION}${LIBICU_SUFFIX}.dat.gz") +set(LIBICU_DATA_URL "${LIBICU_BASE_URL}/${LIBICU_DATA}")
--- a/TODO Tue Mar 19 20:17:58 2019 +0000 +++ b/TODO Thu Apr 04 14:02:55 2019 +0000 @@ -64,6 +64,8 @@ Short-term ---------- +* Support "Retrieve AE Title" (0008,0054) in C-FIND: + https://groups.google.com/d/msg/orthanc-users/wPl0g5mqZco/5X1Z8tEzBgAJ * Support C-GET: http://dclunie.blogspot.be/2016/05/to-c-move-is-human-to-c-get-divine.html * Check Big Endian transfer syntax in ParsedDicomFile::EmbedImage and
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UnitTestsSources/ToolboxTests.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -0,0 +1,136 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "PrecompiledHeadersUnitTests.h" +#include "gtest/gtest.h" +#include "../Core/OrthancException.h" +#include "../Core/Toolbox.h" + +using namespace Orthanc; + +TEST(Toolbox, Base64_allByteValues) +{ + std::string toEncode; + std::string base64Result; + std::string decodedResult; + + size_t size = 2*256; + toEncode.reserve(size); + for (size_t i = 0; i < size; i++) + toEncode.push_back(i % 256); + + Toolbox::EncodeBase64(base64Result, toEncode); + Toolbox::DecodeBase64(decodedResult, base64Result); + + ASSERT_EQ(toEncode, decodedResult); +} + +TEST(Toolbox, Base64_multipleSizes) +{ + std::string toEncode; + std::string base64Result; + std::string decodedResult; + + for (size_t size = 0; size <= 5; size++) + { + printf("base64, testing size %zu\n", size); + toEncode.clear(); + toEncode.reserve(size); + for (size_t i = 0; i < size; i++) + toEncode.push_back(i % 256); + + Toolbox::EncodeBase64(base64Result, toEncode); + Toolbox::DecodeBase64(decodedResult, base64Result); + + ASSERT_EQ(toEncode, decodedResult); + } +} + +static std::string EncodeBase64Bis(const std::string& s) +{ + std::string result; + Toolbox::EncodeBase64(result, s); + return result; +} + + +TEST(Toolbox, Base64) +{ + ASSERT_EQ("", EncodeBase64Bis("")); + ASSERT_EQ("YQ==", EncodeBase64Bis("a")); + + const std::string hello = "SGVsbG8gd29ybGQ="; + ASSERT_EQ(hello, EncodeBase64Bis("Hello world")); + + std::string decoded; + Toolbox::DecodeBase64(decoded, hello); + ASSERT_EQ("Hello world", decoded); + + // Invalid character + ASSERT_THROW(Toolbox::DecodeBase64(decoded, "?"), OrthancException); + + // All the allowed characters + Toolbox::DecodeBase64(decoded, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); +} + + +#if 0 // enable only when compiling in Release with a C++ 11 compiler +#include <chrono> // I had troubles to link with boost::chrono ... + +TEST(Toolbox, Base64_largeString) +{ + std::string toEncode; + std::string base64Result; + std::string decodedResult; + + size_t size = 10 * 1024 * 1024; + toEncode.reserve(size); + for (size_t i = 0; i < size; i++) + toEncode.push_back(i % 256); + + std::chrono::high_resolution_clock::time_point start; + std::chrono::high_resolution_clock::time_point afterEncoding; + std::chrono::high_resolution_clock::time_point afterDecoding; + + start = std::chrono::high_resolution_clock::now(); + Orthanc::Toolbox::EncodeBase64(base64Result, toEncode); + afterEncoding = std::chrono::high_resolution_clock::now(); + Orthanc::Toolbox::DecodeBase64(decodedResult, base64Result); + afterDecoding = std::chrono::high_resolution_clock::now(); + + ASSERT_EQ(toEncode, decodedResult); + + printf("encoding took %zu ms\n", (std::chrono::duration_cast<std::chrono::milliseconds>(afterEncoding - start))); + printf("decoding took %zu ms\n", (std::chrono::duration_cast<std::chrono::milliseconds>(afterDecoding - afterEncoding))); +} +#endif
--- a/UnitTestsSources/UnitTestsMain.cpp Tue Mar 19 20:17:58 2019 +0000 +++ b/UnitTestsSources/UnitTestsMain.cpp Thu Apr 04 14:02:55 2019 +0000 @@ -374,34 +374,6 @@ ASSERT_EQ("da39a3ee-5e6b4b0d-3255bfef-95601890-afd80709", s); } - -static std::string EncodeBase64Bis(const std::string& s) -{ - std::string result; - Toolbox::EncodeBase64(result, s); - return result; -} - - -TEST(Toolbox, Base64) -{ - ASSERT_EQ("", EncodeBase64Bis("")); - ASSERT_EQ("YQ==", EncodeBase64Bis("a")); - - const std::string hello = "SGVsbG8gd29ybGQ="; - ASSERT_EQ(hello, EncodeBase64Bis("Hello world")); - - std::string decoded; - Toolbox::DecodeBase64(decoded, hello); - ASSERT_EQ("Hello world", decoded); - - // Invalid character - ASSERT_THROW(Toolbox::DecodeBase64(decoded, "?"), OrthancException); - - // All the allowed characters - Toolbox::DecodeBase64(decoded, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); -} - TEST(Toolbox, PathToExecutable) { printf("[%s]\n", SystemToolbox::GetPathToExecutable().c_str());