# HG changeset patch # User Sebastien Jodogne # Date 1468576811 -7200 # Node ID 9362080e5e3de93807c3fdadafdc9fb3de5b35a2 # Parent 31615831e42d3d7142ec29bb55a2fe22cba40b58 sync diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/ChunkedBuffer.cpp --- a/Orthanc/Core/ChunkedBuffer.cpp Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/ChunkedBuffer.cpp Fri Jul 15 12:00:11 2016 +0200 @@ -51,17 +51,19 @@ } - void ChunkedBuffer::AddChunk(const char* chunkData, + void ChunkedBuffer::AddChunk(const void* chunkData, size_t chunkSize) { if (chunkSize == 0) { return; } - - assert(chunkData != NULL); - chunks_.push_back(new std::string(chunkData, chunkSize)); - numBytes_ += chunkSize; + else + { + assert(chunkData != NULL); + chunks_.push_back(new std::string(reinterpret_cast(chunkData), chunkSize)); + numBytes_ += chunkSize; + } } diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/ChunkedBuffer.h --- a/Orthanc/Core/ChunkedBuffer.h Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/ChunkedBuffer.h Fri Jul 15 12:00:11 2016 +0200 @@ -61,7 +61,7 @@ return numBytes_; } - void AddChunk(const char* chunkData, + void AddChunk(const void* chunkData, size_t chunkSize); void AddChunk(const std::string& chunk); diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/Enumerations.h --- a/Orthanc/Core/Enumerations.h Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/Enumerations.h Fri Jul 15 12:00:11 2016 +0200 @@ -385,6 +385,17 @@ RequestOrigin_Lua }; + enum ServerBarrierEvent + { + ServerBarrierEvent_Stop, + ServerBarrierEvent_Reload // SIGHUP signal: reload configuration file + }; + + enum FileMode + { + FileMode_ReadBinary, + FileMode_WriteBinary + }; /** * The value representations Orthanc knows about. They correspond to diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/Logging.h --- a/Orthanc/Core/Logging.h Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/Logging.h Fri Jul 15 12:00:11 2016 +0200 @@ -42,10 +42,16 @@ void Finalize(); + void Reset(); + + void Flush(); + void EnableInfoLevel(bool enabled); void EnableTraceLevel(bool enabled); + void SetTargetFile(const std::string& path); + void SetTargetFolder(const std::string& path); struct NullStream : public std::ostream @@ -60,6 +66,12 @@ { return *this; } + + // This overload fixes build problems with Visual Studio 2015 + std::ostream& operator<< (const char* message) + { + return *this; + } }; } } @@ -72,16 +84,10 @@ #else /* ORTHANC_ENABLE_LOGGING == 1 */ -#if ORTHANC_ENABLE_GOOGLE_LOG == 1 -# include // Including this fixes a problem in glog for recent releases of MinGW -# include -#else # include # define LOG(level) ::Orthanc::Logging::InternalLogger(#level, __FILE__, __LINE__) # define VLOG(level) ::Orthanc::Logging::InternalLogger("TRACE", __FILE__, __LINE__) -#endif -#if ORTHANC_ENABLE_GOOGLE_LOG != 1 namespace Orthanc { namespace Logging @@ -107,6 +113,5 @@ }; } } -#endif #endif // ORTHANC_ENABLE_LOGGING diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/Toolbox.cpp --- a/Orthanc/Core/Toolbox.cpp Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/Toolbox.cpp Fri Jul 15 12:00:11 2016 +0200 @@ -111,6 +111,7 @@ namespace Orthanc { +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 static bool finish_; static ServerBarrierEvent barrierEvent_; @@ -188,6 +189,7 @@ const bool stopFlag = false; return ServerBarrierInternal(&stopFlag); } +#endif /* ORTHANC_SANDBOXED */ void Toolbox::ToUpperCase(std::string& s) @@ -228,6 +230,7 @@ } +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::ReadFile(std::string& content, const std::string& path) { @@ -253,8 +256,10 @@ f.close(); } +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool Toolbox::ReadHeader(std::string& header, const std::string& path, size_t headerSize) @@ -298,8 +303,10 @@ return full; } +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::WriteFile(const void* content, size_t size, const std::string& path) @@ -318,16 +325,20 @@ f.close(); } +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::WriteFile(const std::string& content, const std::string& path) { WriteFile(content.size() > 0 ? content.c_str() : NULL, content.size(), path); } +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::RemoveFile(const std::string& path) { if (boost::filesystem::exists(path)) @@ -342,7 +353,7 @@ } } } - +#endif void Toolbox::SplitUriComponents(UriComponents& components, @@ -513,6 +524,7 @@ +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 uint64_t Toolbox::GetFileSize(const std::string& path) { try @@ -524,6 +536,7 @@ throw OrthancException(ErrorCode_InexistentFile); } } +#endif #if !defined(ORTHANC_ENABLE_MD5) || ORTHANC_ENABLE_MD5 == 1 @@ -677,11 +690,15 @@ return std::string(pathbuf); } +#elif defined(ORTHANC_SANDBOXED) && ORTHANC_SANDBOXED == 1 + // Sandboxed Orthanc, no access to the executable + #else #error Support your platform here #endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 std::string Toolbox::GetPathToExecutable() { boost::filesystem::path p(GetPathToExecutableInternal()); @@ -694,6 +711,7 @@ boost::filesystem::path p(GetPathToExecutableInternal()); return boost::filesystem::absolute(p.parent_path()).string(); } +#endif static const char* GetBoostLocaleEncoding(const Encoding sourceEncoding) @@ -1137,6 +1155,7 @@ } +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::MakeDirectory(const std::string& path) { if (boost::filesystem::exists(path)) @@ -1154,12 +1173,15 @@ } } } +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool Toolbox::IsExistingFile(const std::string& path) { return boost::filesystem::exists(path); } +#endif #if ORTHANC_PUGIXML_ENABLED == 1 @@ -1284,6 +1306,7 @@ #endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void Toolbox::ExecuteSystemCommand(const std::string& command, const std::vector& arguments) { @@ -1341,6 +1364,7 @@ throw OrthancException(ErrorCode_SystemCommand); } } +#endif bool Toolbox::IsInteger(const std::string& str) @@ -1461,6 +1485,7 @@ } +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool Toolbox::IsRegularFile(const std::string& path) { namespace fs = boost::filesystem; @@ -1480,5 +1505,172 @@ return false; } +#endif + + + FILE* Toolbox::OpenFile(const std::string& path, + FileMode mode) + { +#if defined(_WIN32) + // TODO Deal with special characters by converting to the current locale +#endif + + const char* m; + switch (mode) + { + case FileMode_ReadBinary: + m = "rb"; + break; + + case FileMode_WriteBinary: + m = "wb"; + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + return fopen(path.c_str(), m); + } + + + + static bool IsUnreservedCharacter(char c) + { + // This function checks whether "c" is an unserved character + // wrt. an URI percent-encoding + // https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding%5Fin%5Fa%5FURI + + return ((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_' || + c == '.' || + c == '~'); + } + + void Toolbox::UriEncode(std::string& target, + const std::string& source) + { + // Estimate the length of the percent-encoded URI + size_t length = 0; + + for (size_t i = 0; i < source.size(); i++) + { + if (IsUnreservedCharacter(source[i])) + { + length += 1; + } + else + { + // This character must be percent-encoded + length += 3; + } + } + + target.clear(); + target.reserve(length); + + for (size_t i = 0; i < source.size(); i++) + { + if (IsUnreservedCharacter(source[i])) + { + target.push_back(source[i]); + } + else + { + // This character must be percent-encoded + uint8_t byte = static_cast(source[i]); + uint8_t a = byte >> 4; + uint8_t b = byte & 0x0f; + + target.push_back('%'); + target.push_back(a < 10 ? a + '0' : a - 10 + 'A'); + target.push_back(b < 10 ? b + '0' : b - 10 + 'A'); + } + } + } + + + static bool HasField(const Json::Value& json, + const std::string& key, + Json::ValueType expectedType) + { + if (json.type() != Json::objectValue || + !json.isMember(key)) + { + return false; + } + else if (json[key].type() == expectedType) + { + return true; + } + else + { + throw OrthancException(ErrorCode_BadParameterType); + } + } + + + std::string Toolbox::GetJsonStringField(const Json::Value& json, + const std::string& key, + const std::string& defaultValue) + { + if (HasField(json, key, Json::stringValue)) + { + return json[key].asString(); + } + else + { + return defaultValue; + } + } + + + bool Toolbox::GetJsonBooleanField(const ::Json::Value& json, + const std::string& key, + bool defaultValue) + { + if (HasField(json, key, Json::booleanValue)) + { + return json[key].asBool(); + } + else + { + return defaultValue; + } + } + + + int Toolbox::GetJsonIntegerField(const ::Json::Value& json, + const std::string& key, + int defaultValue) + { + if (HasField(json, key, Json::intValue)) + { + return json[key].asInt(); + } + else + { + return defaultValue; + } + } + + + unsigned int Toolbox::GetJsonUnsignedIntegerField(const ::Json::Value& json, + const std::string& key, + unsigned int defaultValue) + { + int v = GetJsonIntegerField(json, key, defaultValue); + + if (v < 0) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + else + { + return static_cast(v); + } + } } - diff -r 31615831e42d -r 9362080e5e3d Orthanc/Core/Toolbox.h --- a/Orthanc/Core/Toolbox.h Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Core/Toolbox.h Fri Jul 15 12:00:11 2016 +0200 @@ -47,17 +47,13 @@ { }; - enum ServerBarrierEvent - { - ServerBarrierEvent_Stop, - ServerBarrierEvent_Reload // SIGHUP signal: reload configuration file - }; - namespace Toolbox { +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 ServerBarrierEvent ServerBarrier(const bool& stopFlag); ServerBarrierEvent ServerBarrier(); +#endif void ToUpperCase(std::string& s); // Inplace version @@ -69,23 +65,35 @@ void ToLowerCase(std::string& result, const std::string& source); +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void ReadFile(std::string& content, const std::string& path); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool ReadHeader(std::string& header, const std::string& path, size_t headerSize); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void WriteFile(const std::string& content, const std::string& path); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void WriteFile(const void* content, size_t size, const std::string& path); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void USleep(uint64_t microSeconds); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void RemoveFile(const std::string& path); +#endif void SplitUriComponents(UriComponents& components, const std::string& uri); @@ -102,7 +110,9 @@ std::string FlattenUri(const UriComponents& components, size_t fromLevel = 0); +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 uint64_t GetFileSize(const std::string& path); +#endif #if !defined(ORTHANC_ENABLE_MD5) || ORTHANC_ENABLE_MD5 == 1 void ComputeMD5(std::string& result, @@ -143,9 +153,11 @@ const std::string& content); #endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 std::string GetPathToExecutable(); std::string GetDirectoryOfExecutable(); +#endif std::string ConvertToUtf8(const std::string& source, Encoding sourceEncoding); @@ -177,9 +189,13 @@ const std::string& source, char separator); +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void MakeDirectory(const std::string& path); +#endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool IsExistingFile(const std::string& path); +#endif #if ORTHANC_PUGIXML_ENABLED == 1 void JsonToXml(std::string& target, @@ -188,8 +204,10 @@ const std::string& arrayElement = "item"); #endif +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 void ExecuteSystemCommand(const std::string& command, const std::vector& arguments); +#endif bool IsInteger(const std::string& str); @@ -201,6 +219,30 @@ int GetProcessId(); +#if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1 bool IsRegularFile(const std::string& path); +#endif + + FILE* OpenFile(const std::string& path, + FileMode mode); + + void UriEncode(std::string& target, + const std::string& source); + + std::string GetJsonStringField(const ::Json::Value& json, + const std::string& key, + const std::string& defaultValue); + + bool GetJsonBooleanField(const ::Json::Value& json, + const std::string& key, + bool defaultValue); + + int GetJsonIntegerField(const ::Json::Value& json, + const std::string& key, + int defaultValue); + + unsigned int GetJsonUnsignedIntegerField(const ::Json::Value& json, + const std::string& key, + unsigned int defaultValue); } } diff -r 31615831e42d -r 9362080e5e3d Orthanc/Resources/CMake/BoostConfiguration.cmake --- a/Orthanc/Resources/CMake/BoostConfiguration.cmake Thu Jun 30 20:45:54 2016 +0200 +++ b/Orthanc/Resources/CMake/BoostConfiguration.cmake Fri Jul 15 12:00:11 2016 +0200 @@ -54,16 +54,25 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR - ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD") + ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64") list(APPEND BOOST_SOURCES + ${BOOST_SOURCES_DIR}/libs/atomic/src/lockpool.cpp ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/once.cpp ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/thread.cpp ) add_definitions( -DBOOST_LOCALE_WITH_ICONV=1 + -DBOOST_LOCALE_NO_WINAPI_BACKEND=1 + -DBOOST_LOCALE_NO_STD_BACKEND=1 ) - if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") + if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64") add_definitions(-DBOOST_HAS_SCHED_YIELD=1) endif() @@ -86,6 +95,10 @@ add_definitions(-DBOOST_LOCALE_WITH_WCONV=1) endif() + add_definitions( + -DBOOST_LOCALE_NO_POSIX_BACKEND=1 + -DBOOST_LOCALE_NO_STD_BACKEND=1 + ) else() message(FATAL_ERROR "Support your platform here") endif() @@ -101,14 +114,81 @@ list(APPEND BOOST_SOURCES ${BOOST_REGEX_SOURCES} ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp - ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp - ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp - ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp - ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp ) + if (${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64") + # boost::filesystem is not available on PNaCl + add_definitions( + -DBOOST_HAS_FILESYSTEM_V3=0 + -D__INTEGRITY=1 + -DORTHANC_SANDBOXED=1 + ) + else() + add_definitions(-DBOOST_HAS_FILESYSTEM_V3=1) + list(APPEND BOOST_SOURCES + ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp + ) + endif() + + if (USE_BOOST_LOCALE_BACKENDS) + if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64") + list(APPEND BOOST_SOURCES + ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp + ) + elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND BOOST_SOURCES + ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp + ) + else() + message(FATAL_ERROR "Support your platform here") + endif() + + list(APPEND BOOST_SOURCES + ${BOOST_REGEX_SOURCES} + ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp + ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp + + ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp + ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp + + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/generator.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/date_time.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/formatting.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/ids.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/localization_backend.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/message.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/shared/mo_lambda.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/util/codecvt_converter.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/util/default_locale.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/util/gregorian.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp + ${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp + ) + endif() + add_definitions( # Static build of Boost -DBOOST_ALL_NO_LIB @@ -120,7 +200,6 @@ -DBOOST_SYSTEM_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_HAS_LOCALE=1 - -DBOOST_HAS_FILESYSTEM_V3=1 ) if (CMAKE_COMPILER_IS_GNUCXX)