Mercurial > hg > orthanc-object-storage
diff Common/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp @ 110:37a4b8e2577f
sync orthanc + SDK 1.12.1
author | Alain Mazy <am@osimis.io> |
---|---|
date | Tue, 10 Oct 2023 15:40:36 +0200 |
parents | f3c44d61e1e1 |
children | a3590caf93a3 |
line wrap: on
line diff
--- a/Common/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp Tue Oct 10 15:15:04 2023 +0200 +++ b/Common/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp Tue Oct 10 15:40:36 2023 +0200 @@ -2,7 +2,8 @@ * Orthanc - A Lightweight, RESTful DICOM Store * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2021 Osimis S.A., Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -249,26 +250,53 @@ } } + // helper class to convert std::map of headers to the plugin SDK C structure + class PluginHttpHeaders + { + private: + std::vector<const char*> headersKeys_; + std::vector<const char*> headersValues_; + + public: + explicit PluginHttpHeaders(const std::map<std::string, std::string>& httpHeaders) + { + for (std::map<std::string, std::string>::const_iterator + it = httpHeaders.begin(); it != httpHeaders.end(); ++it) + { + headersKeys_.push_back(it->first.c_str()); + headersValues_.push_back(it->second.c_str()); + } + } + + const char* const* GetKeys() + { + return (headersKeys_.empty() ? NULL : &headersKeys_[0]); + } + + const char* const* GetValues() + { + return (headersValues_.empty() ? NULL : &headersValues_[0]); + } + + uint32_t GetSize() + { + return static_cast<uint32_t>(headersKeys_.size()); + } + }; + bool MemoryBuffer::RestApiGet(const std::string& uri, const std::map<std::string, std::string>& httpHeaders, bool applyPlugins) { Clear(); - std::vector<const char*> headersKeys; - std::vector<const char*> headersValues; - - for (std::map<std::string, std::string>::const_iterator - it = httpHeaders.begin(); it != httpHeaders.end(); it++) - { - headersKeys.push_back(it->first.c_str()); - headersValues.push_back(it->second.c_str()); - } + PluginHttpHeaders headers(httpHeaders); return CheckHttp(OrthancPluginRestApiGet2( - GetGlobalContext(), &buffer_, uri.c_str(), httpHeaders.size(), - (headersKeys.empty() ? NULL : &headersKeys[0]), - (headersValues.empty() ? NULL : &headersValues[0]), applyPlugins)); + GetGlobalContext(), &buffer_, uri.c_str(), + headers.GetSize(), + headers.GetKeys(), + headers.GetValues(), applyPlugins)); } bool MemoryBuffer::RestApiPost(const std::string& uri, @@ -291,6 +319,41 @@ } } +#if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 + + bool MemoryBuffer::RestApiPost(const std::string& uri, + const void* body, + size_t bodySize, + const std::map<std::string, std::string>& httpHeaders, + bool applyPlugins) + { + MemoryBuffer answerHeaders; + uint16_t httpStatus; + + PluginHttpHeaders headers(httpHeaders); + + return CheckHttp(OrthancPluginCallRestApi(GetGlobalContext(), + &buffer_, + *answerHeaders, + &httpStatus, + OrthancPluginHttpMethod_Post, + uri.c_str(), + headers.GetSize(), headers.GetKeys(), headers.GetValues(), + body, bodySize, + applyPlugins)); + } + + + bool MemoryBuffer::RestApiPost(const std::string& uri, + const Json::Value& body, + const std::map<std::string, std::string>& httpHeaders, + bool applyPlugins) + { + std::string s; + WriteFastJson(s, body); + return RestApiPost(uri, s.c_str(), s.size(), httpHeaders, applyPlugins); + } +#endif bool MemoryBuffer::RestApiPut(const std::string& uri, const void* body, @@ -510,6 +573,22 @@ } + void OrthancString::ToJsonWithoutComments(Json::Value& target) const + { + if (str_ == NULL) + { + LogError("Cannot convert an empty memory buffer to JSON"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + + if (!ReadJsonWithoutComments(target, str_)) + { + LogError("Cannot convert some memory buffer to JSON"); + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + } + } + + void MemoryBuffer::DicomToJson(Json::Value& target, OrthancPluginDicomToJsonFormat format, OrthancPluginDicomToJsonFlags flags, @@ -539,6 +618,13 @@ const std::string& password) { Clear(); + + if (body.size() > 0xffffffffu) + { + LogError("Cannot handle body size > 4GB"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), body.c_str(), body.size(), username.empty() ? NULL : username.c_str(), @@ -552,6 +638,13 @@ const std::string& password) { Clear(); + + if (body.size() > 0xffffffffu) + { + LogError("Cannot handle body size > 4GB"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), body.empty() ? NULL : body.c_str(), body.size(), @@ -630,7 +723,7 @@ ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); } - str.ToJson(configuration_); + str.ToJsonWithoutComments(configuration_); if (configuration_.type() != Json::objectValue) { @@ -658,6 +751,12 @@ } } + OrthancConfiguration::OrthancConfiguration(const Json::Value& configuration, const std::string& path) : + configuration_(configuration), + path_(path) + { + } + std::string OrthancConfiguration::GetPath(const std::string& key) const { @@ -1013,7 +1112,7 @@ if (configuration_[key].type() != Json::objectValue) { LogError("The configuration option \"" + GetPath(key) + - "\" is not a string as expected"); + "\" is not an object as expected"); ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); } @@ -1359,6 +1458,27 @@ } + bool RestApiGet(Json::Value& result, + const std::string& uri, + const std::map<std::string, std::string>& httpHeaders, + bool applyPlugins) + { + MemoryBuffer answer; + + if (!answer.RestApiGet(uri, httpHeaders, applyPlugins)) + { + return false; + } + else + { + if (!answer.IsEmpty()) + { + answer.ToJson(result); + } + return true; + } + } + bool RestApiGet(Json::Value& result, const std::string& uri, @@ -1426,6 +1546,30 @@ } } +#if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 + bool RestApiPost(Json::Value& result, + const std::string& uri, + const Json::Value& body, + const std::map<std::string, std::string>& httpHeaders, + bool applyPlugins) + { + MemoryBuffer answer; + + if (!answer.RestApiPost(uri, body, httpHeaders, applyPlugins)) + { + return false; + } + else + { + if (!answer.IsEmpty()) + { + answer.ToJson(result); + } + return true; + } + } +#endif + bool RestApiPost(Json::Value& result, const std::string& uri, @@ -1515,32 +1659,27 @@ " is required)"); } - - bool CheckMinimalOrthancVersion(unsigned int major, - unsigned int minor, - unsigned int revision) + bool CheckMinimalVersion(const char* version, + unsigned int major, + unsigned int minor, + unsigned int revision) { - if (!HasGlobalContext()) - { - LogError("Bad Orthanc context in the plugin"); - return false; - } - - if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) + if (!strcmp(version, "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 +#define ORTHANC_SCANF sscanf_s #else - sscanf +#define ORTHANC_SCANF sscanf #endif - (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || + + // Parse the version + int aa, bb, cc = 0; + if ((ORTHANC_SCANF(version, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 && + ORTHANC_SCANF(version, "%4d.%4d", &aa, &bb) != 2) || aa < 0 || bb < 0 || cc < 0) @@ -1564,7 +1703,6 @@ return false; } - // Check the minor version number assert(a == major); @@ -1592,6 +1730,21 @@ } + bool CheckMinimalOrthancVersion(unsigned int major, + unsigned int minor, + unsigned int revision) + { + if (!HasGlobalContext()) + { + LogError("Bad Orthanc context in the plugin"); + return false; + } + + return CheckMinimalVersion(GetGlobalContext()->orthancVersion, + major, minor, revision); + } + + #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) const char* AutodetectMimeType(const std::string& path) { @@ -1761,7 +1914,8 @@ bool OrthancPeers::DoGet(MemoryBuffer& target, size_t index, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { if (index >= index_.size()) { @@ -1770,10 +1924,12 @@ OrthancPlugins::MemoryBuffer answer; uint16_t status; + PluginHttpHeaders pluginHeaders(headers); + OrthancPluginErrorCode code = OrthancPluginCallPeerApi (GetGlobalContext(), *answer, NULL, &status, peers_, static_cast<uint32_t>(index), OrthancPluginHttpMethod_Get, uri.c_str(), - 0, NULL, NULL, NULL, 0, timeout_); + pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), NULL, 0, timeout_); if (code == OrthancPluginErrorCode_Success) { @@ -1789,21 +1945,23 @@ bool OrthancPeers::DoGet(MemoryBuffer& target, const std::string& name, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { size_t index; return (LookupName(index, name) && - DoGet(target, index, uri)); + DoGet(target, index, uri, headers)); } bool OrthancPeers::DoGet(Json::Value& target, size_t index, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { MemoryBuffer buffer; - if (DoGet(buffer, index, uri)) + if (DoGet(buffer, index, uri, headers)) { buffer.ToJson(target); return true; @@ -1817,11 +1975,12 @@ bool OrthancPeers::DoGet(Json::Value& target, const std::string& name, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { MemoryBuffer buffer; - if (DoGet(buffer, name, uri)) + if (DoGet(buffer, name, uri, headers)) { buffer.ToJson(target); return true; @@ -1836,22 +1995,24 @@ bool OrthancPeers::DoPost(MemoryBuffer& target, const std::string& name, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { size_t index; return (LookupName(index, name) && - DoPost(target, index, uri, body)); + DoPost(target, index, uri, body, headers)); } bool OrthancPeers::DoPost(Json::Value& target, size_t index, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { MemoryBuffer buffer; - if (DoPost(buffer, index, uri, body)) + if (DoPost(buffer, index, uri, body, headers)) { buffer.ToJson(target); return true; @@ -1866,11 +2027,12 @@ bool OrthancPeers::DoPost(Json::Value& target, const std::string& name, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { MemoryBuffer buffer; - if (DoPost(buffer, name, uri, body)) + if (DoPost(buffer, name, uri, body, headers)) { buffer.ToJson(target); return true; @@ -1885,19 +2047,28 @@ bool OrthancPeers::DoPost(MemoryBuffer& target, size_t index, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { if (index >= index_.size()) { ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } + if (body.size() > 0xffffffffu) + { + LogError("Cannot handle body size > 4GB"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + OrthancPlugins::MemoryBuffer answer; uint16_t status; + PluginHttpHeaders pluginHeaders(headers); + OrthancPluginErrorCode code = OrthancPluginCallPeerApi (GetGlobalContext(), *answer, NULL, &status, peers_, static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), - 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); + pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_); if (code == OrthancPluginErrorCode_Success) { @@ -1913,19 +2084,28 @@ bool OrthancPeers::DoPut(size_t index, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { if (index >= index_.size()) { ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); } + if (body.size() > 0xffffffffu) + { + LogError("Cannot handle body size > 4GB"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + OrthancPlugins::MemoryBuffer answer; uint16_t status; + PluginHttpHeaders pluginHeaders(headers); + OrthancPluginErrorCode code = OrthancPluginCallPeerApi (GetGlobalContext(), *answer, NULL, &status, peers_, static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), - 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); + pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_); if (code == OrthancPluginErrorCode_Success) { @@ -1940,16 +2120,18 @@ bool OrthancPeers::DoPut(const std::string& name, const std::string& uri, - const std::string& body) const + const std::string& body, + const std::map<std::string, std::string>& headers) const { size_t index; return (LookupName(index, name) && - DoPut(index, uri, body)); + DoPut(index, uri, body, headers)); } bool OrthancPeers::DoDelete(size_t index, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { if (index >= index_.size()) { @@ -1958,10 +2140,12 @@ OrthancPlugins::MemoryBuffer answer; uint16_t status; + PluginHttpHeaders pluginHeaders(headers); + OrthancPluginErrorCode code = OrthancPluginCallPeerApi (GetGlobalContext(), *answer, NULL, &status, peers_, static_cast<uint32_t>(index), OrthancPluginHttpMethod_Delete, uri.c_str(), - 0, NULL, NULL, NULL, 0, timeout_); + pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), NULL, 0, timeout_); if (code == OrthancPluginErrorCode_Success) { @@ -1975,11 +2159,12 @@ bool OrthancPeers::DoDelete(const std::string& name, - const std::string& uri) const + const std::string& uri, + const std::map<std::string, std::string>& headers) const { size_t index; return (LookupName(index, name) && - DoDelete(index, uri)); + DoDelete(index, uri, headers)); } #endif @@ -2016,6 +2201,36 @@ } +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) + static OrthancPluginErrorCode CopyStringToMemoryBuffer(OrthancPluginMemoryBuffer* target, + const std::string& source) + { + if (OrthancPluginCreateMemoryBuffer(globalContext_, target, source.size()) != OrthancPluginErrorCode_Success) + { + return OrthancPluginErrorCode_NotEnoughMemory; + } + else + { + if (!source.empty()) + { + memcpy(target->data, source.c_str(), source.size()); + } + + return OrthancPluginErrorCode_Success; + } + } +#endif + + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) + OrthancPluginErrorCode OrthancJob::CallbackGetContent(OrthancPluginMemoryBuffer* target, + void* job) + { + assert(job != NULL); + OrthancJob& that = *reinterpret_cast<OrthancJob*>(job); + return CopyStringToMemoryBuffer(target, that.content_); + } +#else const char* OrthancJob::CallbackGetContent(void* job) { assert(job != NULL); @@ -2029,8 +2244,33 @@ return 0; } } - - +#endif + + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) + int32_t OrthancJob::CallbackGetSerialized(OrthancPluginMemoryBuffer* target, + void* job) + { + assert(job != NULL); + OrthancJob& that = *reinterpret_cast<OrthancJob*>(job); + + if (that.hasSerialized_) + { + if (CopyStringToMemoryBuffer(target, that.serialized_) == OrthancPluginErrorCode_Success) + { + return 1; + } + else + { + return -1; + } + } + else + { + return 0; + } + } +#else const char* OrthancJob::CallbackGetSerialized(void* job) { assert(job != NULL); @@ -2053,6 +2293,7 @@ return 0; } } +#endif OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) @@ -2184,10 +2425,15 @@ ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); } - OrthancPluginJob* orthanc = OrthancPluginCreateJob( - GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), - CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, - CallbackStep, CallbackStop, CallbackReset); + OrthancPluginJob* orthanc = +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) + OrthancPluginCreateJob2 +#else + OrthancPluginCreateJob +#endif + (GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), + CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, + CallbackStep, CallbackStop, CallbackReset); if (orthanc == NULL) { @@ -2483,7 +2729,7 @@ } catch (...) { - return OrthancPluginErrorCode_InternalError; + return OrthancPluginErrorCode_Plugin; } } } @@ -2569,8 +2815,8 @@ void HttpClient::ClearCredentials() { - username_.empty(); - password_.empty(); + username_.clear(); + password_.clear(); } @@ -2883,6 +3129,12 @@ MemoryBuffer answerBodyBuffer, answerHeadersBuffer; + if (body.size() > 0xffffffffu) + { + LogError("Cannot handle body size > 4GB"); + ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + } + OrthancPluginErrorCode error = OrthancPluginHttpClient( GetGlobalContext(), *answerBodyBuffer, @@ -3499,4 +3751,275 @@ } } #endif + + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 1) + DicomInstance* DicomInstance::Load(const std::string& instanceId, + OrthancPluginLoadDicomInstanceMode mode) + { + OrthancPluginDicomInstance* instance = OrthancPluginLoadDicomInstance( + GetGlobalContext(), instanceId.c_str(), mode); + + if (instance == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin); + } + else + { + boost::movelib::unique_ptr<DicomInstance> result(new DicomInstance(instance)); + result->toFree_ = true; + return result.release(); + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static std::vector<std::string> WebDavConvertPath(uint32_t pathSize, + const char* const* pathItems) + { + std::vector<std::string> result(pathSize); + + for (uint32_t i = 0; i < pathSize; i++) + { + result[i] = pathItems[i]; + } + + return result; + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavIsExistingFolder(uint8_t* isExisting, + uint32_t pathSize, + const char* const* pathItems, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + *isExisting = (that.IsExistingFolder(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_Plugin; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavListFolder(uint8_t* isExisting, + OrthancPluginWebDavCollection* collection, + OrthancPluginWebDavAddFile addFile, + OrthancPluginWebDavAddFolder addFolder, + uint32_t pathSize, + const char* const* pathItems, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + std::list<IWebDavCollection::FileInfo> files; + std::list<IWebDavCollection::FolderInfo> subfolders; + + if (!that.ListFolder(files, subfolders, WebDavConvertPath(pathSize, pathItems))) + { + *isExisting = 0; + } + else + { + *isExisting = 1; + + for (std::list<IWebDavCollection::FileInfo>::const_iterator + it = files.begin(); it != files.end(); ++it) + { + OrthancPluginErrorCode code = addFile( + collection, it->GetName().c_str(), it->GetContentSize(), + it->GetMimeType().c_str(), it->GetDateTime().c_str()); + + if (code != OrthancPluginErrorCode_Success) + { + return code; + } + } + + for (std::list<IWebDavCollection::FolderInfo>::const_iterator it = + subfolders.begin(); it != subfolders.end(); ++it) + { + OrthancPluginErrorCode code = addFolder( + collection, it->GetName().c_str(), it->GetDateTime().c_str()); + + if (code != OrthancPluginErrorCode_Success) + { + return code; + } + } + } + + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_Plugin; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavRetrieveFile(OrthancPluginWebDavCollection* collection, + OrthancPluginWebDavRetrieveFile retrieveFile, + uint32_t pathSize, + const char* const* pathItems, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + std::string content, mime, dateTime; + + if (that.GetFile(content, mime, dateTime, WebDavConvertPath(pathSize, pathItems))) + { + return retrieveFile(collection, content.empty() ? NULL : content.c_str(), + content.size(), mime.c_str(), dateTime.c_str()); + } + else + { + // Inexisting file + return OrthancPluginErrorCode_Success; + } + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_InternalError; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavStoreFileCallback(uint8_t* isReadOnly, /* out */ + uint32_t pathSize, + const char* const* pathItems, + const void* data, + uint64_t size, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + if (static_cast<uint64_t>(static_cast<size_t>(size)) != size) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(NotEnoughMemory); + } + + *isReadOnly = (that.StoreFile(WebDavConvertPath(pathSize, pathItems), data, + static_cast<size_t>(size)) ? 1 : 0); + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_InternalError; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavCreateFolderCallback(uint8_t* isReadOnly, /* out */ + uint32_t pathSize, + const char* const* pathItems, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + *isReadOnly = (that.CreateFolder(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_InternalError; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + static OrthancPluginErrorCode WebDavDeleteItemCallback(uint8_t* isReadOnly, /* out */ + uint32_t pathSize, + const char* const* pathItems, + void* payload) + { + IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); + + try + { + *isReadOnly = (that.DeleteItem(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); + return OrthancPluginErrorCode_Success; + } + catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) + { + return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); + } + catch (...) + { + return OrthancPluginErrorCode_InternalError; + } + } +#endif + + +#if HAS_ORTHANC_PLUGIN_WEBDAV == 1 + void IWebDavCollection::Register(const std::string& uri, + IWebDavCollection& collection) + { + OrthancPluginErrorCode code = OrthancPluginRegisterWebDavCollection( + GetGlobalContext(), uri.c_str(), WebDavIsExistingFolder, WebDavListFolder, WebDavRetrieveFile, + WebDavStoreFileCallback, WebDavCreateFolderCallback, WebDavDeleteItemCallback, &collection); + + if (code != OrthancPluginErrorCode_Success) + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); + } + } +#endif + + void GetHttpHeaders(std::map<std::string, std::string>& result, const OrthancPluginHttpRequest* request) + { + result.clear(); + + for (uint32_t i = 0; i < request->headersCount; ++i) + { + result[request->headersKeys[i]] = request->headersValues[i]; + } + } }