# HG changeset patch # User amazy # Date 1545131272 -3600 # Node ID c358bdb37c132e712e8c15c4326f8aa7159db575 # Parent c9c2faf76bec1b3573d389a744ddae241ea2e037 more plugin helpers diff -r c9c2faf76bec -r c358bdb37c13 Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Mon Dec 17 10:22:51 2018 +0100 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Tue Dec 18 12:07:52 2018 +0100 @@ -39,1951 +39,1993 @@ namespace OrthancPlugins { - static OrthancPluginContext* globalContext_ = NULL; +static OrthancPluginContext* globalContext_ = NULL; - - void SetGlobalContext(OrthancPluginContext* context) - { - if (context == NULL) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); - } - else if (globalContext_ == NULL) - { - globalContext_ = context; - } - else - { - ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); - } - } - - bool HasGlobalContext() +void SetGlobalContext(OrthancPluginContext* context) +{ + if (context == NULL) { - return globalContext_ != NULL; + ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); } - - - OrthancPluginContext* GetGlobalContext() + else if (globalContext_ == NULL) { - if (globalContext_ == NULL) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); - } - else - { - return globalContext_; - } + globalContext_ = context; + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); } +} + + +bool HasGlobalContext() +{ + return globalContext_ != NULL; +} - void MemoryBuffer::Check(OrthancPluginErrorCode code) +OrthancPluginContext* GetGlobalContext() +{ + if (globalContext_ == NULL) { - if (code != OrthancPluginErrorCode_Success) - { - // Prevent using garbage information - buffer_.data = NULL; - buffer_.size = 0; - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); - } + ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); } + else + { + return globalContext_; + } +} - bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code) +void MemoryBuffer::Check(OrthancPluginErrorCode code) +{ + if (code != OrthancPluginErrorCode_Success) { - if (code != OrthancPluginErrorCode_Success) - { - // Prevent using garbage information - buffer_.data = NULL; - buffer_.size = 0; - } - - if (code == OrthancPluginErrorCode_Success) - { - return true; - } - else if (code == OrthancPluginErrorCode_UnknownResource || - code == OrthancPluginErrorCode_InexistentItem) - { - return false; - } - else - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); - } + // Prevent using garbage information + buffer_.data = NULL; + buffer_.size = 0; + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); } +} - MemoryBuffer::MemoryBuffer() +bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code) +{ + if (code != OrthancPluginErrorCode_Success) { + // Prevent using garbage information buffer_.data = NULL; buffer_.size = 0; } + if (code == OrthancPluginErrorCode_Success) + { + return true; + } + else if (code == OrthancPluginErrorCode_UnknownResource || + code == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); + } +} - void MemoryBuffer::Clear() + +MemoryBuffer::MemoryBuffer() +{ + buffer_.data = NULL; + buffer_.size = 0; +} + + +void MemoryBuffer::Clear() +{ + if (buffer_.data != NULL) { - if (buffer_.data != NULL) - { - OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_); - buffer_.data = NULL; - buffer_.size = 0; - } + OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_); + buffer_.data = NULL; + buffer_.size = 0; + } +} + + +void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other) +{ + Clear(); + + buffer_.data = other.data; + buffer_.size = other.size; + + other.data = NULL; + other.size = 0; +} + + +OrthancPluginMemoryBuffer MemoryBuffer::Release() +{ + OrthancPluginMemoryBuffer result = buffer_; + + buffer_.data = NULL; + buffer_.size = 0; + + return result; +} + + +void MemoryBuffer::ToString(std::string& target) const +{ + if (buffer_.size == 0) + { + target.clear(); + } + else + { + target.assign(reinterpret_cast(buffer_.data), buffer_.size); + } +} + + +void MemoryBuffer::ToJson(Json::Value& target) const +{ + if (buffer_.data == NULL || + buffer_.size == 0) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); } + const char* tmp = reinterpret_cast(buffer_.data); - void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other) + Json::Reader reader; + if (!reader.parse(tmp, tmp + buffer_.size, target)) + { + LogError("Cannot convert some memory buffer to JSON"); + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } +} + + +bool MemoryBuffer::RestApiGet(const std::string& uri, + bool applyPlugins) +{ + Clear(); + + if (applyPlugins) + { + return CheckHttp(OrthancPluginRestApiGetAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str())); + } + else + { + return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); + } +} + +bool MemoryBuffer::RestApiGet(const std::string& uri, + const std::map& httpHeaders, + bool applyPlugins) +{ + Clear(); + + std::vector headersKeys; + std::vector headersValues; + for (std::map::const_iterator it = httpHeaders.begin(); it != httpHeaders.end(); it++) + { + headersKeys.push_back(it->first.c_str()); + headersValues.push_back(it->second.c_str()); + } + + return CheckHttp(OrthancPluginRestApiGet2(GetGlobalContext(), &buffer_, uri.c_str(), httpHeaders.size(), headersKeys.data(), headersValues.data(), applyPlugins)); +} + +bool MemoryBuffer::RestApiPost(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) +{ + Clear(); + + if (applyPlugins) + { + return CheckHttp(OrthancPluginRestApiPostAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + } + else + { + return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + } +} + + +bool MemoryBuffer::RestApiPut(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) +{ + Clear(); + + if (applyPlugins) + { + return CheckHttp(OrthancPluginRestApiPutAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + } + else + { + return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + } +} + + +bool MemoryBuffer::RestApiPost(const std::string& uri, + const Json::Value& body, + bool applyPlugins) +{ + Json::FastWriter writer; + return RestApiPost(uri, writer.write(body), applyPlugins); +} + + +bool MemoryBuffer::RestApiPut(const std::string& uri, + const Json::Value& body, + bool applyPlugins) +{ + Json::FastWriter writer; + return RestApiPut(uri, writer.write(body), applyPlugins); +} + + +void MemoryBuffer::CreateDicom(const Json::Value& tags, + OrthancPluginCreateDicomFlags flags) +{ + Clear(); + + Json::FastWriter writer; + std::string s = writer.write(tags); + + Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); +} + +void MemoryBuffer::CreateDicom(const Json::Value& tags, + const OrthancImage& pixelData, + OrthancPluginCreateDicomFlags flags) +{ + Clear(); + + Json::FastWriter writer; + std::string s = writer.write(tags); + + Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags)); +} + + +void MemoryBuffer::ReadFile(const std::string& path) +{ + Clear(); + Check(OrthancPluginReadFile(GetGlobalContext(), &buffer_, path.c_str())); +} + + +void MemoryBuffer::GetDicomQuery(const OrthancPluginWorklistQuery* query) +{ + Clear(); + Check(OrthancPluginWorklistGetDicomQuery(GetGlobalContext(), &buffer_, query)); +} + + +void OrthancString::Assign(char* str) +{ + if (str == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + else { Clear(); + str_ = str; + } +} - buffer_.data = other.data; - buffer_.size = other.size; + +void OrthancString::Clear() +{ + if (str_ != NULL) + { + OrthancPluginFreeString(GetGlobalContext(), str_); + str_ = NULL; + } +} + + +void OrthancString::ToString(std::string& target) const +{ + if (str_ == NULL) + { + target.clear(); + } + else + { + target.assign(str_); + } +} + + +void OrthancString::ToJson(Json::Value& target) const +{ + if (str_ == NULL) + { + LogError("Cannot convert an empty memory buffer to JSON"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + + Json::Reader reader; + if (!reader.parse(str_, target)) + { + LogError("Cannot convert some memory buffer to JSON"); + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } +} + + +void MemoryBuffer::DicomToJson(Json::Value& target, + OrthancPluginDicomToJsonFormat format, + OrthancPluginDicomToJsonFlags flags, + uint32_t maxStringLength) +{ + OrthancString str; + str.Assign(OrthancPluginDicomBufferToJson + (GetGlobalContext(), GetData(), GetSize(), format, flags, maxStringLength)); + str.ToJson(target); +} + + +bool MemoryBuffer::HttpGet(const std::string& url, + const std::string& username, + const std::string& password) +{ + Clear(); + return CheckHttp(OrthancPluginHttpGet(GetGlobalContext(), &buffer_, url.c_str(), + username.empty() ? NULL : username.c_str(), + password.empty() ? NULL : password.c_str())); +} + + +bool MemoryBuffer::HttpPost(const std::string& url, + const std::string& body, + const std::string& username, + const std::string& password) +{ + Clear(); + return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), + body.c_str(), body.size(), + username.empty() ? NULL : username.c_str(), + password.empty() ? NULL : password.c_str())); +} + + +bool MemoryBuffer::HttpPut(const std::string& url, + const std::string& body, + const std::string& username, + const std::string& password) +{ + Clear(); + return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), + body.empty() ? NULL : body.c_str(), + body.size(), + username.empty() ? NULL : username.c_str(), + password.empty() ? NULL : password.c_str())); +} + + +void MemoryBuffer::GetDicomInstance(const std::string& instanceId) +{ + Clear(); + Check(OrthancPluginGetDicomForInstance(GetGlobalContext(), &buffer_, instanceId.c_str())); +} + + +bool HttpDelete(const std::string& url, + const std::string& username, + const std::string& password) +{ + OrthancPluginErrorCode error = OrthancPluginHttpDelete + (GetGlobalContext(), url.c_str(), + username.empty() ? NULL : username.c_str(), + password.empty() ? NULL : password.c_str()); - other.data = NULL; - other.size = 0; + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); + } +} + + +void LogError(const std::string& message) +{ + if (HasGlobalContext()) + { + OrthancPluginLogError(GetGlobalContext(), message.c_str()); + } +} + + +void LogWarning(const std::string& message) +{ + if (HasGlobalContext()) + { + OrthancPluginLogWarning(GetGlobalContext(), message.c_str()); + } +} + + +void LogInfo(const std::string& message) +{ + if (HasGlobalContext()) + { + OrthancPluginLogInfo(GetGlobalContext(), message.c_str()); + } +} + + +OrthancConfiguration::OrthancConfiguration() +{ + OrthancString str; + str.Assign(OrthancPluginGetConfiguration(GetGlobalContext())); + + if (str.GetContent() == NULL) + { + LogError("Cannot access the Orthanc configuration"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + + str.ToJson(configuration_); + + if (configuration_.type() != Json::objectValue) + { + LogError("Unable to read the Orthanc configuration"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); } +} + + +std::string OrthancConfiguration::GetPath(const std::string& key) const +{ + if (path_.empty()) + { + return key; + } + else + { + return path_ + "." + key; + } +} + + +bool OrthancConfiguration::IsSection(const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + return (configuration_.isMember(key) && + configuration_[key].type() == Json::objectValue); +} + + +void OrthancConfiguration::GetSection(OrthancConfiguration& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + target.path_ = GetPath(key); + + if (!configuration_.isMember(key)) + { + target.configuration_ = Json::objectValue; + } + else + { + if (configuration_[key].type() != Json::objectValue) + { + LogError("The configuration section \"" + target.path_ + + "\" is not an associative array as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } + + target.configuration_ = configuration_[key]; + } +} + + +bool OrthancConfiguration::LookupStringValue(std::string& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + if (!configuration_.isMember(key)) + { + return false; + } + + if (configuration_[key].type() != Json::stringValue) + { + LogError("The configuration option \"" + GetPath(key) + + "\" is not a string as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } + + target = configuration_[key].asString(); + return true; +} - OrthancPluginMemoryBuffer MemoryBuffer::Release() +bool OrthancConfiguration::LookupIntegerValue(int& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + if (!configuration_.isMember(key)) + { + return false; + } + + switch (configuration_[key].type()) + { + case Json::intValue: + target = configuration_[key].asInt(); + return true; + + case Json::uintValue: + target = configuration_[key].asUInt(); + return true; + + default: + LogError("The configuration option \"" + GetPath(key) + + "\" is not an integer as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } +} + + +bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target, + const std::string& key) const +{ + int tmp; + if (!LookupIntegerValue(tmp, key)) { - OrthancPluginMemoryBuffer result = buffer_; + return false; + } + + if (tmp < 0) + { + LogError("The configuration option \"" + GetPath(key) + + "\" is not a positive integer as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } + else + { + target = static_cast(tmp); + return true; + } +} + + +bool OrthancConfiguration::LookupBooleanValue(bool& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + if (!configuration_.isMember(key)) + { + return false; + } + + if (configuration_[key].type() != Json::booleanValue) + { + LogError("The configuration option \"" + GetPath(key) + + "\" is not a Boolean as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } - buffer_.data = NULL; - buffer_.size = 0; - - return result; + target = configuration_[key].asBool(); + return true; +} + + +bool OrthancConfiguration::LookupFloatValue(float& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + if (!configuration_.isMember(key)) + { + return false; + } + + switch (configuration_[key].type()) + { + case Json::realValue: + target = configuration_[key].asFloat(); + return true; + + case Json::intValue: + target = static_cast(configuration_[key].asInt()); + return true; + + case Json::uintValue: + target = static_cast(configuration_[key].asUInt()); + return true; + + default: + LogError("The configuration option \"" + GetPath(key) + + "\" is not an integer as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } +} + + +bool OrthancConfiguration::LookupListOfStrings(std::list& target, + const std::string& key, + bool allowSingleString) const +{ + assert(configuration_.type() == Json::objectValue); + + target.clear(); + + if (!configuration_.isMember(key)) + { + return false; + } + + switch (configuration_[key].type()) + { + case Json::arrayValue: + { + bool ok = true; + + for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++) + { + if (configuration_[key][i].type() == Json::stringValue) + { + target.push_back(configuration_[key][i].asString()); + } + else + { + ok = false; + } + } + + if (ok) + { + return true; + } + + break; } + case Json::stringValue: + if (allowSingleString) + { + target.push_back(configuration_[key].asString()); + return true; + } - void MemoryBuffer::ToString(std::string& target) const + break; + + default: + break; + } + + LogError("The configuration option \"" + GetPath(key) + + "\" is not a list of strings as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); +} + + +bool OrthancConfiguration::LookupSetOfStrings(std::set& target, + const std::string& key, + bool allowSingleString) const +{ + std::list lst; + + if (LookupListOfStrings(lst, key, allowSingleString)) + { + target.clear(); + + for (std::list::const_iterator + it = lst.begin(); it != lst.end(); ++it) + { + target.insert(*it); + } + + return true; + } + else + { + return false; + } +} + + +std::string OrthancConfiguration::GetStringValue(const std::string& key, + const std::string& defaultValue) const +{ + std::string tmp; + if (LookupStringValue(tmp, key)) + { + return tmp; + } + else + { + return defaultValue; + } +} + + +int OrthancConfiguration::GetIntegerValue(const std::string& key, + int defaultValue) const +{ + int tmp; + if (LookupIntegerValue(tmp, key)) + { + return tmp; + } + else { - if (buffer_.size == 0) + return defaultValue; + } +} + + +unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key, + unsigned int defaultValue) const +{ + unsigned int tmp; + if (LookupUnsignedIntegerValue(tmp, key)) + { + return tmp; + } + else + { + return defaultValue; + } +} + + +bool OrthancConfiguration::GetBooleanValue(const std::string& key, + bool defaultValue) const +{ + bool tmp; + if (LookupBooleanValue(tmp, key)) + { + return tmp; + } + else + { + return defaultValue; + } +} + + +float OrthancConfiguration::GetFloatValue(const std::string& key, + float defaultValue) const +{ + float tmp; + if (LookupFloatValue(tmp, key)) + { + return tmp; + } + else + { + return defaultValue; + } +} + + +void OrthancConfiguration::GetDictionary(std::map& target, + const std::string& key) const +{ + assert(configuration_.type() == Json::objectValue); + + target.clear(); + + if (!configuration_.isMember(key)) + { + return; + } + + if (configuration_[key].type() != Json::objectValue) + { + LogError("The configuration option \"" + GetPath(key) + + "\" is not a string as expected"); + + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } + + Json::Value::Members members = configuration_[key].getMemberNames(); + + for (size_t i = 0; i < members.size(); i++) + { + const Json::Value& value = configuration_[key][members[i]]; + + if (value.type() == Json::stringValue) { - target.clear(); + target[members[i]] = value.asString(); } else { - target.assign(reinterpret_cast(buffer_.data), buffer_.size); - } - } - + LogError("The configuration option \"" + GetPath(key) + + "\" is not a dictionary mapping strings to strings"); - void MemoryBuffer::ToJson(Json::Value& target) const - { - if (buffer_.data == NULL || - buffer_.size == 0) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - - const char* tmp = reinterpret_cast(buffer_.data); - - Json::Reader reader; - if (!reader.parse(tmp, tmp + buffer_.size, target)) - { - LogError("Cannot convert some memory buffer to JSON"); ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); } } +} + + +void OrthancImage::Clear() +{ + if (image_ != NULL) + { + OrthancPluginFreeImage(GetGlobalContext(), image_); + image_ = NULL; + } +} + + +void OrthancImage::CheckImageAvailable() +{ + if (image_ == NULL) + { + LogError("Trying to access a NULL image"); + ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); + } +} + + +OrthancImage::OrthancImage() : + image_(NULL) +{ +} + + +OrthancImage::OrthancImage(OrthancPluginImage* image) : + image_(image) +{ +} + + +OrthancImage::OrthancImage(OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height) +{ + image_ = OrthancPluginCreateImage(GetGlobalContext(), format, width, height); + + if (image_ == NULL) + { + LogError("Cannot create an image"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } +} + + +OrthancImage::OrthancImage(OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height, + uint32_t pitch, + void* buffer) +{ + image_ = OrthancPluginCreateImageAccessor + (GetGlobalContext(), format, width, height, pitch, buffer); + + if (image_ == NULL) + { + LogError("Cannot create an image accessor"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } +} + +void OrthancImage::UncompressPngImage(const void* data, + size_t size) +{ + Clear(); + + image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Png); + + if (image_ == NULL) + { + LogError("Cannot uncompress a PNG image"); + ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); + } +} + + +void OrthancImage::UncompressJpegImage(const void* data, + size_t size) +{ + Clear(); + image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Jpeg); + if (image_ == NULL) + { + LogError("Cannot uncompress a JPEG image"); + ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); + } +} + + +void OrthancImage::DecodeDicomImage(const void* data, + size_t size, + unsigned int frame) +{ + Clear(); + image_ = OrthancPluginDecodeDicomImage(GetGlobalContext(), data, size, frame); + if (image_ == NULL) + { + LogError("Cannot uncompress a DICOM image"); + ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); + } +} + + +OrthancPluginPixelFormat OrthancImage::GetPixelFormat() +{ + CheckImageAvailable(); + return OrthancPluginGetImagePixelFormat(GetGlobalContext(), image_); +} - bool MemoryBuffer::RestApiGet(const std::string& uri, - bool applyPlugins) - { - Clear(); +unsigned int OrthancImage::GetWidth() +{ + CheckImageAvailable(); + return OrthancPluginGetImageWidth(GetGlobalContext(), image_); +} + + +unsigned int OrthancImage::GetHeight() +{ + CheckImageAvailable(); + return OrthancPluginGetImageHeight(GetGlobalContext(), image_); +} + + +unsigned int OrthancImage::GetPitch() +{ + CheckImageAvailable(); + return OrthancPluginGetImagePitch(GetGlobalContext(), image_); +} + + +const void* OrthancImage::GetBuffer() +{ + CheckImageAvailable(); + return OrthancPluginGetImageBuffer(GetGlobalContext(), image_); +} + - if (applyPlugins) - { - return CheckHttp(OrthancPluginRestApiGetAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str())); - } - else - { - return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); - } - } +void OrthancImage::CompressPngImage(MemoryBuffer& target) +{ + CheckImageAvailable(); + + OrthancPluginMemoryBuffer tmp; + OrthancPluginCompressPngImage(GetGlobalContext(), &tmp, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer()); + + target.Assign(tmp); +} + + +void OrthancImage::CompressJpegImage(MemoryBuffer& target, + uint8_t quality) +{ + CheckImageAvailable(); + + OrthancPluginMemoryBuffer tmp; + OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); + + target.Assign(tmp); +} + + +void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output) +{ + CheckImageAvailable(); + OrthancPluginCompressAndAnswerPngImage(GetGlobalContext(), output, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer()); +} + - - bool MemoryBuffer::RestApiPost(const std::string& uri, - const char* body, - size_t bodySize, - bool applyPlugins) +void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output, + uint8_t quality) +{ + CheckImageAvailable(); + OrthancPluginCompressAndAnswerJpegImage(GetGlobalContext(), output, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); +} + + + +#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 +FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) : + matcher_(NULL), + worklist_(worklist) +{ + if (worklist_ == NULL) { - Clear(); + ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); + } +} + + +void FindMatcher::SetupDicom(const void* query, + uint32_t size) +{ + worklist_ = NULL; - if (applyPlugins) - { - return CheckHttp(OrthancPluginRestApiPostAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); - } - else - { - return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); - } + matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size); + if (matcher_ == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } +} + + +FindMatcher::~FindMatcher() +{ + // The "worklist_" field + + if (matcher_ != NULL) + { + OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_); + } +} + + + +bool FindMatcher::IsMatch(const void* dicom, + uint32_t size) const +{ + int32_t result; + + if (matcher_ != NULL) + { + result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size); + } + else if (worklist_ != NULL) + { + result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size); + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); } + if (result == 0) + { + return false; + } + else if (result == 1) + { + return true; + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } +} - bool MemoryBuffer::RestApiPut(const std::string& uri, - const char* body, - size_t bodySize, - bool applyPlugins) +#endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ + +void AnswerJson(const Json::Value& value, + OrthancPluginRestOutput* output + ) +{ + Json::StyledWriter writer; + std::string bodyString = writer.write(value); + + OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); +} + +void AnswerString(const std::string& answer, + const char* mimeType, + OrthancPluginRestOutput* output + ) +{ + OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType); +} + +void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) +{ + OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError); +} + +void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods) +{ + OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods); +} + +bool RestApiGetString(std::string& result, + const std::string& uri, + bool applyPlugins) +{ + MemoryBuffer answer; + if (!answer.RestApiGet(uri, applyPlugins)) { - Clear(); + return false; + } + else + { + answer.ToString(result); + return true; + } +} + +bool RestApiGetString(std::string& result, + const std::string& uri, + const std::map& httpHeaders, + bool applyPlugins) +{ + MemoryBuffer answer; + if (!answer.RestApiGet(uri, httpHeaders, applyPlugins)) + { + return false; + } + else + { + answer.ToString(result); + return true; + } +} + + + +bool RestApiGet(Json::Value& result, + const std::string& uri, + bool applyPlugins) +{ + MemoryBuffer answer; - if (applyPlugins) + if (!answer.RestApiGet(uri, applyPlugins)) + { + return false; + } + else + { + if (!answer.IsEmpty()) { - return CheckHttp(OrthancPluginRestApiPutAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + answer.ToJson(result); + } + return true; + } +} + + +bool RestApiPost(Json::Value& result, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) +{ + MemoryBuffer answer; + + if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) + { + return false; + } + else + { + if (!answer.IsEmpty()) + { + answer.ToJson(result); } - else + return true; + } +} + + +bool RestApiPost(Json::Value& result, + const std::string& uri, + const Json::Value& body, + bool applyPlugins) +{ + Json::FastWriter writer; + return RestApiPost(result, uri, writer.write(body), applyPlugins); +} + + +bool RestApiPut(Json::Value& result, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) +{ + MemoryBuffer answer; + + if (!answer.RestApiPut(uri, body, bodySize, applyPlugins)) + { + return false; + } + else + { + if (!answer.IsEmpty()) // i.e, on a PUT to metadata/..., orthand returns an empty response { - return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); + answer.ToJson(result); } + return true; + } +} + + +bool RestApiPut(Json::Value& result, + const std::string& uri, + const Json::Value& body, + bool applyPlugins) +{ + Json::FastWriter writer; + return RestApiPut(result, uri, writer.write(body), applyPlugins); +} + + +bool RestApiDelete(const std::string& uri, + bool applyPlugins) +{ + OrthancPluginErrorCode error; + + if (applyPlugins) + { + error = OrthancPluginRestApiDeleteAfterPlugins(GetGlobalContext(), uri.c_str()); + } + else + { + error = OrthancPluginRestApiDelete(GetGlobalContext(), uri.c_str()); } + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); + } +} - bool MemoryBuffer::RestApiPost(const std::string& uri, - const Json::Value& body, - bool applyPlugins) + +void ReportMinimalOrthancVersion(unsigned int major, + unsigned int minor, + unsigned int revision) +{ + LogError("Your version of the Orthanc core (" + + std::string(GetGlobalContext()->orthancVersion) + + ") is too old to run this plugin (version " + + boost::lexical_cast(major) + "." + + boost::lexical_cast(minor) + "." + + boost::lexical_cast(revision) + + " is required)"); +} + + +bool CheckMinimalOrthancVersion(unsigned int major, + unsigned int minor, + unsigned int revision) +{ + if (!HasGlobalContext()) { - Json::FastWriter writer; - return RestApiPost(uri, writer.write(body), applyPlugins); + LogError("Bad Orthanc context in the plugin"); + return false; } + if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) + { + // Assume compatibility with the mainline + return true; + } - bool MemoryBuffer::RestApiPut(const std::string& uri, - const Json::Value& body, - bool applyPlugins) + // Parse the version of the Orthanc core + int aa, bb, cc; + if ( + #ifdef _MSC_VER + sscanf_s + #else + sscanf + #endif + (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || + aa < 0 || + bb < 0 || + cc < 0) { - Json::FastWriter writer; - return RestApiPut(uri, writer.write(body), applyPlugins); + return false; + } + + unsigned int a = static_cast(aa); + unsigned int b = static_cast(bb); + unsigned int c = static_cast(cc); + + // Check the major version number + + if (a > major) + { + return true; + } + + if (a < major) + { + return false; } - void MemoryBuffer::CreateDicom(const Json::Value& tags, - OrthancPluginCreateDicomFlags flags) - { - Clear(); + // Check the minor version number + assert(a == major); - Json::FastWriter writer; - std::string s = writer.write(tags); - - Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); + if (b > minor) + { + return true; + } + + if (b < minor) + { + return false; } - void MemoryBuffer::CreateDicom(const Json::Value& tags, - const OrthancImage& pixelData, - OrthancPluginCreateDicomFlags flags) - { - Clear(); + // Check the patch level version number + assert(a == major && b == minor); - Json::FastWriter writer; - std::string s = writer.write(tags); - - Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags)); + if (c >= revision) + { + return true; } + else + { + return false; + } +} - void MemoryBuffer::ReadFile(const std::string& path) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) +const char* AutodetectMimeType(const std::string& path) +{ + const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str()); + + if (mime == NULL) + { + // Should never happen, just for safety + return "application/octet-stream"; + } + else { - Clear(); - Check(OrthancPluginReadFile(GetGlobalContext(), &buffer_, path.c_str())); + return mime; } +} +#endif + + +#if HAS_ORTHANC_PLUGIN_PEERS == 1 +size_t OrthancPeers::GetPeerIndex(const std::string& name) const +{ + size_t index; + if (LookupName(index, name)) + { + return index; + } + else + { + LogError("Inexistent peer: " + name); + ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); + } +} - void MemoryBuffer::GetDicomQuery(const OrthancPluginWorklistQuery* query) +OrthancPeers::OrthancPeers() : + peers_(NULL), + timeout_(0) +{ + peers_ = OrthancPluginGetPeers(GetGlobalContext()); + + if (peers_ == NULL) { - Clear(); - Check(OrthancPluginWorklistGetDicomQuery(GetGlobalContext(), &buffer_, query)); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); } + uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_); + + for (uint32_t i = 0; i < count; i++) + { + const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i); + if (name == NULL) + { + OrthancPluginFreePeers(GetGlobalContext(), peers_); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + + index_[name] = i; + } +} + - void OrthancString::Assign(char* str) +OrthancPeers::~OrthancPeers() +{ + if (peers_ != NULL) { - if (str == NULL) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - else - { - Clear(); - str_ = str; - } + OrthancPluginFreePeers(GetGlobalContext(), peers_); } +} - void OrthancString::Clear() +bool OrthancPeers::LookupName(size_t& target, + const std::string& name) const +{ + Index::const_iterator found = index_.find(name); + + if (found == index_.end()) { - if (str_ != NULL) - { - OrthancPluginFreeString(GetGlobalContext(), str_); - str_ = NULL; - } + return false; } + else + { + target = found->second; + return true; + } +} - void OrthancString::ToString(std::string& target) const +std::string OrthancPeers::GetPeerName(size_t index) const +{ + if (index >= index_.size()) { - if (str_ == NULL) + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); + } + else + { + const char* s = OrthancPluginGetPeerName(GetGlobalContext(), peers_, static_cast(index)); + if (s == NULL) { - target.clear(); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); } else { - target.assign(str_); + return s; } } - - - void OrthancString::ToJson(Json::Value& target) const - { - if (str_ == NULL) - { - LogError("Cannot convert an empty memory buffer to JSON"); - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - - Json::Reader reader; - if (!reader.parse(str_, target)) - { - LogError("Cannot convert some memory buffer to JSON"); - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - } - - - void MemoryBuffer::DicomToJson(Json::Value& target, - OrthancPluginDicomToJsonFormat format, - OrthancPluginDicomToJsonFlags flags, - uint32_t maxStringLength) - { - OrthancString str; - str.Assign(OrthancPluginDicomBufferToJson - (GetGlobalContext(), GetData(), GetSize(), format, flags, maxStringLength)); - str.ToJson(target); - } +} - bool MemoryBuffer::HttpGet(const std::string& url, - const std::string& username, - const std::string& password) +std::string OrthancPeers::GetPeerUrl(size_t index) const +{ + if (index >= index_.size()) { - Clear(); - return CheckHttp(OrthancPluginHttpGet(GetGlobalContext(), &buffer_, url.c_str(), - username.empty() ? NULL : username.c_str(), - password.empty() ? NULL : password.c_str())); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } - - - bool MemoryBuffer::HttpPost(const std::string& url, - const std::string& body, - const std::string& username, - const std::string& password) - { - Clear(); - return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), - body.c_str(), body.size(), - username.empty() ? NULL : username.c_str(), - password.empty() ? NULL : password.c_str())); - } - - - bool MemoryBuffer::HttpPut(const std::string& url, - const std::string& body, - const std::string& username, - const std::string& password) + else { - Clear(); - return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), - body.empty() ? NULL : body.c_str(), - body.size(), - username.empty() ? NULL : username.c_str(), - password.empty() ? NULL : password.c_str())); + const char* s = OrthancPluginGetPeerUrl(GetGlobalContext(), peers_, static_cast(index)); + if (s == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + else + { + return s; + } } - +} - void MemoryBuffer::GetDicomInstance(const std::string& instanceId) - { - Clear(); - Check(OrthancPluginGetDicomForInstance(GetGlobalContext(), &buffer_, instanceId.c_str())); - } - - bool HttpDelete(const std::string& url, - const std::string& username, - const std::string& password) +std::string OrthancPeers::GetPeerUrl(const std::string& name) const +{ + return GetPeerUrl(GetPeerIndex(name)); +} + + +bool OrthancPeers::LookupUserProperty(std::string& value, + size_t index, + const std::string& key) const +{ + if (index >= index_.size()) { - OrthancPluginErrorCode error = OrthancPluginHttpDelete - (GetGlobalContext(), url.c_str(), - username.empty() ? NULL : username.c_str(), - password.empty() ? NULL : password.c_str()); - - if (error == OrthancPluginErrorCode_Success) - { - return true; - } - else if (error == OrthancPluginErrorCode_UnknownResource || - error == OrthancPluginErrorCode_InexistentItem) + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); + } + else + { + const char* s = OrthancPluginGetPeerUserProperty(GetGlobalContext(), peers_, static_cast(index), key.c_str()); + if (s == NULL) { return false; } else { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); - } - } - - - void LogError(const std::string& message) - { - if (HasGlobalContext()) - { - OrthancPluginLogError(GetGlobalContext(), message.c_str()); - } - } - - - void LogWarning(const std::string& message) - { - if (HasGlobalContext()) - { - OrthancPluginLogWarning(GetGlobalContext(), message.c_str()); - } - } - - - void LogInfo(const std::string& message) - { - if (HasGlobalContext()) - { - OrthancPluginLogInfo(GetGlobalContext(), message.c_str()); - } - } - - - OrthancConfiguration::OrthancConfiguration() - { - OrthancString str; - str.Assign(OrthancPluginGetConfiguration(GetGlobalContext())); - - if (str.GetContent() == NULL) - { - LogError("Cannot access the Orthanc configuration"); - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - - str.ToJson(configuration_); - - if (configuration_.type() != Json::objectValue) - { - LogError("Unable to read the Orthanc configuration"); - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - } - - - std::string OrthancConfiguration::GetPath(const std::string& key) const - { - if (path_.empty()) - { - return key; - } - else - { - return path_ + "." + key; - } - } - - - bool OrthancConfiguration::IsSection(const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - return (configuration_.isMember(key) && - configuration_[key].type() == Json::objectValue); - } - - - void OrthancConfiguration::GetSection(OrthancConfiguration& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - target.path_ = GetPath(key); - - if (!configuration_.isMember(key)) - { - target.configuration_ = Json::objectValue; - } - else - { - if (configuration_[key].type() != Json::objectValue) - { - LogError("The configuration section \"" + target.path_ + - "\" is not an associative array as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - - target.configuration_ = configuration_[key]; - } - } - - - bool OrthancConfiguration::LookupStringValue(std::string& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - if (!configuration_.isMember(key)) - { - return false; - } - - if (configuration_[key].type() != Json::stringValue) - { - LogError("The configuration option \"" + GetPath(key) + - "\" is not a string as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - - target = configuration_[key].asString(); - return true; - } - - - bool OrthancConfiguration::LookupIntegerValue(int& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - if (!configuration_.isMember(key)) - { - return false; - } - - switch (configuration_[key].type()) - { - case Json::intValue: - target = configuration_[key].asInt(); - return true; - - case Json::uintValue: - target = configuration_[key].asUInt(); - return true; - - default: - LogError("The configuration option \"" + GetPath(key) + - "\" is not an integer as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - } - - - bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target, - const std::string& key) const - { - int tmp; - if (!LookupIntegerValue(tmp, key)) - { - return false; - } - - if (tmp < 0) - { - LogError("The configuration option \"" + GetPath(key) + - "\" is not a positive integer as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - else - { - target = static_cast(tmp); - return true; - } - } - - - bool OrthancConfiguration::LookupBooleanValue(bool& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - if (!configuration_.isMember(key)) - { - return false; - } - - if (configuration_[key].type() != Json::booleanValue) - { - LogError("The configuration option \"" + GetPath(key) + - "\" is not a Boolean as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - - target = configuration_[key].asBool(); - return true; - } - - - bool OrthancConfiguration::LookupFloatValue(float& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - if (!configuration_.isMember(key)) - { - return false; - } - - switch (configuration_[key].type()) - { - case Json::realValue: - target = configuration_[key].asFloat(); - return true; - - case Json::intValue: - target = static_cast(configuration_[key].asInt()); - return true; - - case Json::uintValue: - target = static_cast(configuration_[key].asUInt()); - return true; - - default: - LogError("The configuration option \"" + GetPath(key) + - "\" is not an integer as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - } - - - bool OrthancConfiguration::LookupListOfStrings(std::list& target, - const std::string& key, - bool allowSingleString) const - { - assert(configuration_.type() == Json::objectValue); - - target.clear(); - - if (!configuration_.isMember(key)) - { - return false; - } - - switch (configuration_[key].type()) - { - case Json::arrayValue: - { - bool ok = true; - - for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++) - { - if (configuration_[key][i].type() == Json::stringValue) - { - target.push_back(configuration_[key][i].asString()); - } - else - { - ok = false; - } - } - - if (ok) - { - return true; - } - - break; - } - - case Json::stringValue: - if (allowSingleString) - { - target.push_back(configuration_[key].asString()); - return true; - } - - break; - - default: - break; - } - - LogError("The configuration option \"" + GetPath(key) + - "\" is not a list of strings as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - - - bool OrthancConfiguration::LookupSetOfStrings(std::set& target, - const std::string& key, - bool allowSingleString) const - { - std::list lst; - - if (LookupListOfStrings(lst, key, allowSingleString)) - { - target.clear(); - - for (std::list::const_iterator - it = lst.begin(); it != lst.end(); ++it) - { - target.insert(*it); - } - - return true; - } - else - { - return false; - } - } - - - std::string OrthancConfiguration::GetStringValue(const std::string& key, - const std::string& defaultValue) const - { - std::string tmp; - if (LookupStringValue(tmp, key)) - { - return tmp; - } - else - { - return defaultValue; - } - } - - - int OrthancConfiguration::GetIntegerValue(const std::string& key, - int defaultValue) const - { - int tmp; - if (LookupIntegerValue(tmp, key)) - { - return tmp; - } - else - { - return defaultValue; - } - } - - - unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key, - unsigned int defaultValue) const - { - unsigned int tmp; - if (LookupUnsignedIntegerValue(tmp, key)) - { - return tmp; - } - else - { - return defaultValue; - } - } - - - bool OrthancConfiguration::GetBooleanValue(const std::string& key, - bool defaultValue) const - { - bool tmp; - if (LookupBooleanValue(tmp, key)) - { - return tmp; - } - else - { - return defaultValue; - } - } - - - float OrthancConfiguration::GetFloatValue(const std::string& key, - float defaultValue) const - { - float tmp; - if (LookupFloatValue(tmp, key)) - { - return tmp; - } - else - { - return defaultValue; - } - } - - - void OrthancConfiguration::GetDictionary(std::map& target, - const std::string& key) const - { - assert(configuration_.type() == Json::objectValue); - - target.clear(); - - if (!configuration_.isMember(key)) - { - return; - } - - if (configuration_[key].type() != Json::objectValue) - { - LogError("The configuration option \"" + GetPath(key) + - "\" is not a string as expected"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - - Json::Value::Members members = configuration_[key].getMemberNames(); - - for (size_t i = 0; i < members.size(); i++) - { - const Json::Value& value = configuration_[key][members[i]]; - - if (value.type() == Json::stringValue) - { - target[members[i]] = value.asString(); - } - else - { - LogError("The configuration option \"" + GetPath(key) + - "\" is not a dictionary mapping strings to strings"); - - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); - } - } - } - - - void OrthancImage::Clear() - { - if (image_ != NULL) - { - OrthancPluginFreeImage(GetGlobalContext(), image_); - image_ = NULL; - } - } - - - void OrthancImage::CheckImageAvailable() - { - if (image_ == NULL) - { - LogError("Trying to access a NULL image"); - ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); - } - } - - - OrthancImage::OrthancImage() : - image_(NULL) - { - } - - - OrthancImage::OrthancImage(OrthancPluginImage* image) : - image_(image) - { - } - - - OrthancImage::OrthancImage(OrthancPluginPixelFormat format, - uint32_t width, - uint32_t height) - { - image_ = OrthancPluginCreateImage(GetGlobalContext(), format, width, height); - - if (image_ == NULL) - { - LogError("Cannot create an image"); - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - } - - - OrthancImage::OrthancImage(OrthancPluginPixelFormat format, - uint32_t width, - uint32_t height, - uint32_t pitch, - void* buffer) - { - image_ = OrthancPluginCreateImageAccessor - (GetGlobalContext(), format, width, height, pitch, buffer); - - if (image_ == NULL) - { - LogError("Cannot create an image accessor"); - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - } - - void OrthancImage::UncompressPngImage(const void* data, - size_t size) - { - Clear(); - - image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Png); - - if (image_ == NULL) - { - LogError("Cannot uncompress a PNG image"); - ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); - } - } - - - void OrthancImage::UncompressJpegImage(const void* data, - size_t size) - { - Clear(); - image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Jpeg); - if (image_ == NULL) - { - LogError("Cannot uncompress a JPEG image"); - ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); - } - } - - - void OrthancImage::DecodeDicomImage(const void* data, - size_t size, - unsigned int frame) - { - Clear(); - image_ = OrthancPluginDecodeDicomImage(GetGlobalContext(), data, size, frame); - if (image_ == NULL) - { - LogError("Cannot uncompress a DICOM image"); - ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); - } - } - - - OrthancPluginPixelFormat OrthancImage::GetPixelFormat() - { - CheckImageAvailable(); - return OrthancPluginGetImagePixelFormat(GetGlobalContext(), image_); - } - - - unsigned int OrthancImage::GetWidth() - { - CheckImageAvailable(); - return OrthancPluginGetImageWidth(GetGlobalContext(), image_); - } - - - unsigned int OrthancImage::GetHeight() - { - CheckImageAvailable(); - return OrthancPluginGetImageHeight(GetGlobalContext(), image_); - } - - - unsigned int OrthancImage::GetPitch() - { - CheckImageAvailable(); - return OrthancPluginGetImagePitch(GetGlobalContext(), image_); - } - - - const void* OrthancImage::GetBuffer() - { - CheckImageAvailable(); - return OrthancPluginGetImageBuffer(GetGlobalContext(), image_); - } - - - void OrthancImage::CompressPngImage(MemoryBuffer& target) - { - CheckImageAvailable(); - - OrthancPluginMemoryBuffer tmp; - OrthancPluginCompressPngImage(GetGlobalContext(), &tmp, GetPixelFormat(), - GetWidth(), GetHeight(), GetPitch(), GetBuffer()); - - target.Assign(tmp); - } - - - void OrthancImage::CompressJpegImage(MemoryBuffer& target, - uint8_t quality) - { - CheckImageAvailable(); - - OrthancPluginMemoryBuffer tmp; - OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(), - GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); - - target.Assign(tmp); - } - - - void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output) - { - CheckImageAvailable(); - OrthancPluginCompressAndAnswerPngImage(GetGlobalContext(), output, GetPixelFormat(), - GetWidth(), GetHeight(), GetPitch(), GetBuffer()); - } - - - void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output, - uint8_t quality) - { - CheckImageAvailable(); - OrthancPluginCompressAndAnswerJpegImage(GetGlobalContext(), output, GetPixelFormat(), - GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); - } - - - -#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 - FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) : - matcher_(NULL), - worklist_(worklist) - { - if (worklist_ == NULL) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); - } - } - - - void FindMatcher::SetupDicom(const void* query, - uint32_t size) - { - worklist_ = NULL; - - matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size); - if (matcher_ == NULL) - { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - } - - - FindMatcher::~FindMatcher() - { - // The "worklist_" field - - if (matcher_ != NULL) - { - OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_); - } - } - - - - bool FindMatcher::IsMatch(const void* dicom, - uint32_t size) const - { - int32_t result; - - if (matcher_ != NULL) - { - result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size); - } - else if (worklist_ != NULL) - { - result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size); - } - else - { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - - if (result == 0) - { - return false; - } - else if (result == 1) - { - return true; - } - else - { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); - } - } - -#endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ - - void AnswerJson(const Json::Value& value, - OrthancPluginRestOutput* output - ) - { - Json::StyledWriter writer; - std::string bodyString = writer.write(value); - - OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); - } - - void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) - { - OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError); - } - - void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods) - { - OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods); - } - - bool RestApiGetString(std::string& result, - const std::string& uri, - bool applyPlugins) - { - MemoryBuffer answer; - if (!answer.RestApiGet(uri, applyPlugins)) - { - return false; - } - else - { - answer.ToString(result); - return true; - } - } - - - bool RestApiGet(Json::Value& result, - const std::string& uri, - bool applyPlugins) - { - MemoryBuffer answer; - - if (!answer.RestApiGet(uri, applyPlugins)) - { - return false; - } - else - { - if (!answer.IsEmpty()) - { - answer.ToJson(result); - } - return true; - } - } - - - bool RestApiPost(Json::Value& result, - const std::string& uri, - const char* body, - size_t bodySize, - bool applyPlugins) - { - MemoryBuffer answer; - - if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) - { - return false; - } - else - { - if (!answer.IsEmpty()) - { - answer.ToJson(result); - } + value.assign(s); return true; } } - - - bool RestApiPost(Json::Value& result, - const std::string& uri, - const Json::Value& body, - bool applyPlugins) - { - Json::FastWriter writer; - return RestApiPost(result, uri, writer.write(body), applyPlugins); - } +} - bool RestApiPut(Json::Value& result, - const std::string& uri, - const char* body, - size_t bodySize, - bool applyPlugins) - { - MemoryBuffer answer; - - if (!answer.RestApiPut(uri, body, bodySize, applyPlugins)) - { - return false; - } - else - { - if (!answer.IsEmpty()) // i.e, on a PUT to metadata/..., orthand returns an empty response - { - answer.ToJson(result); - } - return true; - } - } +bool OrthancPeers::LookupUserProperty(std::string& value, + const std::string& peer, + const std::string& key) const +{ + return LookupUserProperty(value, GetPeerIndex(peer), key); +} - bool RestApiPut(Json::Value& result, - const std::string& uri, - const Json::Value& body, - bool applyPlugins) +bool OrthancPeers::DoGet(MemoryBuffer& target, + size_t index, + const std::string& uri) const +{ + if (index >= index_.size()) { - Json::FastWriter writer; - return RestApiPut(result, uri, writer.write(body), applyPlugins); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } - - bool RestApiDelete(const std::string& uri, - bool applyPlugins) - { - OrthancPluginErrorCode error; + OrthancPluginMemoryBuffer answer; + uint16_t status; + OrthancPluginErrorCode code = OrthancPluginCallPeerApi + (GetGlobalContext(), &answer, NULL, &status, peers_, + static_cast(index), OrthancPluginHttpMethod_Get, uri.c_str(), + 0, NULL, NULL, NULL, 0, timeout_); - if (applyPlugins) - { - error = OrthancPluginRestApiDeleteAfterPlugins(GetGlobalContext(), uri.c_str()); - } - else - { - error = OrthancPluginRestApiDelete(GetGlobalContext(), uri.c_str()); - } + if (code == OrthancPluginErrorCode_Success) + { + target.Assign(answer); + return (status == 200); + } + else + { + return false; + } +} + - if (error == OrthancPluginErrorCode_Success) - { - return true; - } - else if (error == OrthancPluginErrorCode_UnknownResource || - error == OrthancPluginErrorCode_InexistentItem) - { - return false; - } - else - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); - } +bool OrthancPeers::DoGet(MemoryBuffer& target, + const std::string& name, + const std::string& uri) const +{ + size_t index; + return (LookupName(index, name) && + DoGet(target, index, uri)); +} + + +bool OrthancPeers::DoGet(Json::Value& target, + size_t index, + const std::string& uri) const +{ + MemoryBuffer buffer; + + if (DoGet(buffer, index, uri)) + { + buffer.ToJson(target); + return true; } + else + { + return false; + } +} - void ReportMinimalOrthancVersion(unsigned int major, - unsigned int minor, - unsigned int revision) +bool OrthancPeers::DoGet(Json::Value& target, + const std::string& name, + const std::string& uri) const +{ + MemoryBuffer buffer; + + if (DoGet(buffer, name, uri)) + { + buffer.ToJson(target); + return true; + } + else { - LogError("Your version of the Orthanc core (" + - std::string(GetGlobalContext()->orthancVersion) + - ") is too old to run this plugin (version " + - boost::lexical_cast(major) + "." + - boost::lexical_cast(minor) + "." + - boost::lexical_cast(revision) + - " is required)"); + return false; } +} + + +bool OrthancPeers::DoPost(MemoryBuffer& target, + const std::string& name, + const std::string& uri, + const std::string& body) const +{ + size_t index; + return (LookupName(index, name) && + DoPost(target, index, uri, body)); +} + + +bool OrthancPeers::DoPost(Json::Value& target, + size_t index, + const std::string& uri, + const std::string& body) const +{ + MemoryBuffer buffer; + + if (DoPost(buffer, index, uri, body)) + { + buffer.ToJson(target); + return true; + } + else + { + return false; + } +} - bool CheckMinimalOrthancVersion(unsigned int major, - unsigned int minor, - unsigned int revision) +bool OrthancPeers::DoPost(Json::Value& target, + const std::string& name, + const std::string& uri, + const std::string& body) const +{ + MemoryBuffer buffer; + + if (DoPost(buffer, name, uri, body)) { - if (!HasGlobalContext()) - { - LogError("Bad Orthanc context in the plugin"); - return false; - } + buffer.ToJson(target); + return true; + } + else + { + return false; + } +} - if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) - { - // Assume compatibility with the mainline - return true; - } - // Parse the version of the Orthanc core - int aa, bb, cc; - if ( - #ifdef _MSC_VER - sscanf_s - #else - sscanf - #endif - (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || - aa < 0 || - bb < 0 || - cc < 0) - { - return false; - } +bool OrthancPeers::DoPost(MemoryBuffer& target, + size_t index, + const std::string& uri, + const std::string& body) const +{ + if (index >= index_.size()) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); + } - unsigned int a = static_cast(aa); - unsigned int b = static_cast(bb); - unsigned int c = static_cast(cc); - - // Check the major version number + OrthancPluginMemoryBuffer answer; + uint16_t status; + OrthancPluginErrorCode code = OrthancPluginCallPeerApi + (GetGlobalContext(), &answer, NULL, &status, peers_, + static_cast(index), OrthancPluginHttpMethod_Post, uri.c_str(), + 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); - if (a > major) - { - return true; - } - - if (a < major) - { - return false; - } + if (code == OrthancPluginErrorCode_Success) + { + target.Assign(answer); + return (status == 200); + } + else + { + return false; + } +} - // Check the minor version number - assert(a == major); - - if (b > minor) - { - return true; - } - - if (b < minor) - { - return false; - } - - // Check the patch level version number - assert(a == major && b == minor); - - if (c >= revision) - { - return true; - } - else - { - return false; - } +bool OrthancPeers::DoPut(size_t index, + const std::string& uri, + const std::string& body) const +{ + if (index >= index_.size()) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } - -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) - const char* AutodetectMimeType(const std::string& path) + OrthancPluginMemoryBuffer answer; + uint16_t status; + OrthancPluginErrorCode code = OrthancPluginCallPeerApi + (GetGlobalContext(), &answer, NULL, &status, peers_, + static_cast(index), OrthancPluginHttpMethod_Put, uri.c_str(), + 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); + + if (code == OrthancPluginErrorCode_Success) + { + OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); + return (status == 200); + } + else { - const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str()); + return false; + } +} + + +bool OrthancPeers::DoPut(const std::string& name, + const std::string& uri, + const std::string& body) const +{ + size_t index; + return (LookupName(index, name) && + DoPut(index, uri, body)); +} + - if (mime == NULL) - { - // Should never happen, just for safety - return "application/octet-stream"; - } - else - { - return mime; - } +bool OrthancPeers::DoDelete(size_t index, + const std::string& uri) const +{ + if (index >= index_.size()) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } + + OrthancPluginMemoryBuffer answer; + uint16_t status; + OrthancPluginErrorCode code = OrthancPluginCallPeerApi + (GetGlobalContext(), &answer, NULL, &status, peers_, + static_cast(index), OrthancPluginHttpMethod_Put, uri.c_str(), + 0, NULL, NULL, NULL, 0, timeout_); + + if (code == OrthancPluginErrorCode_Success) + { + OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); + return (status == 200); + } + else + { + return false; + } +} + + +bool OrthancPeers::DoDelete(const std::string& name, + const std::string& uri) const +{ + size_t index; + return (LookupName(index, name) && + DoDelete(index, uri)); +} #endif -#if HAS_ORTHANC_PLUGIN_PEERS == 1 - size_t OrthancPeers::GetPeerIndex(const std::string& name) const + +#if HAS_ORTHANC_PLUGIN_JOB == 1 +void OrthancJob::CallbackFinalize(void* job) +{ + if (job != NULL) { - size_t index; - if (LookupName(index, name)) - { - return index; - } - else - { - LogError("Inexistent peer: " + name); - ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); - } + delete reinterpret_cast(job); } +} + + +float OrthancJob::CallbackGetProgress(void* job) +{ + assert(job != NULL); + + try + { + return reinterpret_cast(job)->progress_; + } + catch (...) + { + return 0; + } +} - OrthancPeers::OrthancPeers() : - peers_(NULL), - timeout_(0) - { - peers_ = OrthancPluginGetPeers(GetGlobalContext()); - - if (peers_ == NULL) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - - uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_); - - for (uint32_t i = 0; i < count; i++) - { - const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i); - if (name == NULL) - { - OrthancPluginFreePeers(GetGlobalContext(), peers_); - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - - index_[name] = i; - } - } - - - OrthancPeers::~OrthancPeers() - { - if (peers_ != NULL) - { - OrthancPluginFreePeers(GetGlobalContext(), peers_); - } - } - - - bool OrthancPeers::LookupName(size_t& target, - const std::string& name) const - { - Index::const_iterator found = index_.find(name); +const char* OrthancJob::CallbackGetContent(void* job) +{ + assert(job != NULL); - if (found == index_.end()) - { - return false; - } - else - { - target = found->second; - return true; - } - } - - - std::string OrthancPeers::GetPeerName(size_t index) const + try { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - else - { - const char* s = OrthancPluginGetPeerName(GetGlobalContext(), peers_, static_cast(index)); - if (s == NULL) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - else - { - return s; - } - } + return reinterpret_cast(job)->content_.c_str(); } - - - std::string OrthancPeers::GetPeerUrl(size_t index) const + catch (...) { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - else - { - const char* s = OrthancPluginGetPeerUrl(GetGlobalContext(), peers_, static_cast(index)); - if (s == NULL) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - else - { - return s; - } - } + return 0; } - - - std::string OrthancPeers::GetPeerUrl(const std::string& name) const - { - return GetPeerUrl(GetPeerIndex(name)); - } +} - bool OrthancPeers::LookupUserProperty(std::string& value, - size_t index, - const std::string& key) const +const char* OrthancJob::CallbackGetSerialized(void* job) +{ + assert(job != NULL); + + try { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - else - { - const char* s = OrthancPluginGetPeerUserProperty(GetGlobalContext(), peers_, static_cast(index), key.c_str()); - if (s == NULL) - { - return false; - } - else - { - value.assign(s); - return true; - } - } - } + const OrthancJob& tmp = *reinterpret_cast(job); - - bool OrthancPeers::LookupUserProperty(std::string& value, - const std::string& peer, - const std::string& key) const - { - return LookupUserProperty(value, GetPeerIndex(peer), key); - } - - - bool OrthancPeers::DoGet(MemoryBuffer& target, - size_t index, - const std::string& uri) const - { - if (index >= index_.size()) + if (tmp.hasSerialized_) { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - - OrthancPluginMemoryBuffer answer; - uint16_t status; - OrthancPluginErrorCode code = OrthancPluginCallPeerApi - (GetGlobalContext(), &answer, NULL, &status, peers_, - static_cast(index), OrthancPluginHttpMethod_Get, uri.c_str(), - 0, NULL, NULL, NULL, 0, timeout_); - - if (code == OrthancPluginErrorCode_Success) - { - target.Assign(answer); - return (status == 200); - } - else - { - return false; - } - } - - - bool OrthancPeers::DoGet(MemoryBuffer& target, - const std::string& name, - const std::string& uri) const - { - size_t index; - return (LookupName(index, name) && - DoGet(target, index, uri)); - } - - - bool OrthancPeers::DoGet(Json::Value& target, - size_t index, - const std::string& uri) const - { - MemoryBuffer buffer; - - if (DoGet(buffer, index, uri)) - { - buffer.ToJson(target); - return true; + return tmp.serialized_.c_str(); } else { - return false; - } - } - - - bool OrthancPeers::DoGet(Json::Value& target, - const std::string& name, - const std::string& uri) const - { - MemoryBuffer buffer; - - if (DoGet(buffer, name, uri)) - { - buffer.ToJson(target); - return true; - } - else - { - return false; - } - } - - - bool OrthancPeers::DoPost(MemoryBuffer& target, - const std::string& name, - const std::string& uri, - const std::string& body) const - { - size_t index; - return (LookupName(index, name) && - DoPost(target, index, uri, body)); - } - - - bool OrthancPeers::DoPost(Json::Value& target, - size_t index, - const std::string& uri, - const std::string& body) const - { - MemoryBuffer buffer; - - if (DoPost(buffer, index, uri, body)) - { - buffer.ToJson(target); - return true; - } - else - { - return false; - } - } - - - bool OrthancPeers::DoPost(Json::Value& target, - const std::string& name, - const std::string& uri, - const std::string& body) const - { - MemoryBuffer buffer; - - if (DoPost(buffer, name, uri, body)) - { - buffer.ToJson(target); - return true; - } - else - { - return false; - } - } - - - bool OrthancPeers::DoPost(MemoryBuffer& target, - size_t index, - const std::string& uri, - const std::string& body) const - { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - - OrthancPluginMemoryBuffer answer; - uint16_t status; - OrthancPluginErrorCode code = OrthancPluginCallPeerApi - (GetGlobalContext(), &answer, NULL, &status, peers_, - static_cast(index), OrthancPluginHttpMethod_Post, uri.c_str(), - 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); - - if (code == OrthancPluginErrorCode_Success) - { - target.Assign(answer); - return (status == 200); - } - else - { - return false; - } - } - - - bool OrthancPeers::DoPut(size_t index, - const std::string& uri, - const std::string& body) const - { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - - OrthancPluginMemoryBuffer answer; - uint16_t status; - OrthancPluginErrorCode code = OrthancPluginCallPeerApi - (GetGlobalContext(), &answer, NULL, &status, peers_, - static_cast(index), OrthancPluginHttpMethod_Put, uri.c_str(), - 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); - - if (code == OrthancPluginErrorCode_Success) - { - OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); - return (status == 200); - } - else - { - return false; - } - } - - - bool OrthancPeers::DoPut(const std::string& name, - const std::string& uri, - const std::string& body) const - { - size_t index; - return (LookupName(index, name) && - DoPut(index, uri, body)); - } - - - bool OrthancPeers::DoDelete(size_t index, - const std::string& uri) const - { - if (index >= index_.size()) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - - OrthancPluginMemoryBuffer answer; - uint16_t status; - OrthancPluginErrorCode code = OrthancPluginCallPeerApi - (GetGlobalContext(), &answer, NULL, &status, peers_, - static_cast(index), OrthancPluginHttpMethod_Put, uri.c_str(), - 0, NULL, NULL, NULL, 0, timeout_); - - if (code == OrthancPluginErrorCode_Success) - { - OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); - return (status == 200); - } - else - { - return false; - } - } - - - bool OrthancPeers::DoDelete(const std::string& name, - const std::string& uri) const - { - size_t index; - return (LookupName(index, name) && - DoDelete(index, uri)); - } -#endif - - - -#if HAS_ORTHANC_PLUGIN_JOB == 1 - void OrthancJob::CallbackFinalize(void* job) - { - if (job != NULL) - { - delete reinterpret_cast(job); - } - } - - - float OrthancJob::CallbackGetProgress(void* job) - { - assert(job != NULL); - - try - { - return reinterpret_cast(job)->progress_; - } - catch (...) - { - return 0; + return NULL; } } - + catch (...) + { + return 0; + } +} + + +OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) +{ + assert(job != NULL); - const char* OrthancJob::CallbackGetContent(void* job) + try + { + return reinterpret_cast(job)->Step(); + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&) { - assert(job != NULL); + return OrthancPluginJobStepStatus_Failure; + } + catch (...) + { + return OrthancPluginJobStepStatus_Failure; + } +} - try - { - return reinterpret_cast(job)->content_.c_str(); - } - catch (...) - { - return 0; - } + +OrthancPluginErrorCode OrthancJob::CallbackStop(void* job, + OrthancPluginJobStopReason reason) +{ + assert(job != NULL); + + try + { + reinterpret_cast(job)->Stop(reason); + return OrthancPluginErrorCode_Success; } - - - const char* OrthancJob::CallbackGetSerialized(void* job) + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast(e.GetErrorCode()); + } + catch (...) { - assert(job != NULL); + return OrthancPluginErrorCode_Plugin; + } +} - try - { - const OrthancJob& tmp = *reinterpret_cast(job); + +OrthancPluginErrorCode OrthancJob::CallbackReset(void* job) +{ + assert(job != NULL); - if (tmp.hasSerialized_) - { - return tmp.serialized_.c_str(); - } - else - { - return NULL; - } - } - catch (...) - { - return 0; - } + try + { + reinterpret_cast(job)->Reset(); + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast(e.GetErrorCode()); } - + catch (...) + { + return OrthancPluginErrorCode_Plugin; + } +} + + +void OrthancJob::ClearContent() +{ + Json::Value empty = Json::objectValue; + UpdateContent(empty); +} + - OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) +void OrthancJob::UpdateContent(const Json::Value& content) +{ + if (content.type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); + } + else { - assert(job != NULL); + Json::FastWriter writer; + content_ = writer.write(content); + } +} + + +void OrthancJob::ClearSerialized() +{ + hasSerialized_ = false; + serialized_.clear(); +} + - try - { - return reinterpret_cast(job)->Step(); - } - catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&) - { - return OrthancPluginJobStepStatus_Failure; - } - catch (...) - { - return OrthancPluginJobStepStatus_Failure; - } +void OrthancJob::UpdateSerialized(const Json::Value& serialized) +{ + if (serialized.type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); + } + else + { + Json::FastWriter writer; + serialized_ = writer.write(serialized); + hasSerialized_ = true; + } +} + + +void OrthancJob::UpdateProgress(float progress) +{ + if (progress < 0 || + progress > 1) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } - - OrthancPluginErrorCode OrthancJob::CallbackStop(void* job, - OrthancPluginJobStopReason reason) - { - assert(job != NULL); + progress_ = progress; +} - try - { - reinterpret_cast(job)->Stop(reason); - return OrthancPluginErrorCode_Success; - } - catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) - { - return static_cast(e.GetErrorCode()); - } - catch (...) - { - return OrthancPluginErrorCode_Plugin; - } - } - - - OrthancPluginErrorCode OrthancJob::CallbackReset(void* job) - { - assert(job != NULL); - try - { - reinterpret_cast(job)->Reset(); - return OrthancPluginErrorCode_Success; - } - catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) - { - return static_cast(e.GetErrorCode()); - } - catch (...) - { - return OrthancPluginErrorCode_Plugin; - } - } - +OrthancJob::OrthancJob(const std::string& jobType) : + jobType_(jobType), + progress_(0) +{ + ClearContent(); + ClearSerialized(); +} - void OrthancJob::ClearContent() + +OrthancPluginJob* OrthancJob::Create(OrthancJob* job) +{ + if (job == NULL) { - Json::Value empty = Json::objectValue; - UpdateContent(empty); - } - - - void OrthancJob::UpdateContent(const Json::Value& content) - { - if (content.type() != Json::objectValue) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); - } - else - { - Json::FastWriter writer; - content_ = writer.write(content); - } - } - - - void OrthancJob::ClearSerialized() - { - hasSerialized_ = false; - serialized_.clear(); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); } - - void OrthancJob::UpdateSerialized(const Json::Value& serialized) - { - if (serialized.type() != Json::objectValue) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); - } - else - { - Json::FastWriter writer; - serialized_ = writer.write(serialized); - hasSerialized_ = true; - } - } + OrthancPluginJob* orthanc = OrthancPluginCreateJob( + GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), + CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, + CallbackStep, CallbackStop, CallbackReset); - - void OrthancJob::UpdateProgress(float progress) + if (orthanc == NULL) { - if (progress < 0 || - progress > 1) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); - } - - progress_ = progress; + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); } - - - OrthancJob::OrthancJob(const std::string& jobType) : - jobType_(jobType), - progress_(0) + else { - ClearContent(); - ClearSerialized(); + return orthanc; } +} - OrthancPluginJob* OrthancJob::Create(OrthancJob* job) - { - if (job == NULL) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); - } +std::string OrthancJob::Submit(OrthancJob* job, + int priority) +{ + OrthancPluginJob* orthanc = Create(job); - OrthancPluginJob* orthanc = OrthancPluginCreateJob( - GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), - CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, - CallbackStep, CallbackStop, CallbackReset); - - if (orthanc == NULL) - { - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - else - { - return orthanc; - } - } + char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority); - - std::string OrthancJob::Submit(OrthancJob* job, - int priority) + if (id == NULL) { - OrthancPluginJob* orthanc = Create(job); - - char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority); + LogError("Plugin cannot submit job"); + OrthancPluginFreeJob(GetGlobalContext(), orthanc); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + else + { + std::string tmp(id); + tmp.assign(id); + OrthancPluginFreeString(GetGlobalContext(), id); - if (id == NULL) - { - LogError("Plugin cannot submit job"); - OrthancPluginFreeJob(GetGlobalContext(), orthanc); - ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); - } - else - { - std::string tmp(id); - tmp.assign(id); - OrthancPluginFreeString(GetGlobalContext(), id); - - return tmp; - } + return tmp; } +} #endif } diff -r c9c2faf76bec -r c358bdb37c13 Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h Mon Dec 17 10:22:51 2018 +0100 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Dec 18 12:07:52 2018 +0100 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -154,6 +155,10 @@ bool RestApiGet(const std::string& uri, bool applyPlugins); + bool RestApiGet(const std::string& uri, + const std::map& httpHeaders, + bool applyPlugins); + bool RestApiPost(const std::string& uri, const char* body, size_t bodySize, @@ -428,6 +433,11 @@ const std::string& uri, bool applyPlugins); + bool RestApiGetString(std::string& result, + const std::string& uri, + const std::map& httpHeaders, + bool applyPlugins); + bool RestApiPost(Json::Value& result, const std::string& uri, const char* body, @@ -487,6 +497,10 @@ void AnswerJson(const Json::Value& value, OrthancPluginRestOutput* output); + void AnswerString(const std::string& answer, + const char* mimeType, + OrthancPluginRestOutput* output); + void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput* output);