# HG changeset patch # User Sebastien Jodogne # Date 1536758750 -7200 # Node ID 473bf302d6291e08878b1fed07b21ddb562c01d5 # Parent 567d1be0849ed8fc7413827f1509ea1a6cfceaa1 C++ wrappers around OrthancPluginJob and OrthancPluginPeers diff -r 567d1be0849e -r 473bf302d629 Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Tue Sep 11 18:14:52 2018 +0200 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Wed Sep 12 15:25:50 2018 +0200 @@ -1150,10 +1150,10 @@ bool RestApiPut(Json::Value& result, - OrthancPluginContext* context, - const std::string& uri, - const Json::Value& body, - bool applyPlugins) + OrthancPluginContext* context, + const std::string& uri, + const Json::Value& body, + bool applyPlugins) { Json::FastWriter writer; return RestApiPut(result, context, uri, writer.write(body), applyPlugins); @@ -1238,7 +1238,7 @@ bb < 0 || cc < 0) { - throw false; + return false; } unsigned int a = static_cast(aa); @@ -1283,5 +1283,590 @@ return false; } } + + + + +#if HAS_ORTHANC_PLUGIN_PEERS == 1 + OrthancPeers::OrthancPeers(OrthancPluginContext* context) : + context_(context), + peers_(NULL), + timeout_(0) + { + if (context_ == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); + } + + peers_ = OrthancPluginGetPeers(context_); + + if (peers_ == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + + uint32_t count = OrthancPluginGetPeersCount(context_, peers_); + + for (uint32_t i = 0; i < count; i++) + { + const char* name = OrthancPluginGetPeerName(context_, peers_, i); + if (name == NULL) + { + OrthancPluginFreePeers(context_, peers_); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + + index_[name] = i; + } + } + + + OrthancPeers::~OrthancPeers() + { + if (peers_ != NULL) + { + OrthancPluginFreePeers(context_, peers_); + } + } + + + bool OrthancPeers::LookupName(size_t& target, + const std::string& name) const + { + Index::const_iterator found = index_.find(name); + + if (found == index_.end()) + { + return false; + } + else + { + target = found->second; + return true; + } + } + + + std::string OrthancPeers::GetPeerName(size_t index) const + { + if (index >= index_.size()) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); + } + else + { + const char* s = OrthancPluginGetPeerName(context_, peers_, static_cast(index)); + if (s == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + else + { + return s; + } + } + } + + + std::string OrthancPeers::GetPeerUrl(size_t index) const + { + if (index >= index_.size()) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); + } + else + { + const char* s = OrthancPluginGetPeerUrl(context_, peers_, static_cast(index)); + if (s == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + else + { + return s; + } + } + } + + + std::string OrthancPeers::GetPeerUrl(const std::string& name) const + { + size_t index; + if (LookupName(index, name)) + { + return GetPeerUrl(index); + } + else + { + std::string s = "Inexistent peer: " + name; + OrthancPluginLogError(context_, s.c_str()); + ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); + } + } + + + bool OrthancPeers::DoGet(MemoryBuffer& target, + 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 + (context_, &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(context_); + + if (DoGet(buffer, index, uri)) + { + buffer.ToJson(target); + return true; + } + else + { + return false; + } + } + + + bool OrthancPeers::DoGet(Json::Value& target, + const std::string& name, + const std::string& uri) const + { + MemoryBuffer buffer(context_); + + 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(context_); + + 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(context_); + + 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 + (context_, &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 + (context_, &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(context_, &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 + (context_, &answer, NULL, &status, peers_, + static_cast(index), OrthancPluginHttpMethod_Put, uri.c_str(), + 0, NULL, NULL, NULL, 0, timeout_); + + if (code == OrthancPluginErrorCode_Success) + { + OrthancPluginFreeMemoryBuffer(context_, &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; + } + } + + + const char* OrthancJob::CallbackGetContent(void* job) + { + assert(job != NULL); + + try + { + return reinterpret_cast(job)->content_.c_str(); + } + catch (...) + { + return 0; + } + } + + + const char* OrthancJob::CallbackGetSerialized(void* job) + { + assert(job != NULL); + + try + { + const OrthancJob& tmp = *reinterpret_cast(job); + + if (tmp.hasSerialized_) + { + return tmp.serialized_.c_str(); + } + else + { + return NULL; + } + } + catch (...) + { + return 0; + } + } + + + OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) + { + assert(job != NULL); + + try + { + return reinterpret_cast(job)->Step(); + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return OrthancPluginJobStepStatus_Failure; + } + catch (...) + { + return OrthancPluginJobStepStatus_Failure; + } + } + + + OrthancPluginErrorCode OrthancJob::CallbackStop(void* job, + OrthancPluginJobStopReason reason) + { + assert(job != NULL); + + 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; + } + } + + + void OrthancJob::ClearContent() + { + 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(); + } + + + 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); + } + + progress_ = progress; + } + + + OrthancJob::OrthancJob(const std::string& jobType) : + jobType_(jobType), + progress_(0) + { + ClearContent(); + ClearSerialized(); + } + + + OrthancPluginJob* OrthancJob::Create(OrthancPluginContext* context, + OrthancJob* job) + { + if (job == NULL) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); + } + + OrthancPluginJob* orthanc = OrthancPluginCreateJob( + context, 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; + } + } + + + std::string OrthancJob::Submit(OrthancPluginContext* context, + OrthancJob* job, + int priority) + { + OrthancPluginJob* orthanc = Create(context, job); + + char* id = OrthancPluginSubmitJob(context, orthanc, priority); + + if (id == NULL) + { + OrthancPluginLogError(context, "Plugin cannot submit job"); + OrthancPluginFreeJob(context, orthanc); + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); + } + else + { + std::string tmp(id); + tmp.assign(id); + OrthancPluginFreeString(context, id); + + return tmp; + } + } +#endif } - diff -r 567d1be0849e -r 473bf302d629 Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Sep 11 18:14:52 2018 +0200 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Wed Sep 12 15:25:50 2018 +0200 @@ -46,11 +46,11 @@ #if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) -#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \ - (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \ - (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \ - (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \ - (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \ +#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \ + (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \ + (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \ + (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \ + (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \ ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision)))) #endif @@ -63,6 +63,15 @@ #endif +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 4, 2) +# define HAS_ORTHANC_PLUGIN_PEERS 1 +# define HAS_ORTHANC_PLUGIN_JOB 1 +#else +# define HAS_ORTHANC_PLUGIN_PEERS 0 +# define HAS_ORTHANC_PLUGIN_JOB 0 +#endif + + namespace OrthancPlugins { @@ -531,4 +540,157 @@ OrthancPluginRegisterRestCallback(context, uri.c_str(), Internals::Protect); } } + + +#if HAS_ORTHANC_PLUGIN_PEERS == 1 + class OrthancPeers : public boost::noncopyable + { + private: + typedef std::map Index; + + OrthancPluginContext *context_; + OrthancPluginPeers *peers_; + Index index_; + uint32_t timeout_; + + public: + OrthancPeers(OrthancPluginContext* context); + + ~OrthancPeers(); + + uint32_t GetTimeout() const + { + return timeout_; + } + + void SetTimeout(uint32_t timeout) + { + timeout_ = timeout; + } + + bool LookupName(size_t& target, + const std::string& name) const; + + std::string GetPeerName(size_t index) const; + + std::string GetPeerUrl(size_t index) const; + + std::string GetPeerUrl(const std::string& name) const; + + size_t GetPeersCount() const + { + return index_.size(); + } + + bool DoGet(MemoryBuffer& target, + size_t index, + const std::string& uri) const; + + bool DoGet(MemoryBuffer& target, + const std::string& name, + const std::string& uri) const; + + bool DoGet(Json::Value& target, + size_t index, + const std::string& uri) const; + + bool DoGet(Json::Value& target, + const std::string& name, + const std::string& uri) const; + + bool DoPost(MemoryBuffer& target, + size_t index, + const std::string& uri, + const std::string& body) const; + + bool DoPost(MemoryBuffer& target, + const std::string& name, + const std::string& uri, + const std::string& body) const; + + bool DoPost(Json::Value& target, + size_t index, + const std::string& uri, + const std::string& body) const; + + bool DoPost(Json::Value& target, + const std::string& name, + const std::string& uri, + const std::string& body) const; + + bool DoPut(size_t index, + const std::string& uri, + const std::string& body) const; + + bool DoPut(const std::string& name, + const std::string& uri, + const std::string& body) const; + + bool DoDelete(size_t index, + const std::string& uri) const; + + bool DoDelete(const std::string& name, + const std::string& uri) const; + }; +#endif + + + +#if HAS_ORTHANC_PLUGIN_JOB == 1 + class OrthancJob : public boost::noncopyable + { + private: + std::string jobType_; + std::string content_; + bool hasSerialized_; + std::string serialized_; + float progress_; + + static void CallbackFinalize(void* job); + + static float CallbackGetProgress(void* job); + + static const char* CallbackGetContent(void* job); + + static const char* CallbackGetSerialized(void* job); + + static OrthancPluginJobStepStatus CallbackStep(void* job); + + static OrthancPluginErrorCode CallbackStop(void* job, + OrthancPluginJobStopReason reason); + + static OrthancPluginErrorCode CallbackReset(void* job); + + protected: + void ClearContent(); + + void UpdateContent(const Json::Value& content); + + void ClearSerialized(); + + void UpdateSerialized(const Json::Value& serialized); + + void UpdateProgress(float progress); + + public: + OrthancJob(const std::string& jobType); + + virtual ~OrthancJob() + { + } + + virtual OrthancPluginJobStepStatus Step() = 0; + + virtual void Stop(OrthancPluginJobStopReason reason) = 0; + + virtual void Reset() = 0; + + static OrthancPluginJob* Create(OrthancPluginContext* context, + OrthancJob* job /* takes ownership */); + + static std::string Submit(OrthancPluginContext* context, + OrthancJob* job /* takes ownership */, + int priority); + }; +#endif }