Mercurial > hg > orthanc-databases
annotate Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h @ 524:48aba35fe64e large-queries
merged BEGIN and SET TRANSACTION statements
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 09 Jul 2024 16:30:52 +0200 |
parents | 54d518dcd74a |
children |
rev | line source |
---|---|
152 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium |
459
ecd0b719cff5
update year to 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
425
diff
changeset
|
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
152 | 8 * |
9 * This program is free software: you can redistribute it and/or | |
10 * modify it under the terms of the GNU General Public License as | |
11 * published by the Free Software Foundation, either version 3 of the | |
12 * License, or (at your option) any later version. | |
160 | 13 * |
152 | 14 * This program is distributed in the hope that it will be useful, but |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21 **/ | |
22 | |
23 | |
24 #pragma once | |
25 | |
26 #include "OrthancPluginException.h" | |
27 | |
28 #include <orthanc/OrthancCPlugin.h> | |
29 #include <boost/noncopyable.hpp> | |
30 #include <boost/lexical_cast.hpp> | |
31 #include <boost/date_time/posix_time/posix_time.hpp> | |
32 #include <json/value.h> | |
33 #include <vector> | |
34 #include <list> | |
35 #include <set> | |
36 #include <map> | |
37 | |
38 | |
39 | |
40 /** | |
41 * The definition of ORTHANC_PLUGINS_VERSION_IS_ABOVE below is for | |
42 * backward compatibility with Orthanc SDK <= 1.3.0. | |
43 * | |
44 * $ hg diff -r Orthanc-1.3.0:Orthanc-1.3.1 ../../../Plugins/Include/orthanc/OrthancCPlugin.h | |
45 * | |
46 **/ | |
47 #if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) | |
48 #define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \ | |
49 (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \ | |
50 (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \ | |
51 (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \ | |
52 (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \ | |
53 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision)))) | |
54 #endif | |
55 | |
56 | |
57 #if !defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE) | |
58 #define ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(major, minor, revision) \ | |
59 (ORTHANC_VERSION_MAJOR > major || \ | |
60 (ORTHANC_VERSION_MAJOR == major && \ | |
61 (ORTHANC_VERSION_MINOR > minor || \ | |
62 (ORTHANC_VERSION_MINOR == minor && \ | |
63 ORTHANC_VERSION_REVISION >= revision)))) | |
64 #endif | |
65 | |
66 | |
67 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0) | |
68 // The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0 | |
69 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 1 | |
70 #else | |
71 # define HAS_ORTHANC_PLUGIN_FIND_MATCHER 0 | |
72 #endif | |
73 | |
74 | |
75 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 4, 2) | |
76 # define HAS_ORTHANC_PLUGIN_PEERS 1 | |
77 # define HAS_ORTHANC_PLUGIN_JOB 1 | |
78 #else | |
79 # define HAS_ORTHANC_PLUGIN_PEERS 0 | |
80 # define HAS_ORTHANC_PLUGIN_JOB 0 | |
81 #endif | |
82 | |
83 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) | |
84 # define HAS_ORTHANC_PLUGIN_EXCEPTION_DETAILS 1 | |
85 #else | |
86 # define HAS_ORTHANC_PLUGIN_EXCEPTION_DETAILS 0 | |
87 #endif | |
88 | |
89 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 4) | |
90 # define HAS_ORTHANC_PLUGIN_METRICS 1 | |
91 #else | |
92 # define HAS_ORTHANC_PLUGIN_METRICS 0 | |
93 #endif | |
94 | |
95 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 1, 0) | |
96 # define HAS_ORTHANC_PLUGIN_HTTP_CLIENT 1 | |
97 #else | |
98 # define HAS_ORTHANC_PLUGIN_HTTP_CLIENT 0 | |
99 #endif | |
100 | |
101 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 7) | |
102 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_CLIENT 1 | |
103 #else | |
104 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_CLIENT 0 | |
105 #endif | |
106 | |
107 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 7) | |
108 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER 1 | |
109 #else | |
110 # define HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER 0 | |
111 #endif | |
112 | |
113 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 0) | |
114 # define HAS_ORTHANC_PLUGIN_STORAGE_COMMITMENT_SCP 1 | |
115 #else | |
116 # define HAS_ORTHANC_PLUGIN_STORAGE_COMMITMENT_SCP 0 | |
117 #endif | |
118 | |
397 | 119 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 9, 2) |
120 # define HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API 1 | |
121 #else | |
122 # define HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API 0 | |
123 #endif | |
124 | |
125 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 10, 1) | |
126 # define HAS_ORTHANC_PLUGIN_WEBDAV 1 | |
127 #else | |
128 # define HAS_ORTHANC_PLUGIN_WEBDAV 0 | |
129 #endif | |
130 | |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
131 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 4) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
132 # define HAS_ORTHANC_PLUGIN_LOG_MESSAGE 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
133 #else |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
134 # define HAS_ORTHANC_PLUGIN_LOG_MESSAGE 0 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
135 #endif |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
136 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
137 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
138 // Macro to tag a function as having been deprecated |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
139 #if (__cplusplus >= 201402L) // C++14 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
140 # define ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(f) [[deprecated]] f |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
141 #elif defined(__GNUC__) || defined(__clang__) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
142 # define ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(f) f __attribute__((deprecated)) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
143 #elif defined(_MSC_VER) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
144 # define ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(f) __declspec(deprecated) f |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
145 #else |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
146 # define ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
147 #endif |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
148 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
149 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
150 #if !defined(__ORTHANC_FILE__) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
151 # if defined(_MSC_VER) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
152 # pragma message("Warning: Macro __ORTHANC_FILE__ is not defined, this will leak the full path of the source files in the binaries") |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
153 # else |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
154 # warning Warning: Macro __ORTHANC_FILE__ is not defined, this will leak the full path of the source files in the binaries |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
155 # endif |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
156 # define __ORTHANC_FILE__ __FILE__ |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
157 #endif |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
158 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
159 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
160 #if HAS_ORTHANC_PLUGIN_LOG_MESSAGE == 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
161 # define ORTHANC_PLUGINS_LOG_ERROR(msg) ::OrthancPlugins::LogMessage(OrthancPluginLogLevel_Error, __ORTHANC_FILE__, __LINE__, msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
162 # define ORTHANC_PLUGINS_LOG_WARNING(msg) ::OrthancPlugins::LogMessage(OrthancPluginLogLevel_Warning, __ORTHANC_FILE__, __LINE__, msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
163 # define ORTHANC_PLUGINS_LOG_INFO(msg) ::OrthancPlugins::LogMessage(OrthancPluginLogLevel_Info, __ORTHANC_FILE__, __LINE__, msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
164 #else |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
165 # define ORTHANC_PLUGINS_LOG_ERROR(msg) ::OrthancPlugins::LogError(msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
166 # define ORTHANC_PLUGINS_LOG_WARNING(msg) ::OrthancPlugins::LogWarning(msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
167 # define ORTHANC_PLUGINS_LOG_INFO(msg) ::OrthancPlugins::LogInfo(msg) |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
168 #endif |
152 | 169 |
170 | |
171 namespace OrthancPlugins | |
172 { | |
173 typedef void (*RestCallback) (OrthancPluginRestOutput* output, | |
174 const char* url, | |
175 const OrthancPluginHttpRequest* request); | |
176 | |
177 void SetGlobalContext(OrthancPluginContext* context); | |
178 | |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
179 void SetGlobalContext(OrthancPluginContext* context, |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
180 const char* pluginName); |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
181 |
425 | 182 void ResetGlobalContext(); |
183 | |
152 | 184 bool HasGlobalContext(); |
185 | |
186 OrthancPluginContext* GetGlobalContext(); | |
187 | |
188 | |
189 class OrthancImage; | |
190 | |
191 | |
192 class MemoryBuffer : public boost::noncopyable | |
193 { | |
194 private: | |
195 OrthancPluginMemoryBuffer buffer_; | |
196 | |
197 void Check(OrthancPluginErrorCode code); | |
198 | |
199 bool CheckHttp(OrthancPluginErrorCode code); | |
200 | |
201 public: | |
202 MemoryBuffer(); | |
203 | |
204 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
205 // This constructor makes a copy of the given buffer in the memory | |
206 // handled by the Orthanc core | |
207 MemoryBuffer(const void* buffer, | |
208 size_t size); | |
209 #endif | |
210 | |
211 ~MemoryBuffer() | |
212 { | |
213 Clear(); | |
214 } | |
215 | |
216 OrthancPluginMemoryBuffer* operator*() | |
217 { | |
218 return &buffer_; | |
219 } | |
220 | |
221 // This transfers ownership from "other" to "this" | |
222 void Assign(OrthancPluginMemoryBuffer& other); | |
223 | |
224 void Swap(MemoryBuffer& other); | |
225 | |
226 OrthancPluginMemoryBuffer Release(); | |
227 | |
228 const char* GetData() const | |
229 { | |
230 if (buffer_.size > 0) | |
231 { | |
232 return reinterpret_cast<const char*>(buffer_.data); | |
233 } | |
234 else | |
235 { | |
236 return NULL; | |
237 } | |
238 } | |
239 | |
240 size_t GetSize() const | |
241 { | |
242 return buffer_.size; | |
243 } | |
244 | |
245 bool IsEmpty() const | |
246 { | |
247 return GetSize() == 0 || GetData() == NULL; | |
248 } | |
249 | |
250 void Clear(); | |
251 | |
252 void ToString(std::string& target) const; | |
253 | |
254 void ToJson(Json::Value& target) const; | |
255 | |
256 bool RestApiGet(const std::string& uri, | |
257 bool applyPlugins); | |
258 | |
259 bool RestApiGet(const std::string& uri, | |
260 const std::map<std::string, std::string>& httpHeaders, | |
261 bool applyPlugins); | |
262 | |
263 bool RestApiPost(const std::string& uri, | |
264 const void* body, | |
265 size_t bodySize, | |
266 bool applyPlugins); | |
267 | |
268 bool RestApiPut(const std::string& uri, | |
269 const void* body, | |
270 size_t bodySize, | |
271 bool applyPlugins); | |
272 | |
273 bool RestApiPost(const std::string& uri, | |
274 const Json::Value& body, | |
275 bool applyPlugins); | |
276 | |
397 | 277 #if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 |
278 bool RestApiPost(const std::string& uri, | |
279 const Json::Value& body, | |
280 const std::map<std::string, std::string>& httpHeaders, | |
281 bool applyPlugins); | |
282 | |
283 bool RestApiPost(const std::string& uri, | |
284 const void* body, | |
285 size_t bodySize, | |
286 const std::map<std::string, std::string>& httpHeaders, | |
287 bool applyPlugins); | |
288 #endif | |
289 | |
152 | 290 bool RestApiPut(const std::string& uri, |
291 const Json::Value& body, | |
292 bool applyPlugins); | |
293 | |
294 bool RestApiPost(const std::string& uri, | |
295 const std::string& body, | |
296 bool applyPlugins) | |
297 { | |
298 return RestApiPost(uri, body.empty() ? NULL : body.c_str(), body.size(), applyPlugins); | |
299 } | |
300 | |
301 bool RestApiPut(const std::string& uri, | |
302 const std::string& body, | |
303 bool applyPlugins) | |
304 { | |
305 return RestApiPut(uri, body.empty() ? NULL : body.c_str(), body.size(), applyPlugins); | |
306 } | |
307 | |
308 void CreateDicom(const Json::Value& tags, | |
309 OrthancPluginCreateDicomFlags flags); | |
310 | |
311 void CreateDicom(const Json::Value& tags, | |
312 const OrthancImage& pixelData, | |
313 OrthancPluginCreateDicomFlags flags); | |
314 | |
315 void ReadFile(const std::string& path); | |
316 | |
317 void GetDicomQuery(const OrthancPluginWorklistQuery* query); | |
318 | |
319 void DicomToJson(Json::Value& target, | |
320 OrthancPluginDicomToJsonFormat format, | |
321 OrthancPluginDicomToJsonFlags flags, | |
322 uint32_t maxStringLength); | |
323 | |
324 bool HttpGet(const std::string& url, | |
325 const std::string& username, | |
326 const std::string& password); | |
327 | |
328 bool HttpPost(const std::string& url, | |
329 const std::string& body, | |
330 const std::string& username, | |
331 const std::string& password); | |
332 | |
333 bool HttpPut(const std::string& url, | |
334 const std::string& body, | |
335 const std::string& username, | |
336 const std::string& password); | |
337 | |
338 void GetDicomInstance(const std::string& instanceId); | |
339 }; | |
340 | |
341 | |
342 class OrthancString : public boost::noncopyable | |
343 { | |
344 private: | |
345 char* str_; | |
346 | |
347 void Clear(); | |
348 | |
349 public: | |
350 OrthancString() : | |
351 str_(NULL) | |
352 { | |
353 } | |
354 | |
355 ~OrthancString() | |
356 { | |
357 Clear(); | |
358 } | |
359 | |
360 // This transfers ownership, warning: The string must have been | |
361 // allocated by the Orthanc core | |
362 void Assign(char* str); | |
363 | |
364 const char* GetContent() const | |
365 { | |
366 return str_; | |
367 } | |
368 | |
397 | 369 bool IsNullOrEmpty() const |
370 { | |
371 return str_ == NULL || str_[0] == 0; | |
372 } | |
373 | |
152 | 374 void ToString(std::string& target) const; |
375 | |
376 void ToJson(Json::Value& target) const; | |
397 | 377 |
378 void ToJsonWithoutComments(Json::Value& target) const; | |
379 }; | |
152 | 380 |
381 | |
382 class OrthancConfiguration : public boost::noncopyable | |
383 { | |
384 private: | |
385 Json::Value configuration_; // Necessarily a Json::objectValue | |
386 std::string path_; | |
387 | |
388 std::string GetPath(const std::string& key) const; | |
389 | |
390 void LoadConfiguration(); | |
391 | |
392 public: | |
397 | 393 OrthancConfiguration(); // loads the full Orthanc configuration |
152 | 394 |
395 explicit OrthancConfiguration(bool load); | |
396 | |
397 | 397 explicit OrthancConfiguration(const Json::Value& configuration, const std::string& path); // e.g. to load a section from a default json content |
398 | |
152 | 399 const Json::Value& GetJson() const |
400 { | |
401 return configuration_; | |
402 } | |
403 | |
404 bool IsSection(const std::string& key) const; | |
405 | |
406 void GetSection(OrthancConfiguration& target, | |
407 const std::string& key) const; | |
408 | |
409 bool LookupStringValue(std::string& target, | |
410 const std::string& key) const; | |
411 | |
412 bool LookupIntegerValue(int& target, | |
413 const std::string& key) const; | |
414 | |
415 bool LookupUnsignedIntegerValue(unsigned int& target, | |
416 const std::string& key) const; | |
417 | |
418 bool LookupBooleanValue(bool& target, | |
419 const std::string& key) const; | |
420 | |
421 bool LookupFloatValue(float& target, | |
422 const std::string& key) const; | |
423 | |
424 bool LookupListOfStrings(std::list<std::string>& target, | |
425 const std::string& key, | |
426 bool allowSingleString) const; | |
427 | |
428 bool LookupSetOfStrings(std::set<std::string>& target, | |
429 const std::string& key, | |
430 bool allowSingleString) const; | |
431 | |
432 std::string GetStringValue(const std::string& key, | |
433 const std::string& defaultValue) const; | |
434 | |
435 int GetIntegerValue(const std::string& key, | |
436 int defaultValue) const; | |
437 | |
438 unsigned int GetUnsignedIntegerValue(const std::string& key, | |
439 unsigned int defaultValue) const; | |
440 | |
441 bool GetBooleanValue(const std::string& key, | |
442 bool defaultValue) const; | |
443 | |
444 float GetFloatValue(const std::string& key, | |
445 float defaultValue) const; | |
446 | |
447 void GetDictionary(std::map<std::string, std::string>& target, | |
448 const std::string& key) const; | |
449 }; | |
450 | |
451 class OrthancImage : public boost::noncopyable | |
452 { | |
453 private: | |
454 OrthancPluginImage* image_; | |
455 | |
456 void Clear(); | |
457 | |
458 void CheckImageAvailable() const; | |
459 | |
460 public: | |
461 OrthancImage(); | |
462 | |
463 explicit OrthancImage(OrthancPluginImage* image); | |
464 | |
465 OrthancImage(OrthancPluginPixelFormat format, | |
466 uint32_t width, | |
467 uint32_t height); | |
468 | |
469 OrthancImage(OrthancPluginPixelFormat format, | |
470 uint32_t width, | |
471 uint32_t height, | |
472 uint32_t pitch, | |
473 void* buffer); | |
474 | |
475 ~OrthancImage() | |
476 { | |
477 Clear(); | |
478 } | |
479 | |
480 void UncompressPngImage(const void* data, | |
481 size_t size); | |
482 | |
483 void UncompressJpegImage(const void* data, | |
484 size_t size); | |
485 | |
486 void DecodeDicomImage(const void* data, | |
487 size_t size, | |
488 unsigned int frame); | |
489 | |
490 OrthancPluginPixelFormat GetPixelFormat() const; | |
491 | |
492 unsigned int GetWidth() const; | |
493 | |
494 unsigned int GetHeight() const; | |
495 | |
496 unsigned int GetPitch() const; | |
497 | |
498 void* GetBuffer() const; | |
499 | |
500 const OrthancPluginImage* GetObject() const | |
501 { | |
502 return image_; | |
503 } | |
504 | |
505 void CompressPngImage(MemoryBuffer& target) const; | |
506 | |
507 void CompressJpegImage(MemoryBuffer& target, | |
508 uint8_t quality) const; | |
509 | |
510 void AnswerPngImage(OrthancPluginRestOutput* output) const; | |
511 | |
512 void AnswerJpegImage(OrthancPluginRestOutput* output, | |
513 uint8_t quality) const; | |
514 | |
515 void* GetWriteableBuffer(); | |
516 | |
517 OrthancPluginImage* Release(); | |
518 }; | |
519 | |
520 | |
521 #if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 | |
522 class FindMatcher : public boost::noncopyable | |
523 { | |
524 private: | |
525 OrthancPluginFindMatcher* matcher_; | |
526 const OrthancPluginWorklistQuery* worklist_; | |
527 | |
528 void SetupDicom(const void* query, | |
529 uint32_t size); | |
530 | |
531 public: | |
532 explicit FindMatcher(const OrthancPluginWorklistQuery* worklist); | |
533 | |
534 FindMatcher(const void* query, | |
535 uint32_t size) | |
536 { | |
537 SetupDicom(query, size); | |
538 } | |
539 | |
540 explicit FindMatcher(const MemoryBuffer& dicom) | |
541 { | |
542 SetupDicom(dicom.GetData(), dicom.GetSize()); | |
543 } | |
544 | |
545 ~FindMatcher(); | |
546 | |
547 bool IsMatch(const void* dicom, | |
548 uint32_t size) const; | |
549 | |
550 bool IsMatch(const MemoryBuffer& dicom) const | |
551 { | |
552 return IsMatch(dicom.GetData(), dicom.GetSize()); | |
553 } | |
554 }; | |
555 #endif | |
556 | |
557 | |
193
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
558 bool ReadJson(Json::Value& target, |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
559 const std::string& source); |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
560 |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
561 bool ReadJson(Json::Value& target, |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
562 const void* buffer, |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
563 size_t size); |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
564 |
272
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
565 bool ReadJsonWithoutComments(Json::Value& target, |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
566 const std::string& source); |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
567 |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
568 bool ReadJsonWithoutComments(Json::Value& target, |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
569 const void* buffer, |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
570 size_t size); |
c7dc70a0a477
upgrade to Orthanc SDK 1.9.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
571 |
193
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
572 void WriteFastJson(std::string& target, |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
573 const Json::Value& source); |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
574 |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
575 void WriteStyledJson(std::string& target, |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
576 const Json::Value& source); |
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
170
diff
changeset
|
577 |
152 | 578 bool RestApiGet(Json::Value& result, |
579 const std::string& uri, | |
580 bool applyPlugins); | |
581 | |
397 | 582 bool RestApiGet(Json::Value& result, |
583 const std::string& uri, | |
584 const std::map<std::string, std::string>& httpHeaders, | |
585 bool applyPlugins); | |
586 | |
152 | 587 bool RestApiGetString(std::string& result, |
588 const std::string& uri, | |
589 bool applyPlugins); | |
590 | |
591 bool RestApiGetString(std::string& result, | |
592 const std::string& uri, | |
593 const std::map<std::string, std::string>& httpHeaders, | |
594 bool applyPlugins); | |
595 | |
596 bool RestApiPost(std::string& result, | |
597 const std::string& uri, | |
598 const void* body, | |
599 size_t bodySize, | |
600 bool applyPlugins); | |
601 | |
602 bool RestApiPost(Json::Value& result, | |
603 const std::string& uri, | |
604 const void* body, | |
605 size_t bodySize, | |
606 bool applyPlugins); | |
607 | |
397 | 608 #if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 |
609 bool RestApiPost(Json::Value& result, | |
610 const std::string& uri, | |
611 const Json::Value& body, | |
612 const std::map<std::string, std::string>& httpHeaders, | |
613 bool applyPlugins); | |
614 #endif | |
615 | |
152 | 616 bool RestApiPost(Json::Value& result, |
617 const std::string& uri, | |
618 const Json::Value& body, | |
619 bool applyPlugins); | |
620 | |
621 inline bool RestApiPost(Json::Value& result, | |
622 const std::string& uri, | |
623 const std::string& body, | |
624 bool applyPlugins) | |
625 { | |
626 return RestApiPost(result, uri, body.empty() ? NULL : body.c_str(), | |
627 body.size(), applyPlugins); | |
628 } | |
629 | |
630 inline bool RestApiPost(Json::Value& result, | |
631 const std::string& uri, | |
632 const MemoryBuffer& body, | |
633 bool applyPlugins) | |
634 { | |
635 return RestApiPost(result, uri, body.GetData(), | |
636 body.GetSize(), applyPlugins); | |
637 } | |
638 | |
639 bool RestApiPut(Json::Value& result, | |
640 const std::string& uri, | |
641 const void* body, | |
642 size_t bodySize, | |
643 bool applyPlugins); | |
644 | |
645 bool RestApiPut(Json::Value& result, | |
646 const std::string& uri, | |
647 const Json::Value& body, | |
648 bool applyPlugins); | |
649 | |
650 inline bool RestApiPut(Json::Value& result, | |
651 const std::string& uri, | |
652 const std::string& body, | |
653 bool applyPlugins) | |
654 { | |
655 return RestApiPut(result, uri, body.empty() ? NULL : body.c_str(), | |
656 body.size(), applyPlugins); | |
657 } | |
658 | |
659 bool RestApiDelete(const std::string& uri, | |
660 bool applyPlugins); | |
661 | |
662 bool HttpDelete(const std::string& url, | |
663 const std::string& username, | |
664 const std::string& password); | |
665 | |
666 void AnswerJson(const Json::Value& value, | |
667 OrthancPluginRestOutput* output); | |
668 | |
669 void AnswerString(const std::string& answer, | |
670 const char* mimeType, | |
671 OrthancPluginRestOutput* output); | |
672 | |
673 void AnswerHttpError(uint16_t httpError, | |
674 OrthancPluginRestOutput* output); | |
675 | |
676 void AnswerMethodNotAllowed(OrthancPluginRestOutput* output, const char* allowedMethods); | |
677 | |
678 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) | |
679 const char* AutodetectMimeType(const std::string& path); | |
680 #endif | |
681 | |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
682 #if HAS_ORTHANC_PLUGIN_LOG_MESSAGE == 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
683 void LogMessage(OrthancPluginLogLevel level, |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
684 const char* file, |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
685 uint32_t line, |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
686 const std::string& message); |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
687 #endif |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
688 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
689 #if HAS_ORTHANC_PLUGIN_LOG_MESSAGE == 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
690 // Use macro ORTHANC_PLUGINS_LOG_ERROR() instead |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
691 ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(void LogError(const std::string& message)); |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
692 #else |
152 | 693 void LogError(const std::string& message); |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
694 #endif |
152 | 695 |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
696 #if HAS_ORTHANC_PLUGIN_LOG_MESSAGE == 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
697 // Use macro ORTHANC_PLUGINS_LOG_WARNING() instead |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
698 ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(void LogWarning(const std::string& message)); |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
699 #else |
152 | 700 void LogWarning(const std::string& message); |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
701 #endif |
152 | 702 |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
703 #if HAS_ORTHANC_PLUGIN_LOG_MESSAGE == 1 |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
704 // Use macro ORTHANC_PLUGINS_LOG_INFO() instead |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
705 ORTHANC_PLUGIN_CPP_WRAPPER_DEPRECATED(void LogInfo(const std::string& message)); |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
706 #else |
152 | 707 void LogInfo(const std::string& message); |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
491
diff
changeset
|
708 #endif |
152 | 709 |
710 void ReportMinimalOrthancVersion(unsigned int major, | |
711 unsigned int minor, | |
712 unsigned int revision); | |
713 | |
714 bool CheckMinimalOrthancVersion(unsigned int major, | |
715 unsigned int minor, | |
716 unsigned int revision); | |
717 | |
397 | 718 bool CheckMinimalVersion(const char* version, |
719 unsigned int major, | |
720 unsigned int minor, | |
721 unsigned int revision); | |
152 | 722 |
723 namespace Internals | |
724 { | |
725 template <RestCallback Callback> | |
726 static OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, | |
727 const char* url, | |
728 const OrthancPluginHttpRequest* request) | |
729 { | |
730 try | |
731 { | |
732 Callback(output, url, request); | |
733 return OrthancPluginErrorCode_Success; | |
734 } | |
735 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
736 { | |
737 #if HAS_ORTHANC_EXCEPTION == 1 && HAS_ORTHANC_PLUGIN_EXCEPTION_DETAILS == 1 | |
738 if (HasGlobalContext() && | |
739 e.HasDetails()) | |
740 { | |
741 // The "false" instructs Orthanc not to log the detailed | |
742 // error message. This is to avoid duplicating the details, | |
743 // because "OrthancException" already does it on construction. | |
744 OrthancPluginSetHttpErrorDetails | |
745 (GetGlobalContext(), output, e.GetDetails(), false); | |
746 } | |
747 #endif | |
748 | |
749 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
750 } | |
751 catch (boost::bad_lexical_cast&) | |
752 { | |
753 return OrthancPluginErrorCode_BadFileFormat; | |
754 } | |
755 catch (...) | |
756 { | |
757 return OrthancPluginErrorCode_Plugin; | |
758 } | |
759 } | |
760 } | |
761 | |
762 | |
763 template <RestCallback Callback> | |
764 void RegisterRestCallback(const std::string& uri, | |
765 bool isThreadSafe) | |
766 { | |
767 if (isThreadSafe) | |
768 { | |
769 OrthancPluginRegisterRestCallbackNoLock | |
770 (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>); | |
771 } | |
772 else | |
773 { | |
774 OrthancPluginRegisterRestCallback | |
775 (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>); | |
776 } | |
777 } | |
778 | |
779 | |
780 #if HAS_ORTHANC_PLUGIN_PEERS == 1 | |
781 class OrthancPeers : public boost::noncopyable | |
782 { | |
783 private: | |
784 typedef std::map<std::string, uint32_t> Index; | |
785 | |
786 OrthancPluginPeers *peers_; | |
787 Index index_; | |
788 uint32_t timeout_; | |
789 | |
790 size_t GetPeerIndex(const std::string& name) const; | |
791 | |
792 public: | |
793 OrthancPeers(); | |
794 | |
795 ~OrthancPeers(); | |
796 | |
797 uint32_t GetTimeout() const | |
798 { | |
799 return timeout_; | |
800 } | |
801 | |
802 void SetTimeout(uint32_t timeout) | |
803 { | |
804 timeout_ = timeout; | |
805 } | |
806 | |
807 bool LookupName(size_t& target, | |
808 const std::string& name) const; | |
809 | |
810 std::string GetPeerName(size_t index) const; | |
811 | |
812 std::string GetPeerUrl(size_t index) const; | |
813 | |
814 std::string GetPeerUrl(const std::string& name) const; | |
815 | |
816 size_t GetPeersCount() const | |
817 { | |
818 return index_.size(); | |
819 } | |
820 | |
821 bool LookupUserProperty(std::string& value, | |
822 size_t index, | |
823 const std::string& key) const; | |
824 | |
825 bool LookupUserProperty(std::string& value, | |
826 const std::string& peer, | |
827 const std::string& key) const; | |
828 | |
829 bool DoGet(MemoryBuffer& target, | |
830 size_t index, | |
397 | 831 const std::string& uri, |
832 const std::map<std::string, std::string>& headers) const; | |
152 | 833 |
834 bool DoGet(MemoryBuffer& target, | |
835 const std::string& name, | |
397 | 836 const std::string& uri, |
837 const std::map<std::string, std::string>& headers) const; | |
152 | 838 |
839 bool DoGet(Json::Value& target, | |
840 size_t index, | |
397 | 841 const std::string& uri, |
842 const std::map<std::string, std::string>& headers) const; | |
152 | 843 |
844 bool DoGet(Json::Value& target, | |
845 const std::string& name, | |
397 | 846 const std::string& uri, |
847 const std::map<std::string, std::string>& headers) const; | |
152 | 848 |
849 bool DoPost(MemoryBuffer& target, | |
850 size_t index, | |
851 const std::string& uri, | |
397 | 852 const std::string& body, |
853 const std::map<std::string, std::string>& headers) const; | |
152 | 854 |
855 bool DoPost(MemoryBuffer& target, | |
856 const std::string& name, | |
857 const std::string& uri, | |
397 | 858 const std::string& body, |
859 const std::map<std::string, std::string>& headers) const; | |
152 | 860 |
861 bool DoPost(Json::Value& target, | |
862 size_t index, | |
863 const std::string& uri, | |
397 | 864 const std::string& body, |
865 const std::map<std::string, std::string>& headers) const; | |
152 | 866 |
867 bool DoPost(Json::Value& target, | |
868 const std::string& name, | |
869 const std::string& uri, | |
397 | 870 const std::string& body, |
871 const std::map<std::string, std::string>& headers) const; | |
152 | 872 |
873 bool DoPut(size_t index, | |
874 const std::string& uri, | |
397 | 875 const std::string& body, |
876 const std::map<std::string, std::string>& headers) const; | |
152 | 877 |
878 bool DoPut(const std::string& name, | |
879 const std::string& uri, | |
397 | 880 const std::string& body, |
881 const std::map<std::string, std::string>& headers) const; | |
152 | 882 |
883 bool DoDelete(size_t index, | |
397 | 884 const std::string& uri, |
885 const std::map<std::string, std::string>& headers) const; | |
152 | 886 |
887 bool DoDelete(const std::string& name, | |
397 | 888 const std::string& uri, |
889 const std::map<std::string, std::string>& headers) const; | |
152 | 890 }; |
891 #endif | |
892 | |
893 | |
894 | |
895 #if HAS_ORTHANC_PLUGIN_JOB == 1 | |
896 class OrthancJob : public boost::noncopyable | |
897 { | |
898 private: | |
899 std::string jobType_; | |
900 std::string content_; | |
901 bool hasSerialized_; | |
902 std::string serialized_; | |
903 float progress_; | |
904 | |
905 static void CallbackFinalize(void* job); | |
906 | |
907 static float CallbackGetProgress(void* job); | |
908 | |
397 | 909 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) |
910 static OrthancPluginErrorCode CallbackGetContent(OrthancPluginMemoryBuffer* target, | |
911 void* job); | |
912 #else | |
152 | 913 static const char* CallbackGetContent(void* job); |
397 | 914 #endif |
152 | 915 |
397 | 916 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) |
917 static int32_t CallbackGetSerialized(OrthancPluginMemoryBuffer* target, | |
918 void* job); | |
919 #else | |
152 | 920 static const char* CallbackGetSerialized(void* job); |
397 | 921 #endif |
152 | 922 |
923 static OrthancPluginJobStepStatus CallbackStep(void* job); | |
924 | |
925 static OrthancPluginErrorCode CallbackStop(void* job, | |
926 OrthancPluginJobStopReason reason); | |
927 | |
928 static OrthancPluginErrorCode CallbackReset(void* job); | |
929 | |
930 protected: | |
931 void ClearContent(); | |
932 | |
933 void UpdateContent(const Json::Value& content); | |
934 | |
935 void ClearSerialized(); | |
936 | |
937 void UpdateSerialized(const Json::Value& serialized); | |
938 | |
939 void UpdateProgress(float progress); | |
940 | |
941 public: | |
170 | 942 explicit OrthancJob(const std::string& jobType); |
152 | 943 |
944 virtual ~OrthancJob() | |
945 { | |
946 } | |
947 | |
948 virtual OrthancPluginJobStepStatus Step() = 0; | |
949 | |
950 virtual void Stop(OrthancPluginJobStopReason reason) = 0; | |
951 | |
952 virtual void Reset() = 0; | |
953 | |
954 static OrthancPluginJob* Create(OrthancJob* job /* takes ownership */); | |
955 | |
956 static std::string Submit(OrthancJob* job /* takes ownership */, | |
957 int priority); | |
958 | |
959 static void SubmitAndWait(Json::Value& result, | |
960 OrthancJob* job /* takes ownership */, | |
961 int priority); | |
962 | |
963 // Submit a job from a POST on the REST API with the same | |
964 // conventions as in the Orthanc core (according to the | |
965 // "Synchronous" and "Priority" options) | |
966 static void SubmitFromRestApiPost(OrthancPluginRestOutput* output, | |
967 const Json::Value& body, | |
968 OrthancJob* job); | |
969 }; | |
970 #endif | |
971 | |
972 | |
973 #if HAS_ORTHANC_PLUGIN_METRICS == 1 | |
974 inline void SetMetricsValue(char* name, | |
975 float value) | |
976 { | |
977 OrthancPluginSetMetricsValue(GetGlobalContext(), name, | |
978 value, OrthancPluginMetricsType_Default); | |
979 } | |
980 | |
981 class MetricsTimer : public boost::noncopyable | |
982 { | |
983 private: | |
984 std::string name_; | |
985 boost::posix_time::ptime start_; | |
986 | |
987 public: | |
988 explicit MetricsTimer(const char* name); | |
989 | |
990 ~MetricsTimer(); | |
991 }; | |
992 #endif | |
993 | |
994 | |
995 #if HAS_ORTHANC_PLUGIN_HTTP_CLIENT == 1 | |
996 class HttpClient : public boost::noncopyable | |
997 { | |
998 public: | |
999 typedef std::map<std::string, std::string> HttpHeaders; | |
1000 | |
1001 class IRequestBody : public boost::noncopyable | |
1002 { | |
1003 public: | |
1004 virtual ~IRequestBody() | |
1005 { | |
1006 } | |
1007 | |
1008 virtual bool ReadNextChunk(std::string& chunk) = 0; | |
1009 }; | |
1010 | |
1011 | |
1012 class IAnswer : public boost::noncopyable | |
1013 { | |
1014 public: | |
1015 virtual ~IAnswer() | |
1016 { | |
1017 } | |
1018 | |
1019 virtual void AddHeader(const std::string& key, | |
1020 const std::string& value) = 0; | |
1021 | |
1022 virtual void AddChunk(const void* data, | |
1023 size_t size) = 0; | |
1024 }; | |
1025 | |
1026 | |
1027 private: | |
1028 class RequestBodyWrapper; | |
1029 | |
1030 uint16_t httpStatus_; | |
1031 OrthancPluginHttpMethod method_; | |
1032 std::string url_; | |
1033 HttpHeaders headers_; | |
1034 std::string username_; | |
1035 std::string password_; | |
1036 uint32_t timeout_; | |
1037 std::string certificateFile_; | |
1038 std::string certificateKeyFile_; | |
1039 std::string certificateKeyPassword_; | |
1040 bool pkcs11_; | |
1041 std::string fullBody_; | |
1042 IRequestBody* chunkedBody_; | |
1043 bool allowChunkedTransfers_; | |
1044 | |
1045 #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_CLIENT == 1 | |
1046 void ExecuteWithStream(uint16_t& httpStatus, // out | |
1047 IAnswer& answer, // out | |
1048 IRequestBody& body) const; | |
1049 #endif | |
1050 | |
1051 void ExecuteWithoutStream(uint16_t& httpStatus, // out | |
1052 HttpHeaders& answerHeaders, // out | |
1053 std::string& answerBody, // out | |
1054 const std::string& body) const; | |
1055 | |
1056 public: | |
1057 HttpClient(); | |
1058 | |
1059 uint16_t GetHttpStatus() const | |
1060 { | |
1061 return httpStatus_; | |
1062 } | |
1063 | |
1064 void SetMethod(OrthancPluginHttpMethod method) | |
1065 { | |
1066 method_ = method; | |
1067 } | |
1068 | |
1069 const std::string& GetUrl() const | |
1070 { | |
1071 return url_; | |
1072 } | |
1073 | |
1074 void SetUrl(const std::string& url) | |
1075 { | |
1076 url_ = url; | |
1077 } | |
1078 | |
1079 void SetHeaders(const HttpHeaders& headers) | |
1080 { | |
1081 headers_ = headers; | |
1082 } | |
1083 | |
1084 void AddHeader(const std::string& key, | |
1085 const std::string& value) | |
1086 { | |
1087 headers_[key] = value; | |
1088 } | |
1089 | |
1090 void AddHeaders(const HttpHeaders& headers); | |
1091 | |
1092 void SetCredentials(const std::string& username, | |
1093 const std::string& password); | |
1094 | |
1095 void ClearCredentials(); | |
1096 | |
1097 void SetTimeout(unsigned int timeout) // 0 for default timeout | |
1098 { | |
1099 timeout_ = timeout; | |
1100 } | |
1101 | |
1102 void SetCertificate(const std::string& certificateFile, | |
1103 const std::string& keyFile, | |
1104 const std::string& keyPassword); | |
1105 | |
1106 void ClearCertificate(); | |
1107 | |
1108 void SetPkcs11(bool pkcs11) | |
1109 { | |
1110 pkcs11_ = pkcs11; | |
1111 } | |
1112 | |
1113 void ClearBody(); | |
1114 | |
1115 void SwapBody(std::string& body); | |
1116 | |
1117 void SetBody(const std::string& body); | |
1118 | |
1119 void SetBody(IRequestBody& body); | |
1120 | |
1121 // This function can be used to disable chunked transfers if the | |
1122 // remote server is Orthanc with a version <= 1.5.6. | |
1123 void SetChunkedTransfersAllowed(bool allow) | |
1124 { | |
1125 allowChunkedTransfers_ = allow; | |
1126 } | |
1127 | |
1128 bool IsChunkedTransfersAllowed() const | |
1129 { | |
1130 return allowChunkedTransfers_; | |
1131 } | |
1132 | |
1133 void Execute(IAnswer& answer); | |
1134 | |
1135 void Execute(HttpHeaders& answerHeaders /* out */, | |
1136 std::string& answerBody /* out */); | |
1137 | |
1138 void Execute(HttpHeaders& answerHeaders /* out */, | |
1139 Json::Value& answerBody /* out */); | |
1140 | |
1141 void Execute(); | |
1142 }; | |
1143 #endif | |
1144 | |
1145 | |
1146 | |
1147 class IChunkedRequestReader : public boost::noncopyable | |
1148 { | |
1149 public: | |
1150 virtual ~IChunkedRequestReader() | |
1151 { | |
1152 } | |
1153 | |
1154 virtual void AddChunk(const void* data, | |
1155 size_t size) = 0; | |
1156 | |
1157 virtual void Execute(OrthancPluginRestOutput* output) = 0; | |
1158 }; | |
1159 | |
1160 | |
1161 typedef IChunkedRequestReader* (*ChunkedRestCallback) (const char* url, | |
1162 const OrthancPluginHttpRequest* request); | |
1163 | |
1164 | |
1165 namespace Internals | |
1166 { | |
1167 void NullRestCallback(OrthancPluginRestOutput* output, | |
1168 const char* url, | |
1169 const OrthancPluginHttpRequest* request); | |
1170 | |
1171 IChunkedRequestReader *NullChunkedRestCallback(const char* url, | |
1172 const OrthancPluginHttpRequest* request); | |
1173 | |
1174 | |
1175 #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 | |
1176 template <ChunkedRestCallback Callback> | |
1177 static OrthancPluginErrorCode ChunkedProtect(OrthancPluginServerChunkedRequestReader** reader, | |
1178 const char* url, | |
1179 const OrthancPluginHttpRequest* request) | |
1180 { | |
1181 try | |
1182 { | |
1183 if (reader == NULL) | |
1184 { | |
1185 return OrthancPluginErrorCode_InternalError; | |
1186 } | |
1187 else | |
1188 { | |
1189 *reader = reinterpret_cast<OrthancPluginServerChunkedRequestReader*>(Callback(url, request)); | |
1190 if (*reader == NULL) | |
1191 { | |
1192 return OrthancPluginErrorCode_Plugin; | |
1193 } | |
1194 else | |
1195 { | |
1196 return OrthancPluginErrorCode_Success; | |
1197 } | |
1198 } | |
1199 } | |
1200 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
1201 { | |
1202 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1203 } | |
1204 catch (boost::bad_lexical_cast&) | |
1205 { | |
1206 return OrthancPluginErrorCode_BadFileFormat; | |
1207 } | |
1208 catch (...) | |
1209 { | |
1210 return OrthancPluginErrorCode_Plugin; | |
1211 } | |
1212 } | |
1213 | |
1214 OrthancPluginErrorCode ChunkedRequestReaderAddChunk( | |
1215 OrthancPluginServerChunkedRequestReader* reader, | |
1216 const void* data, | |
1217 uint32_t size); | |
1218 | |
1219 OrthancPluginErrorCode ChunkedRequestReaderExecute( | |
1220 OrthancPluginServerChunkedRequestReader* reader, | |
1221 OrthancPluginRestOutput* output); | |
1222 | |
1223 void ChunkedRequestReaderFinalize( | |
1224 OrthancPluginServerChunkedRequestReader* reader); | |
1225 | |
1226 #else | |
1227 | |
1228 OrthancPluginErrorCode ChunkedRestCompatibility(OrthancPluginRestOutput* output, | |
1229 const char* url, | |
1230 const OrthancPluginHttpRequest* request, | |
1231 RestCallback GetHandler, | |
1232 ChunkedRestCallback PostHandler, | |
1233 RestCallback DeleteHandler, | |
1234 ChunkedRestCallback PutHandler); | |
1235 | |
1236 template< | |
1237 RestCallback GetHandler, | |
1238 ChunkedRestCallback PostHandler, | |
1239 RestCallback DeleteHandler, | |
1240 ChunkedRestCallback PutHandler | |
1241 > | |
1242 inline OrthancPluginErrorCode ChunkedRestCompatibility(OrthancPluginRestOutput* output, | |
1243 const char* url, | |
1244 const OrthancPluginHttpRequest* request) | |
1245 { | |
1246 return ChunkedRestCompatibility(output, url, request, GetHandler, | |
1247 PostHandler, DeleteHandler, PutHandler); | |
1248 } | |
1249 #endif | |
1250 } | |
1251 | |
1252 | |
1253 | |
1254 // NB: We use a templated class instead of a templated function, because | |
1255 // default values are only available in functions since C++11 | |
1256 template< | |
1257 RestCallback GetHandler = Internals::NullRestCallback, | |
1258 ChunkedRestCallback PostHandler = Internals::NullChunkedRestCallback, | |
1259 RestCallback DeleteHandler = Internals::NullRestCallback, | |
1260 ChunkedRestCallback PutHandler = Internals::NullChunkedRestCallback | |
1261 > | |
1262 class ChunkedRestRegistration : public boost::noncopyable | |
1263 { | |
1264 public: | |
1265 static void Apply(const std::string& uri) | |
1266 { | |
1267 #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 | |
1268 OrthancPluginRegisterChunkedRestCallback( | |
1269 GetGlobalContext(), uri.c_str(), | |
1270 GetHandler == Internals::NullRestCallback ? NULL : Internals::Protect<GetHandler>, | |
1271 PostHandler == Internals::NullChunkedRestCallback ? NULL : Internals::ChunkedProtect<PostHandler>, | |
1272 DeleteHandler == Internals::NullRestCallback ? NULL : Internals::Protect<DeleteHandler>, | |
1273 PutHandler == Internals::NullChunkedRestCallback ? NULL : Internals::ChunkedProtect<PutHandler>, | |
1274 Internals::ChunkedRequestReaderAddChunk, | |
1275 Internals::ChunkedRequestReaderExecute, | |
1276 Internals::ChunkedRequestReaderFinalize); | |
1277 #else | |
1278 OrthancPluginRegisterRestCallbackNoLock( | |
1279 GetGlobalContext(), uri.c_str(), | |
1280 Internals::ChunkedRestCompatibility<GetHandler, PostHandler, DeleteHandler, PutHandler>); | |
1281 #endif | |
1282 } | |
1283 }; | |
1284 | |
1285 | |
1286 | |
1287 #if HAS_ORTHANC_PLUGIN_STORAGE_COMMITMENT_SCP == 1 | |
1288 class IStorageCommitmentScpHandler : public boost::noncopyable | |
1289 { | |
1290 public: | |
1291 virtual ~IStorageCommitmentScpHandler() | |
1292 { | |
1293 } | |
1294 | |
1295 virtual OrthancPluginStorageCommitmentFailureReason Lookup(const std::string& sopClassUid, | |
1296 const std::string& sopInstanceUid) = 0; | |
1297 | |
1298 static OrthancPluginErrorCode Lookup(OrthancPluginStorageCommitmentFailureReason* target, | |
1299 void* rawHandler, | |
1300 const char* sopClassUid, | |
1301 const char* sopInstanceUid); | |
1302 | |
1303 static void Destructor(void* rawHandler); | |
1304 }; | |
1305 #endif | |
1306 | |
1307 | |
1308 class DicomInstance : public boost::noncopyable | |
1309 { | |
1310 private: | |
1311 bool toFree_; | |
1312 | |
1313 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) | |
1314 const OrthancPluginDicomInstance* instance_; | |
1315 #else | |
1316 OrthancPluginDicomInstance* instance_; | |
1317 #endif | |
1318 | |
1319 public: | |
1320 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) | |
167 | 1321 explicit DicomInstance(const OrthancPluginDicomInstance* instance); |
152 | 1322 #else |
167 | 1323 explicit DicomInstance(OrthancPluginDicomInstance* instance); |
152 | 1324 #endif |
1325 | |
1326 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1327 DicomInstance(const void* buffer, | |
1328 size_t size); | |
1329 #endif | |
1330 | |
1331 ~DicomInstance(); | |
1332 | |
425 | 1333 const OrthancPluginDicomInstance* GetObject() const |
1334 { | |
1335 return instance_; | |
1336 } | |
1337 | |
152 | 1338 std::string GetRemoteAet() const; |
1339 | |
1340 const void* GetBuffer() const | |
1341 { | |
1342 return OrthancPluginGetInstanceData(GetGlobalContext(), instance_); | |
1343 } | |
1344 | |
1345 size_t GetSize() const | |
1346 { | |
1347 return static_cast<size_t>(OrthancPluginGetInstanceSize(GetGlobalContext(), instance_)); | |
1348 } | |
1349 | |
1350 void GetJson(Json::Value& target) const; | |
1351 | |
1352 void GetSimplifiedJson(Json::Value& target) const; | |
1353 | |
1354 OrthancPluginInstanceOrigin GetOrigin() const | |
1355 { | |
1356 return OrthancPluginGetInstanceOrigin(GetGlobalContext(), instance_); | |
1357 } | |
1358 | |
1359 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) | |
1360 std::string GetTransferSyntaxUid() const; | |
1361 #endif | |
1362 | |
1363 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) | |
1364 bool HasPixelData() const; | |
1365 #endif | |
1366 | |
1367 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1368 unsigned int GetFramesCount() const | |
1369 { | |
1370 return OrthancPluginGetInstanceFramesCount(GetGlobalContext(), instance_); | |
1371 } | |
1372 #endif | |
1373 | |
1374 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1375 void GetRawFrame(std::string& target, | |
1376 unsigned int frameIndex) const; | |
1377 #endif | |
1378 | |
1379 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1380 OrthancImage* GetDecodedFrame(unsigned int frameIndex) const; | |
1381 #endif | |
1382 | |
1383 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1384 void Serialize(std::string& target) const; | |
1385 #endif | |
1386 | |
1387 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) | |
1388 static DicomInstance* Transcode(const void* buffer, | |
1389 size_t size, | |
1390 const std::string& transferSyntax); | |
1391 #endif | |
425 | 1392 |
1393 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 1) | |
1394 static DicomInstance* Load(const std::string& instanceId, | |
1395 OrthancPluginLoadDicomInstanceMode mode); | |
1396 #endif | |
152 | 1397 }; |
397 | 1398 |
1399 // helper method to convert Http headers from the plugin SDK to a std::map | |
1400 void GetHttpHeaders(std::map<std::string, std::string>& result, const OrthancPluginHttpRequest* request); | |
1401 | |
1402 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
1403 class IWebDavCollection : public boost::noncopyable | |
1404 { | |
1405 public: | |
1406 class FileInfo | |
1407 { | |
1408 private: | |
1409 std::string name_; | |
1410 uint64_t contentSize_; | |
1411 std::string mime_; | |
1412 std::string dateTime_; | |
1413 | |
1414 public: | |
1415 FileInfo(const std::string& name, | |
1416 uint64_t contentSize, | |
1417 const std::string& dateTime) : | |
1418 name_(name), | |
1419 contentSize_(contentSize), | |
1420 dateTime_(dateTime) | |
1421 { | |
1422 } | |
1423 | |
1424 const std::string& GetName() const | |
1425 { | |
1426 return name_; | |
1427 } | |
1428 | |
1429 uint64_t GetContentSize() const | |
1430 { | |
1431 return contentSize_; | |
1432 } | |
1433 | |
1434 void SetMimeType(const std::string& mime) | |
1435 { | |
1436 mime_ = mime; | |
1437 } | |
1438 | |
1439 const std::string& GetMimeType() const | |
1440 { | |
1441 return mime_; | |
1442 } | |
1443 | |
1444 const std::string& GetDateTime() const | |
1445 { | |
1446 return dateTime_; | |
1447 } | |
1448 }; | |
1449 | |
1450 class FolderInfo | |
1451 { | |
1452 private: | |
1453 std::string name_; | |
1454 std::string dateTime_; | |
1455 | |
1456 public: | |
1457 FolderInfo(const std::string& name, | |
1458 const std::string& dateTime) : | |
1459 name_(name), | |
1460 dateTime_(dateTime) | |
1461 { | |
1462 } | |
1463 | |
1464 const std::string& GetName() const | |
1465 { | |
1466 return name_; | |
1467 } | |
1468 | |
1469 const std::string& GetDateTime() const | |
1470 { | |
1471 return dateTime_; | |
1472 } | |
1473 }; | |
1474 | |
1475 virtual ~IWebDavCollection() | |
1476 { | |
1477 } | |
1478 | |
1479 virtual bool IsExistingFolder(const std::vector<std::string>& path) = 0; | |
1480 | |
1481 virtual bool ListFolder(std::list<FileInfo>& files, | |
1482 std::list<FolderInfo>& subfolders, | |
1483 const std::vector<std::string>& path) = 0; | |
1484 | |
1485 virtual bool GetFile(std::string& content /* out */, | |
1486 std::string& mime /* out */, | |
1487 std::string& dateTime /* out */, | |
1488 const std::vector<std::string>& path) = 0; | |
1489 | |
1490 virtual bool StoreFile(const std::vector<std::string>& path, | |
1491 const void* data, | |
1492 size_t size) = 0; | |
1493 | |
1494 virtual bool CreateFolder(const std::vector<std::string>& path) = 0; | |
1495 | |
1496 virtual bool DeleteItem(const std::vector<std::string>& path) = 0; | |
1497 | |
1498 static void Register(const std::string& uri, | |
1499 IWebDavCollection& collection); | |
1500 }; | |
1501 #endif | |
491 | 1502 |
1503 void SetRootUri(const std::string& pluginIdentifier, | |
1504 const std::string& uri); | |
1505 | |
1506 void SetDescription(const std::string& pluginIdentifier, | |
1507 const std::string& description); | |
1508 | |
1509 void ExtendOrthancExplorer(const std::string& pluginIdentifier, | |
1510 const std::string& javascript); | |
152 | 1511 } |