# HG changeset patch # User Sebastien Jodogne # Date 1466800105 -7200 # Node ID 438f86ee19fcf9a0c49d6317b04a5c218a3ee661 # Parent b534834a300e2dec90a22f086276e7b4c8ae89e3 toolbox shared by all plugins diff -r b534834a300e -r 438f86ee19fc Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Fri Jun 24 22:28:25 2016 +0200 @@ -0,0 +1,829 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "OrthancPluginCppWrapper.h" + +#include + + +namespace OrthancPlugins +{ + const char* PluginException::GetErrorDescription(OrthancPluginContext* context) const + { + const char* description = OrthancPluginGetErrorDescription(context, code_); + if (description) + { + return description; + } + else + { + return "No description available"; + } + } + + + MemoryBuffer::MemoryBuffer(OrthancPluginContext* context) : + context_(context) + { + buffer_.data = NULL; + buffer_.size = 0; + } + + + void MemoryBuffer::Clear() + { + if (buffer_.data != NULL) + { + OrthancPluginFreeMemoryBuffer(context_, &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; + } + + + 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) + { + throw PluginException(OrthancPluginErrorCode_InternalError); + } + + const char* tmp = reinterpret_cast(buffer_.data); + + Json::Reader reader; + if (!reader.parse(tmp, tmp + buffer_.size, target)) + { + OrthancPluginLogError(context_, "Cannot convert some memory buffer to JSON"); + throw PluginException(OrthancPluginErrorCode_BadFileFormat); + } + } + + + bool MemoryBuffer::RestApiGet(const std::string& uri, + bool applyPlugins) + { + Clear(); + + OrthancPluginErrorCode error; + + if (applyPlugins) + { + error = OrthancPluginRestApiGetAfterPlugins(context_, &buffer_, uri.c_str()); + } + else + { + error = OrthancPluginRestApiGet(context_, &buffer_, uri.c_str()); + } + + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + throw PluginException(error); + } + } + + + bool MemoryBuffer::RestApiPost(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) + { + Clear(); + + OrthancPluginErrorCode error; + + if (applyPlugins) + { + error = OrthancPluginRestApiPostAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize); + } + else + { + error = OrthancPluginRestApiPost(context_, &buffer_, uri.c_str(), body, bodySize); + } + + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + throw PluginException(error); + } + } + + + bool MemoryBuffer::RestApiPut(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) + { + Clear(); + + OrthancPluginErrorCode error; + + if (applyPlugins) + { + error = OrthancPluginRestApiPutAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize); + } + else + { + error = OrthancPluginRestApiPut(context_, &buffer_, uri.c_str(), body, bodySize); + } + + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + throw PluginException(error); + } + } + + + OrthancString::OrthancString(OrthancPluginContext* context, + char* str) : + context_(context), + str_(str) + { + } + + + void OrthancString::Clear() + { + if (str_ != NULL) + { + OrthancPluginFreeString(context_, 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) + { + OrthancPluginLogError(context_, "Cannot convert an empty memory buffer to JSON"); + throw PluginException(OrthancPluginErrorCode_InternalError); + } + + Json::Reader reader; + if (!reader.parse(str_, target)) + { + OrthancPluginLogError(context_, "Cannot convert some memory buffer to JSON"); + throw PluginException(OrthancPluginErrorCode_BadFileFormat); + } + } + + + OrthancConfiguration::OrthancConfiguration(OrthancPluginContext* context) : + context_(context) + { + OrthancString str(context, OrthancPluginGetConfiguration(context)); + + if (str.GetContent() == NULL) + { + OrthancPluginLogError(context, "Cannot access the Orthanc configuration"); + throw PluginException(OrthancPluginErrorCode_InternalError); + } + + str.ToJson(configuration_); + + if (configuration_.type() != Json::objectValue) + { + OrthancPluginLogError(context, "Unable to read the Orthanc configuration"); + throw PluginException(OrthancPluginErrorCode_InternalError); + } + } + + + OrthancPluginContext* OrthancConfiguration::GetContext() const + { + if (context_ == NULL) + { + throw PluginException(OrthancPluginErrorCode_Plugin); + } + else + { + return context_; + } + } + + + std::string OrthancConfiguration::GetPath(const std::string& key) const + { + if (path_.empty()) + { + return key; + } + else + { + return path_ + "." + key; + } + } + + + void OrthancConfiguration::GetSection(OrthancConfiguration& target, + const std::string& key) const + { + assert(configuration_.type() == Json::objectValue); + + target.context_ = context_; + target.path_ = GetPath(key); + + if (!configuration_.isMember(key)) + { + target.configuration_ = Json::objectValue; + } + else + { + if (configuration_[key].type() != Json::objectValue) + { + if (context_ != NULL) + { + std::string s = "The configuration section \"" + target.path_ + "\" is not an associative array as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_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) + { + if (context_ != NULL) + { + std::string s = "The configuration option \"" + GetPath(key) + "\" is not a string as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_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: + if (context_ != NULL) + { + std::string s = "The configuration option \"" + GetPath(key) + "\" is not an integer as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_BadFileFormat); + } + } + + + bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target, + const std::string& key) const + { + int tmp; + if (!LookupIntegerValue(tmp, key)) + { + return false; + } + + if (tmp < 0) + { + if (context_ != NULL) + { + std::string s = "The configuration option \"" + GetPath(key) + "\" is not a positive integer as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_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) + { + if (context_ != NULL) + { + std::string s = "The configuration option \"" + GetPath(key) + "\" is not a Boolean as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_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 = configuration_[key].asInt(); + return true; + + case Json::uintValue: + target = configuration_[key].asUInt(); + return true; + + default: + if (context_ != NULL) + { + std::string s = "The configuration option \"" + GetPath(key) + "\" is not an integer as expected"; + OrthancPluginLogError(context_, s.c_str()); + } + + throw PluginException(OrthancPluginErrorCode_BadFileFormat); + } + } + + + 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 OrthancImage::Clear() + { + if (image_ != NULL) + { + OrthancPluginFreeImage(context_, image_); + image_ = NULL; + } + } + + + void OrthancImage::CheckImageAvailable() + { + if (image_ == NULL) + { + OrthancPluginLogError(context_, "Trying to access a NULL image"); + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + OrthancImage::Image(OrthancPluginContext* context) : + context_(context), + image_(NULL) + { + if (context == NULL) + { + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + OrthancImage::Image(OrthancPluginContext* context, + OrthancPluginImage* image) : + context_(context), + image_(image) + { + if (context == NULL) + { + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + OrthancImage::Image(OrthancPluginContext* context, + OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height) : + context_(context) + { + if (context == NULL) + { + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + else + { + image_ = OrthancPluginCreateImage(context, format, width, height); + } + } + + + void OrthancImage::UncompressPngImage(const void* data, + size_t size) + { + Clear(); + image_ = OrthancPluginUncompressImage(context_, data, size, OrthancPluginImageFormat_Png); + if (image_ == NULL) + { + OrthancPluginLogError(context_, "Cannot uncompress a PNG image"); + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + void OrthancImage::UncompressJpegImage(const void* data, + size_t size) + { + Clear(); + image_ = OrthancPluginUncompressImage(context_, data, size, OrthancPluginImageFormat_Jpeg); + if (image_ == NULL) + { + OrthancPluginLogError(context_, "Cannot uncompress a JPEG image"); + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + void OrthancImage::DecodeDicomImage(const void* data, + size_t size, + unsigned int frame) + { + Clear(); + image_ = OrthancPluginDecodeDicomImage(context_, data, size, frame); + if (image_ == NULL) + { + OrthancPluginLogError(context_, "Cannot uncompress a DICOM image"); + throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + OrthancPluginPixelFormat OrthancImage::GetPixelFormat() + { + CheckImageAvailable(); + return OrthancPluginGetImagePixelFormat(context_, image_); + } + + + unsigned int OrthancImage::GetWidth() + { + CheckImageAvailable(); + return OrthancPluginGetImageWidth(context_, image_); + } + + + unsigned int OrthancImage::GetHeight() + { + CheckImageAvailable(); + return OrthancPluginGetImageHeight(context_, image_); + } + + + unsigned int OrthancImage::GetPitch() + { + CheckImageAvailable(); + return OrthancPluginGetImagePitch(context_, image_); + } + + + const void* OrthancImage::GetBuffer() + { + CheckImageAvailable(); + return OrthancPluginGetImageBuffer(context_, image_); + } + + + void OrthancImage::CompressPngImage(MemoryBuffer& target) + { + CheckImageAvailable(); + + OrthancPluginMemoryBuffer tmp; + OrthancPluginCompressPngImage(context_, &tmp, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer()); + + target.Assign(tmp); + } + + + void OrthancImage::CompressJpegImage(MemoryBuffer& target, + uint8_t quality) + { + CheckImageAvailable(); + + OrthancPluginMemoryBuffer tmp; + OrthancPluginCompressJpegImage(context_, &tmp, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); + + target.Assign(tmp); + } + + + void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output) + { + CheckImageAvailable(); + OrthancPluginCompressAndAnswerPngImage(context_, output, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer()); + } + + + void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output, + uint8_t quality) + { + CheckImageAvailable(); + OrthancPluginCompressAndAnswerJpegImage(context_, output, GetPixelFormat(), + GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); + } + + + bool RestApiGetJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + bool applyPlugins) + { + MemoryBuffer answer(context); + if (!answer.RestApiGet(uri, applyPlugins)) + { + return false; + } + else + { + answer.ToJson(result); + return true; + } + } + + + bool RestApiPostJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) + { + MemoryBuffer answer(context); + if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) + { + return false; + } + else + { + answer.ToJson(result); + return true; + } + } + + + bool RestApiPutJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins) + { + MemoryBuffer answer(context); + if (!answer.RestApiPut(uri, body, bodySize, applyPlugins)) + { + return false; + } + else + { + answer.ToJson(result); + return true; + } + } + + + bool RestApiDelete(OrthancPluginContext* context, + const std::string& uri, + bool applyPlugins) + { + OrthancPluginErrorCode error; + + if (applyPlugins) + { + error = OrthancPluginRestApiDeleteAfterPlugins(context, uri.c_str()); + } + else + { + error = OrthancPluginRestApiDelete(context, uri.c_str()); + } + + if (error == OrthancPluginErrorCode_Success) + { + return true; + } + else if (error == OrthancPluginErrorCode_UnknownResource || + error == OrthancPluginErrorCode_InexistentItem) + { + return false; + } + else + { + throw PluginException(error); + } + } +} + diff -r b534834a300e -r 438f86ee19fc Plugins/Samples/Common/OrthancPluginCppWrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Fri Jun 24 22:28:25 2016 +0200 @@ -0,0 +1,384 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include +#include +#include +#include + +#if HAS_ORTHANC_EXCEPTION == 1 +# include +#endif + + +namespace OrthancPlugins +{ + typedef void (*RestCallback) (OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request); + + + class PluginException + { + private: + OrthancPluginErrorCode code_; + + public: + PluginException(OrthancPluginErrorCode code) : code_(code) + { + } + + OrthancPluginErrorCode GetErrorCode() const + { + return code_; + } + + const char* GetErrorDescription(OrthancPluginContext* context) const; + }; + + + class MemoryBuffer : public boost::noncopyable + { + private: + OrthancPluginContext* context_; + OrthancPluginMemoryBuffer buffer_; + + public: + MemoryBuffer(OrthancPluginContext* context); + + ~MemoryBuffer() + { + Clear(); + } + + OrthancPluginMemoryBuffer* operator*() + { + return &buffer_; + } + + // This transfers ownership + void Assign(OrthancPluginMemoryBuffer& other); + + const char* GetData() const + { + if (buffer_.size > 0) + { + return reinterpret_cast(buffer_.data); + } + else + { + return NULL; + } + } + + size_t GetSize() const + { + return buffer_.size; + } + + void Clear(); + + void ToString(std::string& target) const; + + void ToJson(Json::Value& target) const; + + bool RestApiGet(const std::string& uri, + bool applyPlugins); + + bool RestApiPost(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins); + + bool RestApiPut(const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins); + + bool RestApiPost(const std::string& uri, + const std::string& body, + bool applyPlugins) + { + return RestApiPost(uri, body.empty() ? NULL : body.c_str(), body.size(), applyPlugins); + } + + bool RestApiPut(const std::string& uri, + const std::string& body, + bool applyPlugins) + { + return RestApiPut(uri, body.empty() ? NULL : body.c_str(), body.size(), applyPlugins); + } + }; + + + class OrthancString : public boost::noncopyable + { + private: + OrthancPluginContext* context_; + char* str_; + + public: + OrthancString(OrthancPluginContext* context, + char* str); + + ~OrthancString() + { + Clear(); + } + + void Clear(); + + const char* GetContent() const + { + return str_; + } + + void ToString(std::string& target) const; + + void ToJson(Json::Value& target) const; + }; + + + class OrthancConfiguration : public boost::noncopyable + { + private: + OrthancPluginContext* context_; + Json::Value configuration_; + std::string path_; + + std::string GetPath(const std::string& key) const; + + public: + OrthancConfiguration() : context_(NULL) + { + } + + OrthancConfiguration(OrthancPluginContext* context); + + OrthancPluginContext* GetContext() const; + + const Json::Value& GetJson() const + { + return configuration_; + } + + void GetSection(OrthancConfiguration& target, + const std::string& key) const; + + bool LookupStringValue(std::string& target, + const std::string& key) const; + + bool LookupIntegerValue(int& target, + const std::string& key) const; + + bool LookupUnsignedIntegerValue(unsigned int& target, + const std::string& key) const; + + bool LookupBooleanValue(bool& target, + const std::string& key) const; + + bool LookupFloatValue(float& target, + const std::string& key) const; + + std::string GetStringValue(const std::string& key, + const std::string& defaultValue) const; + + int GetIntegerValue(const std::string& key, + int defaultValue) const; + + unsigned int GetUnsignedIntegerValue(const std::string& key, + unsigned int defaultValue) const; + + bool GetBooleanValue(const std::string& key, + bool defaultValue) const; + + float GetFloatValue(const std::string& key, + float defaultValue) const; + }; + + class OrthancImage + { + private: + OrthancPluginContext* context_; + OrthancPluginImage* image_; + + void Clear(); + + void CheckImageAvailable(); + + public: + OrthancImage(OrthancPluginContext* context); + + OrthancImage(OrthancPluginContext* context, + OrthancPluginImage* image); + + OrthancImage(OrthancPluginContext* context, + OrthancPluginPixelFormat format, + uint32_t width, + uint32_t height); + + ~OrthancImage() + { + Clear(); + } + + void UncompressPngImage(const void* data, + size_t size); + + void UncompressJpegImage(const void* data, + size_t size); + + void DecodeDicomImage(const void* data, + size_t size, + unsigned int frame); + + OrthancPluginPixelFormat GetPixelFormat(); + + unsigned int GetWidth(); + + unsigned int GetHeight(); + + unsigned int GetPitch(); + + const void* GetBuffer(); + + void CompressPngImage(MemoryBuffer& target); + + void CompressJpegImage(MemoryBuffer& target, + uint8_t quality); + + void AnswerPngImage(OrthancPluginRestOutput* output); + + void AnswerJpegImage(OrthancPluginRestOutput* output, + uint8_t quality); + }; + + + bool RestApiGetJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + bool applyPlugins); + + bool RestApiPostJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins); + + bool RestApiPutJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const char* body, + size_t bodySize, + bool applyPlugins); + + inline bool RestApiPostJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const std::string& body, + bool applyPlugins) + { + return RestApiPostJson(result, context, uri, body.empty() ? NULL : body.c_str(), + body.size(), applyPlugins); + } + + bool RestApiDelete(OrthancPluginContext* context, + const std::string& uri, + bool applyPlugins); + + inline bool RestApiPutJson(Json::Value& result, + OrthancPluginContext* context, + const std::string& uri, + const std::string& body, + bool applyPlugins) + { + return RestApiPutJson(result, context, uri, body.empty() ? NULL : body.c_str(), + body.size(), applyPlugins); + } + + bool RestApiDelete(OrthancPluginContext* context, + const std::string& uri, + bool applyPlugins); + + + namespace Internals + { + template + OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) + { + try + { + Callback(output, url, request); + return OrthancPluginErrorCode_Success; + } + catch (OrthancPlugins::PluginException& e) + { + return e.GetErrorCode(); + } +#if HAS_ORTHANC_EXCEPTION == 1 + catch (Orthanc::OrthancException& e) + { + return static_cast(e.GetErrorCode()); + } +#endif + catch (boost::bad_lexical_cast& e) + { + return OrthancPluginErrorCode_BadFileFormat; + } + catch (...) + { + return OrthancPluginErrorCode_Plugin; + } + } + } + + + template + void RegisterRestCallback(OrthancPluginContext* context, + const std::string& uri, + bool isThreadSafe) + { + if (isThreadSafe) + { + OrthancPluginRegisterRestCallbackNoLock(context, uri.c_str(), Internals::Protect); + } + else + { + OrthancPluginRegisterRestCallback(context, uri.c_str(), Internals::Protect); + } + } +}