Mercurial > hg > orthanc
comparison Plugins/Samples/Common/OrthancPluginCppWrapper.cpp @ 3026:c358bdb37c13
more plugin helpers
author | amazy |
---|---|
date | Tue, 18 Dec 2018 12:07:52 +0100 |
parents | 9cc3d40e389b |
children | ff65c925f57a |
comparison
equal
deleted
inserted
replaced
3023:c9c2faf76bec | 3026:c358bdb37c13 |
---|---|
37 #include <json/writer.h> | 37 #include <json/writer.h> |
38 | 38 |
39 | 39 |
40 namespace OrthancPlugins | 40 namespace OrthancPlugins |
41 { | 41 { |
42 static OrthancPluginContext* globalContext_ = NULL; | 42 static OrthancPluginContext* globalContext_ = NULL; |
43 | 43 |
44 | 44 |
45 void SetGlobalContext(OrthancPluginContext* context) | 45 void SetGlobalContext(OrthancPluginContext* context) |
46 { | 46 { |
47 if (context == NULL) | 47 if (context == NULL) |
48 { | |
49 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); | |
50 } | |
51 else if (globalContext_ == NULL) | |
52 { | |
53 globalContext_ = context; | |
54 } | |
55 else | |
56 { | |
57 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | |
58 } | |
59 } | |
60 | |
61 | |
62 bool HasGlobalContext() | |
63 { | |
64 return globalContext_ != NULL; | |
65 } | |
66 | |
67 | |
68 OrthancPluginContext* GetGlobalContext() | |
69 { | |
70 if (globalContext_ == NULL) | |
71 { | |
72 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | |
73 } | |
74 else | |
75 { | |
76 return globalContext_; | |
77 } | |
78 } | |
79 | |
80 | |
81 void MemoryBuffer::Check(OrthancPluginErrorCode code) | |
82 { | |
83 if (code != OrthancPluginErrorCode_Success) | |
84 { | |
85 // Prevent using garbage information | |
86 buffer_.data = NULL; | |
87 buffer_.size = 0; | |
88 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | |
89 } | |
90 } | |
91 | |
92 | |
93 bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code) | |
94 { | |
95 if (code != OrthancPluginErrorCode_Success) | |
96 { | |
97 // Prevent using garbage information | |
98 buffer_.data = NULL; | |
99 buffer_.size = 0; | |
100 } | |
101 | |
102 if (code == OrthancPluginErrorCode_Success) | |
103 { | |
104 return true; | |
105 } | |
106 else if (code == OrthancPluginErrorCode_UnknownResource || | |
107 code == OrthancPluginErrorCode_InexistentItem) | |
108 { | |
109 return false; | |
110 } | |
111 else | |
112 { | |
113 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | |
114 } | |
115 } | |
116 | |
117 | |
118 MemoryBuffer::MemoryBuffer() | |
119 { | |
120 buffer_.data = NULL; | |
121 buffer_.size = 0; | |
122 } | |
123 | |
124 | |
125 void MemoryBuffer::Clear() | |
126 { | |
127 if (buffer_.data != NULL) | |
128 { | |
129 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_); | |
130 buffer_.data = NULL; | |
131 buffer_.size = 0; | |
132 } | |
133 } | |
134 | |
135 | |
136 void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other) | |
137 { | |
138 Clear(); | |
139 | |
140 buffer_.data = other.data; | |
141 buffer_.size = other.size; | |
142 | |
143 other.data = NULL; | |
144 other.size = 0; | |
145 } | |
146 | |
147 | |
148 OrthancPluginMemoryBuffer MemoryBuffer::Release() | |
149 { | |
150 OrthancPluginMemoryBuffer result = buffer_; | |
151 | |
152 buffer_.data = NULL; | |
153 buffer_.size = 0; | |
154 | |
155 return result; | |
156 } | |
157 | |
158 | |
159 void MemoryBuffer::ToString(std::string& target) const | |
160 { | |
161 if (buffer_.size == 0) | |
162 { | |
163 target.clear(); | |
164 } | |
165 else | |
166 { | |
167 target.assign(reinterpret_cast<const char*>(buffer_.data), buffer_.size); | |
168 } | |
169 } | |
170 | |
171 | |
172 void MemoryBuffer::ToJson(Json::Value& target) const | |
173 { | |
174 if (buffer_.data == NULL || | |
175 buffer_.size == 0) | |
176 { | |
177 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
178 } | |
179 | |
180 const char* tmp = reinterpret_cast<const char*>(buffer_.data); | |
181 | |
182 Json::Reader reader; | |
183 if (!reader.parse(tmp, tmp + buffer_.size, target)) | |
184 { | |
185 LogError("Cannot convert some memory buffer to JSON"); | |
186 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
187 } | |
188 } | |
189 | |
190 | |
191 bool MemoryBuffer::RestApiGet(const std::string& uri, | |
192 bool applyPlugins) | |
193 { | |
194 Clear(); | |
195 | |
196 if (applyPlugins) | |
197 { | |
198 return CheckHttp(OrthancPluginRestApiGetAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str())); | |
199 } | |
200 else | |
201 { | |
202 return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); | |
203 } | |
204 } | |
205 | |
206 bool MemoryBuffer::RestApiGet(const std::string& uri, | |
207 const std::map<std::string, std::string>& httpHeaders, | |
208 bool applyPlugins) | |
209 { | |
210 Clear(); | |
211 | |
212 std::vector<const char*> headersKeys; | |
213 std::vector<const char*> headersValues; | |
214 for (std::map<std::string, std::string>::const_iterator it = httpHeaders.begin(); it != httpHeaders.end(); it++) | |
215 { | |
216 headersKeys.push_back(it->first.c_str()); | |
217 headersValues.push_back(it->second.c_str()); | |
218 } | |
219 | |
220 return CheckHttp(OrthancPluginRestApiGet2(GetGlobalContext(), &buffer_, uri.c_str(), httpHeaders.size(), headersKeys.data(), headersValues.data(), applyPlugins)); | |
221 } | |
222 | |
223 bool MemoryBuffer::RestApiPost(const std::string& uri, | |
224 const char* body, | |
225 size_t bodySize, | |
226 bool applyPlugins) | |
227 { | |
228 Clear(); | |
229 | |
230 if (applyPlugins) | |
231 { | |
232 return CheckHttp(OrthancPluginRestApiPostAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | |
233 } | |
234 else | |
235 { | |
236 return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | |
237 } | |
238 } | |
239 | |
240 | |
241 bool MemoryBuffer::RestApiPut(const std::string& uri, | |
242 const char* body, | |
243 size_t bodySize, | |
244 bool applyPlugins) | |
245 { | |
246 Clear(); | |
247 | |
248 if (applyPlugins) | |
249 { | |
250 return CheckHttp(OrthancPluginRestApiPutAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | |
251 } | |
252 else | |
253 { | |
254 return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | |
255 } | |
256 } | |
257 | |
258 | |
259 bool MemoryBuffer::RestApiPost(const std::string& uri, | |
260 const Json::Value& body, | |
261 bool applyPlugins) | |
262 { | |
263 Json::FastWriter writer; | |
264 return RestApiPost(uri, writer.write(body), applyPlugins); | |
265 } | |
266 | |
267 | |
268 bool MemoryBuffer::RestApiPut(const std::string& uri, | |
269 const Json::Value& body, | |
270 bool applyPlugins) | |
271 { | |
272 Json::FastWriter writer; | |
273 return RestApiPut(uri, writer.write(body), applyPlugins); | |
274 } | |
275 | |
276 | |
277 void MemoryBuffer::CreateDicom(const Json::Value& tags, | |
278 OrthancPluginCreateDicomFlags flags) | |
279 { | |
280 Clear(); | |
281 | |
282 Json::FastWriter writer; | |
283 std::string s = writer.write(tags); | |
284 | |
285 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); | |
286 } | |
287 | |
288 void MemoryBuffer::CreateDicom(const Json::Value& tags, | |
289 const OrthancImage& pixelData, | |
290 OrthancPluginCreateDicomFlags flags) | |
291 { | |
292 Clear(); | |
293 | |
294 Json::FastWriter writer; | |
295 std::string s = writer.write(tags); | |
296 | |
297 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags)); | |
298 } | |
299 | |
300 | |
301 void MemoryBuffer::ReadFile(const std::string& path) | |
302 { | |
303 Clear(); | |
304 Check(OrthancPluginReadFile(GetGlobalContext(), &buffer_, path.c_str())); | |
305 } | |
306 | |
307 | |
308 void MemoryBuffer::GetDicomQuery(const OrthancPluginWorklistQuery* query) | |
309 { | |
310 Clear(); | |
311 Check(OrthancPluginWorklistGetDicomQuery(GetGlobalContext(), &buffer_, query)); | |
312 } | |
313 | |
314 | |
315 void OrthancString::Assign(char* str) | |
316 { | |
317 if (str == NULL) | |
318 { | |
319 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
320 } | |
321 else | |
322 { | |
323 Clear(); | |
324 str_ = str; | |
325 } | |
326 } | |
327 | |
328 | |
329 void OrthancString::Clear() | |
330 { | |
331 if (str_ != NULL) | |
332 { | |
333 OrthancPluginFreeString(GetGlobalContext(), str_); | |
334 str_ = NULL; | |
335 } | |
336 } | |
337 | |
338 | |
339 void OrthancString::ToString(std::string& target) const | |
340 { | |
341 if (str_ == NULL) | |
342 { | |
343 target.clear(); | |
344 } | |
345 else | |
346 { | |
347 target.assign(str_); | |
348 } | |
349 } | |
350 | |
351 | |
352 void OrthancString::ToJson(Json::Value& target) const | |
353 { | |
354 if (str_ == NULL) | |
355 { | |
356 LogError("Cannot convert an empty memory buffer to JSON"); | |
357 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
358 } | |
359 | |
360 Json::Reader reader; | |
361 if (!reader.parse(str_, target)) | |
362 { | |
363 LogError("Cannot convert some memory buffer to JSON"); | |
364 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
365 } | |
366 } | |
367 | |
368 | |
369 void MemoryBuffer::DicomToJson(Json::Value& target, | |
370 OrthancPluginDicomToJsonFormat format, | |
371 OrthancPluginDicomToJsonFlags flags, | |
372 uint32_t maxStringLength) | |
373 { | |
374 OrthancString str; | |
375 str.Assign(OrthancPluginDicomBufferToJson | |
376 (GetGlobalContext(), GetData(), GetSize(), format, flags, maxStringLength)); | |
377 str.ToJson(target); | |
378 } | |
379 | |
380 | |
381 bool MemoryBuffer::HttpGet(const std::string& url, | |
382 const std::string& username, | |
383 const std::string& password) | |
384 { | |
385 Clear(); | |
386 return CheckHttp(OrthancPluginHttpGet(GetGlobalContext(), &buffer_, url.c_str(), | |
387 username.empty() ? NULL : username.c_str(), | |
388 password.empty() ? NULL : password.c_str())); | |
389 } | |
390 | |
391 | |
392 bool MemoryBuffer::HttpPost(const std::string& url, | |
393 const std::string& body, | |
394 const std::string& username, | |
395 const std::string& password) | |
396 { | |
397 Clear(); | |
398 return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), | |
399 body.c_str(), body.size(), | |
400 username.empty() ? NULL : username.c_str(), | |
401 password.empty() ? NULL : password.c_str())); | |
402 } | |
403 | |
404 | |
405 bool MemoryBuffer::HttpPut(const std::string& url, | |
406 const std::string& body, | |
407 const std::string& username, | |
408 const std::string& password) | |
409 { | |
410 Clear(); | |
411 return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), | |
412 body.empty() ? NULL : body.c_str(), | |
413 body.size(), | |
414 username.empty() ? NULL : username.c_str(), | |
415 password.empty() ? NULL : password.c_str())); | |
416 } | |
417 | |
418 | |
419 void MemoryBuffer::GetDicomInstance(const std::string& instanceId) | |
420 { | |
421 Clear(); | |
422 Check(OrthancPluginGetDicomForInstance(GetGlobalContext(), &buffer_, instanceId.c_str())); | |
423 } | |
424 | |
425 | |
426 bool HttpDelete(const std::string& url, | |
427 const std::string& username, | |
428 const std::string& password) | |
429 { | |
430 OrthancPluginErrorCode error = OrthancPluginHttpDelete | |
431 (GetGlobalContext(), url.c_str(), | |
432 username.empty() ? NULL : username.c_str(), | |
433 password.empty() ? NULL : password.c_str()); | |
434 | |
435 if (error == OrthancPluginErrorCode_Success) | |
436 { | |
437 return true; | |
438 } | |
439 else if (error == OrthancPluginErrorCode_UnknownResource || | |
440 error == OrthancPluginErrorCode_InexistentItem) | |
441 { | |
442 return false; | |
443 } | |
444 else | |
445 { | |
446 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); | |
447 } | |
448 } | |
449 | |
450 | |
451 void LogError(const std::string& message) | |
452 { | |
453 if (HasGlobalContext()) | |
454 { | |
455 OrthancPluginLogError(GetGlobalContext(), message.c_str()); | |
456 } | |
457 } | |
458 | |
459 | |
460 void LogWarning(const std::string& message) | |
461 { | |
462 if (HasGlobalContext()) | |
463 { | |
464 OrthancPluginLogWarning(GetGlobalContext(), message.c_str()); | |
465 } | |
466 } | |
467 | |
468 | |
469 void LogInfo(const std::string& message) | |
470 { | |
471 if (HasGlobalContext()) | |
472 { | |
473 OrthancPluginLogInfo(GetGlobalContext(), message.c_str()); | |
474 } | |
475 } | |
476 | |
477 | |
478 OrthancConfiguration::OrthancConfiguration() | |
479 { | |
480 OrthancString str; | |
481 str.Assign(OrthancPluginGetConfiguration(GetGlobalContext())); | |
482 | |
483 if (str.GetContent() == NULL) | |
484 { | |
485 LogError("Cannot access the Orthanc configuration"); | |
486 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
487 } | |
488 | |
489 str.ToJson(configuration_); | |
490 | |
491 if (configuration_.type() != Json::objectValue) | |
492 { | |
493 LogError("Unable to read the Orthanc configuration"); | |
494 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
495 } | |
496 } | |
497 | |
498 | |
499 std::string OrthancConfiguration::GetPath(const std::string& key) const | |
500 { | |
501 if (path_.empty()) | |
502 { | |
503 return key; | |
504 } | |
505 else | |
506 { | |
507 return path_ + "." + key; | |
508 } | |
509 } | |
510 | |
511 | |
512 bool OrthancConfiguration::IsSection(const std::string& key) const | |
513 { | |
514 assert(configuration_.type() == Json::objectValue); | |
515 | |
516 return (configuration_.isMember(key) && | |
517 configuration_[key].type() == Json::objectValue); | |
518 } | |
519 | |
520 | |
521 void OrthancConfiguration::GetSection(OrthancConfiguration& target, | |
522 const std::string& key) const | |
523 { | |
524 assert(configuration_.type() == Json::objectValue); | |
525 | |
526 target.path_ = GetPath(key); | |
527 | |
528 if (!configuration_.isMember(key)) | |
529 { | |
530 target.configuration_ = Json::objectValue; | |
531 } | |
532 else | |
533 { | |
534 if (configuration_[key].type() != Json::objectValue) | |
48 { | 535 { |
49 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); | 536 LogError("The configuration section \"" + target.path_ + |
50 } | 537 "\" is not an associative array as expected"); |
51 else if (globalContext_ == NULL) | 538 |
539 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
540 } | |
541 | |
542 target.configuration_ = configuration_[key]; | |
543 } | |
544 } | |
545 | |
546 | |
547 bool OrthancConfiguration::LookupStringValue(std::string& target, | |
548 const std::string& key) const | |
549 { | |
550 assert(configuration_.type() == Json::objectValue); | |
551 | |
552 if (!configuration_.isMember(key)) | |
553 { | |
554 return false; | |
555 } | |
556 | |
557 if (configuration_[key].type() != Json::stringValue) | |
558 { | |
559 LogError("The configuration option \"" + GetPath(key) + | |
560 "\" is not a string as expected"); | |
561 | |
562 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
563 } | |
564 | |
565 target = configuration_[key].asString(); | |
566 return true; | |
567 } | |
568 | |
569 | |
570 bool OrthancConfiguration::LookupIntegerValue(int& target, | |
571 const std::string& key) const | |
572 { | |
573 assert(configuration_.type() == Json::objectValue); | |
574 | |
575 if (!configuration_.isMember(key)) | |
576 { | |
577 return false; | |
578 } | |
579 | |
580 switch (configuration_[key].type()) | |
581 { | |
582 case Json::intValue: | |
583 target = configuration_[key].asInt(); | |
584 return true; | |
585 | |
586 case Json::uintValue: | |
587 target = configuration_[key].asUInt(); | |
588 return true; | |
589 | |
590 default: | |
591 LogError("The configuration option \"" + GetPath(key) + | |
592 "\" is not an integer as expected"); | |
593 | |
594 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
595 } | |
596 } | |
597 | |
598 | |
599 bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target, | |
600 const std::string& key) const | |
601 { | |
602 int tmp; | |
603 if (!LookupIntegerValue(tmp, key)) | |
604 { | |
605 return false; | |
606 } | |
607 | |
608 if (tmp < 0) | |
609 { | |
610 LogError("The configuration option \"" + GetPath(key) + | |
611 "\" is not a positive integer as expected"); | |
612 | |
613 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
614 } | |
615 else | |
616 { | |
617 target = static_cast<unsigned int>(tmp); | |
618 return true; | |
619 } | |
620 } | |
621 | |
622 | |
623 bool OrthancConfiguration::LookupBooleanValue(bool& target, | |
624 const std::string& key) const | |
625 { | |
626 assert(configuration_.type() == Json::objectValue); | |
627 | |
628 if (!configuration_.isMember(key)) | |
629 { | |
630 return false; | |
631 } | |
632 | |
633 if (configuration_[key].type() != Json::booleanValue) | |
634 { | |
635 LogError("The configuration option \"" + GetPath(key) + | |
636 "\" is not a Boolean as expected"); | |
637 | |
638 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
639 } | |
640 | |
641 target = configuration_[key].asBool(); | |
642 return true; | |
643 } | |
644 | |
645 | |
646 bool OrthancConfiguration::LookupFloatValue(float& target, | |
647 const std::string& key) const | |
648 { | |
649 assert(configuration_.type() == Json::objectValue); | |
650 | |
651 if (!configuration_.isMember(key)) | |
652 { | |
653 return false; | |
654 } | |
655 | |
656 switch (configuration_[key].type()) | |
657 { | |
658 case Json::realValue: | |
659 target = configuration_[key].asFloat(); | |
660 return true; | |
661 | |
662 case Json::intValue: | |
663 target = static_cast<float>(configuration_[key].asInt()); | |
664 return true; | |
665 | |
666 case Json::uintValue: | |
667 target = static_cast<float>(configuration_[key].asUInt()); | |
668 return true; | |
669 | |
670 default: | |
671 LogError("The configuration option \"" + GetPath(key) + | |
672 "\" is not an integer as expected"); | |
673 | |
674 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
675 } | |
676 } | |
677 | |
678 | |
679 bool OrthancConfiguration::LookupListOfStrings(std::list<std::string>& target, | |
680 const std::string& key, | |
681 bool allowSingleString) const | |
682 { | |
683 assert(configuration_.type() == Json::objectValue); | |
684 | |
685 target.clear(); | |
686 | |
687 if (!configuration_.isMember(key)) | |
688 { | |
689 return false; | |
690 } | |
691 | |
692 switch (configuration_[key].type()) | |
693 { | |
694 case Json::arrayValue: | |
695 { | |
696 bool ok = true; | |
697 | |
698 for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++) | |
52 { | 699 { |
53 globalContext_ = context; | 700 if (configuration_[key][i].type() == Json::stringValue) |
701 { | |
702 target.push_back(configuration_[key][i].asString()); | |
703 } | |
704 else | |
705 { | |
706 ok = false; | |
707 } | |
708 } | |
709 | |
710 if (ok) | |
711 { | |
712 return true; | |
713 } | |
714 | |
715 break; | |
716 } | |
717 | |
718 case Json::stringValue: | |
719 if (allowSingleString) | |
720 { | |
721 target.push_back(configuration_[key].asString()); | |
722 return true; | |
723 } | |
724 | |
725 break; | |
726 | |
727 default: | |
728 break; | |
729 } | |
730 | |
731 LogError("The configuration option \"" + GetPath(key) + | |
732 "\" is not a list of strings as expected"); | |
733 | |
734 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
735 } | |
736 | |
737 | |
738 bool OrthancConfiguration::LookupSetOfStrings(std::set<std::string>& target, | |
739 const std::string& key, | |
740 bool allowSingleString) const | |
741 { | |
742 std::list<std::string> lst; | |
743 | |
744 if (LookupListOfStrings(lst, key, allowSingleString)) | |
745 { | |
746 target.clear(); | |
747 | |
748 for (std::list<std::string>::const_iterator | |
749 it = lst.begin(); it != lst.end(); ++it) | |
750 { | |
751 target.insert(*it); | |
752 } | |
753 | |
754 return true; | |
755 } | |
756 else | |
757 { | |
758 return false; | |
759 } | |
760 } | |
761 | |
762 | |
763 std::string OrthancConfiguration::GetStringValue(const std::string& key, | |
764 const std::string& defaultValue) const | |
765 { | |
766 std::string tmp; | |
767 if (LookupStringValue(tmp, key)) | |
768 { | |
769 return tmp; | |
770 } | |
771 else | |
772 { | |
773 return defaultValue; | |
774 } | |
775 } | |
776 | |
777 | |
778 int OrthancConfiguration::GetIntegerValue(const std::string& key, | |
779 int defaultValue) const | |
780 { | |
781 int tmp; | |
782 if (LookupIntegerValue(tmp, key)) | |
783 { | |
784 return tmp; | |
785 } | |
786 else | |
787 { | |
788 return defaultValue; | |
789 } | |
790 } | |
791 | |
792 | |
793 unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key, | |
794 unsigned int defaultValue) const | |
795 { | |
796 unsigned int tmp; | |
797 if (LookupUnsignedIntegerValue(tmp, key)) | |
798 { | |
799 return tmp; | |
800 } | |
801 else | |
802 { | |
803 return defaultValue; | |
804 } | |
805 } | |
806 | |
807 | |
808 bool OrthancConfiguration::GetBooleanValue(const std::string& key, | |
809 bool defaultValue) const | |
810 { | |
811 bool tmp; | |
812 if (LookupBooleanValue(tmp, key)) | |
813 { | |
814 return tmp; | |
815 } | |
816 else | |
817 { | |
818 return defaultValue; | |
819 } | |
820 } | |
821 | |
822 | |
823 float OrthancConfiguration::GetFloatValue(const std::string& key, | |
824 float defaultValue) const | |
825 { | |
826 float tmp; | |
827 if (LookupFloatValue(tmp, key)) | |
828 { | |
829 return tmp; | |
830 } | |
831 else | |
832 { | |
833 return defaultValue; | |
834 } | |
835 } | |
836 | |
837 | |
838 void OrthancConfiguration::GetDictionary(std::map<std::string, std::string>& target, | |
839 const std::string& key) const | |
840 { | |
841 assert(configuration_.type() == Json::objectValue); | |
842 | |
843 target.clear(); | |
844 | |
845 if (!configuration_.isMember(key)) | |
846 { | |
847 return; | |
848 } | |
849 | |
850 if (configuration_[key].type() != Json::objectValue) | |
851 { | |
852 LogError("The configuration option \"" + GetPath(key) + | |
853 "\" is not a string as expected"); | |
854 | |
855 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
856 } | |
857 | |
858 Json::Value::Members members = configuration_[key].getMemberNames(); | |
859 | |
860 for (size_t i = 0; i < members.size(); i++) | |
861 { | |
862 const Json::Value& value = configuration_[key][members[i]]; | |
863 | |
864 if (value.type() == Json::stringValue) | |
865 { | |
866 target[members[i]] = value.asString(); | |
54 } | 867 } |
55 else | 868 else |
56 { | 869 { |
57 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | 870 LogError("The configuration option \"" + GetPath(key) + |
871 "\" is not a dictionary mapping strings to strings"); | |
872 | |
873 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
58 } | 874 } |
59 } | 875 } |
60 | 876 } |
61 | 877 |
62 bool HasGlobalContext() | 878 |
63 { | 879 void OrthancImage::Clear() |
64 return globalContext_ != NULL; | 880 { |
65 } | 881 if (image_ != NULL) |
66 | 882 { |
67 | 883 OrthancPluginFreeImage(GetGlobalContext(), image_); |
68 OrthancPluginContext* GetGlobalContext() | 884 image_ = NULL; |
69 { | 885 } |
70 if (globalContext_ == NULL) | 886 } |
887 | |
888 | |
889 void OrthancImage::CheckImageAvailable() | |
890 { | |
891 if (image_ == NULL) | |
892 { | |
893 LogError("Trying to access a NULL image"); | |
894 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
895 } | |
896 } | |
897 | |
898 | |
899 OrthancImage::OrthancImage() : | |
900 image_(NULL) | |
901 { | |
902 } | |
903 | |
904 | |
905 OrthancImage::OrthancImage(OrthancPluginImage* image) : | |
906 image_(image) | |
907 { | |
908 } | |
909 | |
910 | |
911 OrthancImage::OrthancImage(OrthancPluginPixelFormat format, | |
912 uint32_t width, | |
913 uint32_t height) | |
914 { | |
915 image_ = OrthancPluginCreateImage(GetGlobalContext(), format, width, height); | |
916 | |
917 if (image_ == NULL) | |
918 { | |
919 LogError("Cannot create an image"); | |
920 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
921 } | |
922 } | |
923 | |
924 | |
925 OrthancImage::OrthancImage(OrthancPluginPixelFormat format, | |
926 uint32_t width, | |
927 uint32_t height, | |
928 uint32_t pitch, | |
929 void* buffer) | |
930 { | |
931 image_ = OrthancPluginCreateImageAccessor | |
932 (GetGlobalContext(), format, width, height, pitch, buffer); | |
933 | |
934 if (image_ == NULL) | |
935 { | |
936 LogError("Cannot create an image accessor"); | |
937 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
938 } | |
939 } | |
940 | |
941 void OrthancImage::UncompressPngImage(const void* data, | |
942 size_t size) | |
943 { | |
944 Clear(); | |
945 | |
946 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Png); | |
947 | |
948 if (image_ == NULL) | |
949 { | |
950 LogError("Cannot uncompress a PNG image"); | |
951 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
952 } | |
953 } | |
954 | |
955 | |
956 void OrthancImage::UncompressJpegImage(const void* data, | |
957 size_t size) | |
958 { | |
959 Clear(); | |
960 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Jpeg); | |
961 if (image_ == NULL) | |
962 { | |
963 LogError("Cannot uncompress a JPEG image"); | |
964 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
965 } | |
966 } | |
967 | |
968 | |
969 void OrthancImage::DecodeDicomImage(const void* data, | |
970 size_t size, | |
971 unsigned int frame) | |
972 { | |
973 Clear(); | |
974 image_ = OrthancPluginDecodeDicomImage(GetGlobalContext(), data, size, frame); | |
975 if (image_ == NULL) | |
976 { | |
977 LogError("Cannot uncompress a DICOM image"); | |
978 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
979 } | |
980 } | |
981 | |
982 | |
983 OrthancPluginPixelFormat OrthancImage::GetPixelFormat() | |
984 { | |
985 CheckImageAvailable(); | |
986 return OrthancPluginGetImagePixelFormat(GetGlobalContext(), image_); | |
987 } | |
988 | |
989 | |
990 unsigned int OrthancImage::GetWidth() | |
991 { | |
992 CheckImageAvailable(); | |
993 return OrthancPluginGetImageWidth(GetGlobalContext(), image_); | |
994 } | |
995 | |
996 | |
997 unsigned int OrthancImage::GetHeight() | |
998 { | |
999 CheckImageAvailable(); | |
1000 return OrthancPluginGetImageHeight(GetGlobalContext(), image_); | |
1001 } | |
1002 | |
1003 | |
1004 unsigned int OrthancImage::GetPitch() | |
1005 { | |
1006 CheckImageAvailable(); | |
1007 return OrthancPluginGetImagePitch(GetGlobalContext(), image_); | |
1008 } | |
1009 | |
1010 | |
1011 const void* OrthancImage::GetBuffer() | |
1012 { | |
1013 CheckImageAvailable(); | |
1014 return OrthancPluginGetImageBuffer(GetGlobalContext(), image_); | |
1015 } | |
1016 | |
1017 | |
1018 void OrthancImage::CompressPngImage(MemoryBuffer& target) | |
1019 { | |
1020 CheckImageAvailable(); | |
1021 | |
1022 OrthancPluginMemoryBuffer tmp; | |
1023 OrthancPluginCompressPngImage(GetGlobalContext(), &tmp, GetPixelFormat(), | |
1024 GetWidth(), GetHeight(), GetPitch(), GetBuffer()); | |
1025 | |
1026 target.Assign(tmp); | |
1027 } | |
1028 | |
1029 | |
1030 void OrthancImage::CompressJpegImage(MemoryBuffer& target, | |
1031 uint8_t quality) | |
1032 { | |
1033 CheckImageAvailable(); | |
1034 | |
1035 OrthancPluginMemoryBuffer tmp; | |
1036 OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(), | |
1037 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); | |
1038 | |
1039 target.Assign(tmp); | |
1040 } | |
1041 | |
1042 | |
1043 void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output) | |
1044 { | |
1045 CheckImageAvailable(); | |
1046 OrthancPluginCompressAndAnswerPngImage(GetGlobalContext(), output, GetPixelFormat(), | |
1047 GetWidth(), GetHeight(), GetPitch(), GetBuffer()); | |
1048 } | |
1049 | |
1050 | |
1051 void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output, | |
1052 uint8_t quality) | |
1053 { | |
1054 CheckImageAvailable(); | |
1055 OrthancPluginCompressAndAnswerJpegImage(GetGlobalContext(), output, GetPixelFormat(), | |
1056 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); | |
1057 } | |
1058 | |
1059 | |
1060 | |
1061 #if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 | |
1062 FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) : | |
1063 matcher_(NULL), | |
1064 worklist_(worklist) | |
1065 { | |
1066 if (worklist_ == NULL) | |
1067 { | |
1068 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
1069 } | |
1070 } | |
1071 | |
1072 | |
1073 void FindMatcher::SetupDicom(const void* query, | |
1074 uint32_t size) | |
1075 { | |
1076 worklist_ = NULL; | |
1077 | |
1078 matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size); | |
1079 if (matcher_ == NULL) | |
1080 { | |
1081 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1082 } | |
1083 } | |
1084 | |
1085 | |
1086 FindMatcher::~FindMatcher() | |
1087 { | |
1088 // The "worklist_" field | |
1089 | |
1090 if (matcher_ != NULL) | |
1091 { | |
1092 OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_); | |
1093 } | |
1094 } | |
1095 | |
1096 | |
1097 | |
1098 bool FindMatcher::IsMatch(const void* dicom, | |
1099 uint32_t size) const | |
1100 { | |
1101 int32_t result; | |
1102 | |
1103 if (matcher_ != NULL) | |
1104 { | |
1105 result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size); | |
1106 } | |
1107 else if (worklist_ != NULL) | |
1108 { | |
1109 result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size); | |
1110 } | |
1111 else | |
1112 { | |
1113 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1114 } | |
1115 | |
1116 if (result == 0) | |
1117 { | |
1118 return false; | |
1119 } | |
1120 else if (result == 1) | |
1121 { | |
1122 return true; | |
1123 } | |
1124 else | |
1125 { | |
1126 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1127 } | |
1128 } | |
1129 | |
1130 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ | |
1131 | |
1132 void AnswerJson(const Json::Value& value, | |
1133 OrthancPluginRestOutput* output | |
1134 ) | |
1135 { | |
1136 Json::StyledWriter writer; | |
1137 std::string bodyString = writer.write(value); | |
1138 | |
1139 OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); | |
1140 } | |
1141 | |
1142 void AnswerString(const std::string& answer, | |
1143 const char* mimeType, | |
1144 OrthancPluginRestOutput* output | |
1145 ) | |
1146 { | |
1147 OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType); | |
1148 } | |
1149 | |
1150 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) | |
1151 { | |
1152 OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError); | |
1153 } | |
1154 | |
1155 void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods) | |
1156 { | |
1157 OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods); | |
1158 } | |
1159 | |
1160 bool RestApiGetString(std::string& result, | |
1161 const std::string& uri, | |
1162 bool applyPlugins) | |
1163 { | |
1164 MemoryBuffer answer; | |
1165 if (!answer.RestApiGet(uri, applyPlugins)) | |
1166 { | |
1167 return false; | |
1168 } | |
1169 else | |
1170 { | |
1171 answer.ToString(result); | |
1172 return true; | |
1173 } | |
1174 } | |
1175 | |
1176 bool RestApiGetString(std::string& result, | |
1177 const std::string& uri, | |
1178 const std::map<std::string, std::string>& httpHeaders, | |
1179 bool applyPlugins) | |
1180 { | |
1181 MemoryBuffer answer; | |
1182 if (!answer.RestApiGet(uri, httpHeaders, applyPlugins)) | |
1183 { | |
1184 return false; | |
1185 } | |
1186 else | |
1187 { | |
1188 answer.ToString(result); | |
1189 return true; | |
1190 } | |
1191 } | |
1192 | |
1193 | |
1194 | |
1195 bool RestApiGet(Json::Value& result, | |
1196 const std::string& uri, | |
1197 bool applyPlugins) | |
1198 { | |
1199 MemoryBuffer answer; | |
1200 | |
1201 if (!answer.RestApiGet(uri, applyPlugins)) | |
1202 { | |
1203 return false; | |
1204 } | |
1205 else | |
1206 { | |
1207 if (!answer.IsEmpty()) | |
71 { | 1208 { |
72 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | 1209 answer.ToJson(result); |
1210 } | |
1211 return true; | |
1212 } | |
1213 } | |
1214 | |
1215 | |
1216 bool RestApiPost(Json::Value& result, | |
1217 const std::string& uri, | |
1218 const char* body, | |
1219 size_t bodySize, | |
1220 bool applyPlugins) | |
1221 { | |
1222 MemoryBuffer answer; | |
1223 | |
1224 if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) | |
1225 { | |
1226 return false; | |
1227 } | |
1228 else | |
1229 { | |
1230 if (!answer.IsEmpty()) | |
1231 { | |
1232 answer.ToJson(result); | |
1233 } | |
1234 return true; | |
1235 } | |
1236 } | |
1237 | |
1238 | |
1239 bool RestApiPost(Json::Value& result, | |
1240 const std::string& uri, | |
1241 const Json::Value& body, | |
1242 bool applyPlugins) | |
1243 { | |
1244 Json::FastWriter writer; | |
1245 return RestApiPost(result, uri, writer.write(body), applyPlugins); | |
1246 } | |
1247 | |
1248 | |
1249 bool RestApiPut(Json::Value& result, | |
1250 const std::string& uri, | |
1251 const char* body, | |
1252 size_t bodySize, | |
1253 bool applyPlugins) | |
1254 { | |
1255 MemoryBuffer answer; | |
1256 | |
1257 if (!answer.RestApiPut(uri, body, bodySize, applyPlugins)) | |
1258 { | |
1259 return false; | |
1260 } | |
1261 else | |
1262 { | |
1263 if (!answer.IsEmpty()) // i.e, on a PUT to metadata/..., orthand returns an empty response | |
1264 { | |
1265 answer.ToJson(result); | |
1266 } | |
1267 return true; | |
1268 } | |
1269 } | |
1270 | |
1271 | |
1272 bool RestApiPut(Json::Value& result, | |
1273 const std::string& uri, | |
1274 const Json::Value& body, | |
1275 bool applyPlugins) | |
1276 { | |
1277 Json::FastWriter writer; | |
1278 return RestApiPut(result, uri, writer.write(body), applyPlugins); | |
1279 } | |
1280 | |
1281 | |
1282 bool RestApiDelete(const std::string& uri, | |
1283 bool applyPlugins) | |
1284 { | |
1285 OrthancPluginErrorCode error; | |
1286 | |
1287 if (applyPlugins) | |
1288 { | |
1289 error = OrthancPluginRestApiDeleteAfterPlugins(GetGlobalContext(), uri.c_str()); | |
1290 } | |
1291 else | |
1292 { | |
1293 error = OrthancPluginRestApiDelete(GetGlobalContext(), uri.c_str()); | |
1294 } | |
1295 | |
1296 if (error == OrthancPluginErrorCode_Success) | |
1297 { | |
1298 return true; | |
1299 } | |
1300 else if (error == OrthancPluginErrorCode_UnknownResource || | |
1301 error == OrthancPluginErrorCode_InexistentItem) | |
1302 { | |
1303 return false; | |
1304 } | |
1305 else | |
1306 { | |
1307 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); | |
1308 } | |
1309 } | |
1310 | |
1311 | |
1312 void ReportMinimalOrthancVersion(unsigned int major, | |
1313 unsigned int minor, | |
1314 unsigned int revision) | |
1315 { | |
1316 LogError("Your version of the Orthanc core (" + | |
1317 std::string(GetGlobalContext()->orthancVersion) + | |
1318 ") is too old to run this plugin (version " + | |
1319 boost::lexical_cast<std::string>(major) + "." + | |
1320 boost::lexical_cast<std::string>(minor) + "." + | |
1321 boost::lexical_cast<std::string>(revision) + | |
1322 " is required)"); | |
1323 } | |
1324 | |
1325 | |
1326 bool CheckMinimalOrthancVersion(unsigned int major, | |
1327 unsigned int minor, | |
1328 unsigned int revision) | |
1329 { | |
1330 if (!HasGlobalContext()) | |
1331 { | |
1332 LogError("Bad Orthanc context in the plugin"); | |
1333 return false; | |
1334 } | |
1335 | |
1336 if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) | |
1337 { | |
1338 // Assume compatibility with the mainline | |
1339 return true; | |
1340 } | |
1341 | |
1342 // Parse the version of the Orthanc core | |
1343 int aa, bb, cc; | |
1344 if ( | |
1345 #ifdef _MSC_VER | |
1346 sscanf_s | |
1347 #else | |
1348 sscanf | |
1349 #endif | |
1350 (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || | |
1351 aa < 0 || | |
1352 bb < 0 || | |
1353 cc < 0) | |
1354 { | |
1355 return false; | |
1356 } | |
1357 | |
1358 unsigned int a = static_cast<unsigned int>(aa); | |
1359 unsigned int b = static_cast<unsigned int>(bb); | |
1360 unsigned int c = static_cast<unsigned int>(cc); | |
1361 | |
1362 // Check the major version number | |
1363 | |
1364 if (a > major) | |
1365 { | |
1366 return true; | |
1367 } | |
1368 | |
1369 if (a < major) | |
1370 { | |
1371 return false; | |
1372 } | |
1373 | |
1374 | |
1375 // Check the minor version number | |
1376 assert(a == major); | |
1377 | |
1378 if (b > minor) | |
1379 { | |
1380 return true; | |
1381 } | |
1382 | |
1383 if (b < minor) | |
1384 { | |
1385 return false; | |
1386 } | |
1387 | |
1388 // Check the patch level version number | |
1389 assert(a == major && b == minor); | |
1390 | |
1391 if (c >= revision) | |
1392 { | |
1393 return true; | |
1394 } | |
1395 else | |
1396 { | |
1397 return false; | |
1398 } | |
1399 } | |
1400 | |
1401 | |
1402 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) | |
1403 const char* AutodetectMimeType(const std::string& path) | |
1404 { | |
1405 const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str()); | |
1406 | |
1407 if (mime == NULL) | |
1408 { | |
1409 // Should never happen, just for safety | |
1410 return "application/octet-stream"; | |
1411 } | |
1412 else | |
1413 { | |
1414 return mime; | |
1415 } | |
1416 } | |
1417 #endif | |
1418 | |
1419 | |
1420 #if HAS_ORTHANC_PLUGIN_PEERS == 1 | |
1421 size_t OrthancPeers::GetPeerIndex(const std::string& name) const | |
1422 { | |
1423 size_t index; | |
1424 if (LookupName(index, name)) | |
1425 { | |
1426 return index; | |
1427 } | |
1428 else | |
1429 { | |
1430 LogError("Inexistent peer: " + name); | |
1431 ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); | |
1432 } | |
1433 } | |
1434 | |
1435 | |
1436 OrthancPeers::OrthancPeers() : | |
1437 peers_(NULL), | |
1438 timeout_(0) | |
1439 { | |
1440 peers_ = OrthancPluginGetPeers(GetGlobalContext()); | |
1441 | |
1442 if (peers_ == NULL) | |
1443 { | |
1444 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1445 } | |
1446 | |
1447 uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_); | |
1448 | |
1449 for (uint32_t i = 0; i < count; i++) | |
1450 { | |
1451 const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i); | |
1452 if (name == NULL) | |
1453 { | |
1454 OrthancPluginFreePeers(GetGlobalContext(), peers_); | |
1455 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1456 } | |
1457 | |
1458 index_[name] = i; | |
1459 } | |
1460 } | |
1461 | |
1462 | |
1463 OrthancPeers::~OrthancPeers() | |
1464 { | |
1465 if (peers_ != NULL) | |
1466 { | |
1467 OrthancPluginFreePeers(GetGlobalContext(), peers_); | |
1468 } | |
1469 } | |
1470 | |
1471 | |
1472 bool OrthancPeers::LookupName(size_t& target, | |
1473 const std::string& name) const | |
1474 { | |
1475 Index::const_iterator found = index_.find(name); | |
1476 | |
1477 if (found == index_.end()) | |
1478 { | |
1479 return false; | |
1480 } | |
1481 else | |
1482 { | |
1483 target = found->second; | |
1484 return true; | |
1485 } | |
1486 } | |
1487 | |
1488 | |
1489 std::string OrthancPeers::GetPeerName(size_t index) const | |
1490 { | |
1491 if (index >= index_.size()) | |
1492 { | |
1493 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1494 } | |
1495 else | |
1496 { | |
1497 const char* s = OrthancPluginGetPeerName(GetGlobalContext(), peers_, static_cast<uint32_t>(index)); | |
1498 if (s == NULL) | |
1499 { | |
1500 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
73 } | 1501 } |
74 else | 1502 else |
75 { | 1503 { |
76 return globalContext_; | 1504 return s; |
77 } | 1505 } |
78 } | 1506 } |
79 | 1507 } |
80 | 1508 |
81 void MemoryBuffer::Check(OrthancPluginErrorCode code) | 1509 |
82 { | 1510 std::string OrthancPeers::GetPeerUrl(size_t index) const |
83 if (code != OrthancPluginErrorCode_Success) | 1511 { |
1512 if (index >= index_.size()) | |
1513 { | |
1514 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1515 } | |
1516 else | |
1517 { | |
1518 const char* s = OrthancPluginGetPeerUrl(GetGlobalContext(), peers_, static_cast<uint32_t>(index)); | |
1519 if (s == NULL) | |
84 { | 1520 { |
85 // Prevent using garbage information | 1521 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); |
86 buffer_.data = NULL; | |
87 buffer_.size = 0; | |
88 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | |
89 } | 1522 } |
90 } | 1523 else |
91 | |
92 | |
93 bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code) | |
94 { | |
95 if (code != OrthancPluginErrorCode_Success) | |
96 { | 1524 { |
97 // Prevent using garbage information | 1525 return s; |
98 buffer_.data = NULL; | |
99 buffer_.size = 0; | |
100 } | 1526 } |
101 | 1527 } |
102 if (code == OrthancPluginErrorCode_Success) | 1528 } |
103 { | 1529 |
104 return true; | 1530 |
105 } | 1531 std::string OrthancPeers::GetPeerUrl(const std::string& name) const |
106 else if (code == OrthancPluginErrorCode_UnknownResource || | 1532 { |
107 code == OrthancPluginErrorCode_InexistentItem) | 1533 return GetPeerUrl(GetPeerIndex(name)); |
1534 } | |
1535 | |
1536 | |
1537 bool OrthancPeers::LookupUserProperty(std::string& value, | |
1538 size_t index, | |
1539 const std::string& key) const | |
1540 { | |
1541 if (index >= index_.size()) | |
1542 { | |
1543 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1544 } | |
1545 else | |
1546 { | |
1547 const char* s = OrthancPluginGetPeerUserProperty(GetGlobalContext(), peers_, static_cast<uint32_t>(index), key.c_str()); | |
1548 if (s == NULL) | |
108 { | 1549 { |
109 return false; | 1550 return false; |
110 } | 1551 } |
111 else | 1552 else |
112 { | 1553 { |
113 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | 1554 value.assign(s); |
1555 return true; | |
114 } | 1556 } |
115 } | 1557 } |
116 | 1558 } |
117 | 1559 |
118 MemoryBuffer::MemoryBuffer() | 1560 |
119 { | 1561 bool OrthancPeers::LookupUserProperty(std::string& value, |
120 buffer_.data = NULL; | 1562 const std::string& peer, |
121 buffer_.size = 0; | 1563 const std::string& key) const |
122 } | 1564 { |
123 | 1565 return LookupUserProperty(value, GetPeerIndex(peer), key); |
124 | 1566 } |
125 void MemoryBuffer::Clear() | 1567 |
126 { | 1568 |
127 if (buffer_.data != NULL) | 1569 bool OrthancPeers::DoGet(MemoryBuffer& target, |
1570 size_t index, | |
1571 const std::string& uri) const | |
1572 { | |
1573 if (index >= index_.size()) | |
1574 { | |
1575 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1576 } | |
1577 | |
1578 OrthancPluginMemoryBuffer answer; | |
1579 uint16_t status; | |
1580 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1581 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1582 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Get, uri.c_str(), | |
1583 0, NULL, NULL, NULL, 0, timeout_); | |
1584 | |
1585 if (code == OrthancPluginErrorCode_Success) | |
1586 { | |
1587 target.Assign(answer); | |
1588 return (status == 200); | |
1589 } | |
1590 else | |
1591 { | |
1592 return false; | |
1593 } | |
1594 } | |
1595 | |
1596 | |
1597 bool OrthancPeers::DoGet(MemoryBuffer& target, | |
1598 const std::string& name, | |
1599 const std::string& uri) const | |
1600 { | |
1601 size_t index; | |
1602 return (LookupName(index, name) && | |
1603 DoGet(target, index, uri)); | |
1604 } | |
1605 | |
1606 | |
1607 bool OrthancPeers::DoGet(Json::Value& target, | |
1608 size_t index, | |
1609 const std::string& uri) const | |
1610 { | |
1611 MemoryBuffer buffer; | |
1612 | |
1613 if (DoGet(buffer, index, uri)) | |
1614 { | |
1615 buffer.ToJson(target); | |
1616 return true; | |
1617 } | |
1618 else | |
1619 { | |
1620 return false; | |
1621 } | |
1622 } | |
1623 | |
1624 | |
1625 bool OrthancPeers::DoGet(Json::Value& target, | |
1626 const std::string& name, | |
1627 const std::string& uri) const | |
1628 { | |
1629 MemoryBuffer buffer; | |
1630 | |
1631 if (DoGet(buffer, name, uri)) | |
1632 { | |
1633 buffer.ToJson(target); | |
1634 return true; | |
1635 } | |
1636 else | |
1637 { | |
1638 return false; | |
1639 } | |
1640 } | |
1641 | |
1642 | |
1643 bool OrthancPeers::DoPost(MemoryBuffer& target, | |
1644 const std::string& name, | |
1645 const std::string& uri, | |
1646 const std::string& body) const | |
1647 { | |
1648 size_t index; | |
1649 return (LookupName(index, name) && | |
1650 DoPost(target, index, uri, body)); | |
1651 } | |
1652 | |
1653 | |
1654 bool OrthancPeers::DoPost(Json::Value& target, | |
1655 size_t index, | |
1656 const std::string& uri, | |
1657 const std::string& body) const | |
1658 { | |
1659 MemoryBuffer buffer; | |
1660 | |
1661 if (DoPost(buffer, index, uri, body)) | |
1662 { | |
1663 buffer.ToJson(target); | |
1664 return true; | |
1665 } | |
1666 else | |
1667 { | |
1668 return false; | |
1669 } | |
1670 } | |
1671 | |
1672 | |
1673 bool OrthancPeers::DoPost(Json::Value& target, | |
1674 const std::string& name, | |
1675 const std::string& uri, | |
1676 const std::string& body) const | |
1677 { | |
1678 MemoryBuffer buffer; | |
1679 | |
1680 if (DoPost(buffer, name, uri, body)) | |
1681 { | |
1682 buffer.ToJson(target); | |
1683 return true; | |
1684 } | |
1685 else | |
1686 { | |
1687 return false; | |
1688 } | |
1689 } | |
1690 | |
1691 | |
1692 bool OrthancPeers::DoPost(MemoryBuffer& target, | |
1693 size_t index, | |
1694 const std::string& uri, | |
1695 const std::string& body) const | |
1696 { | |
1697 if (index >= index_.size()) | |
1698 { | |
1699 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1700 } | |
1701 | |
1702 OrthancPluginMemoryBuffer answer; | |
1703 uint16_t status; | |
1704 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1705 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1706 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), | |
1707 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | |
1708 | |
1709 if (code == OrthancPluginErrorCode_Success) | |
1710 { | |
1711 target.Assign(answer); | |
1712 return (status == 200); | |
1713 } | |
1714 else | |
1715 { | |
1716 return false; | |
1717 } | |
1718 } | |
1719 | |
1720 | |
1721 bool OrthancPeers::DoPut(size_t index, | |
1722 const std::string& uri, | |
1723 const std::string& body) const | |
1724 { | |
1725 if (index >= index_.size()) | |
1726 { | |
1727 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1728 } | |
1729 | |
1730 OrthancPluginMemoryBuffer answer; | |
1731 uint16_t status; | |
1732 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1733 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1734 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), | |
1735 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | |
1736 | |
1737 if (code == OrthancPluginErrorCode_Success) | |
1738 { | |
1739 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); | |
1740 return (status == 200); | |
1741 } | |
1742 else | |
1743 { | |
1744 return false; | |
1745 } | |
1746 } | |
1747 | |
1748 | |
1749 bool OrthancPeers::DoPut(const std::string& name, | |
1750 const std::string& uri, | |
1751 const std::string& body) const | |
1752 { | |
1753 size_t index; | |
1754 return (LookupName(index, name) && | |
1755 DoPut(index, uri, body)); | |
1756 } | |
1757 | |
1758 | |
1759 bool OrthancPeers::DoDelete(size_t index, | |
1760 const std::string& uri) const | |
1761 { | |
1762 if (index >= index_.size()) | |
1763 { | |
1764 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1765 } | |
1766 | |
1767 OrthancPluginMemoryBuffer answer; | |
1768 uint16_t status; | |
1769 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1770 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1771 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), | |
1772 0, NULL, NULL, NULL, 0, timeout_); | |
1773 | |
1774 if (code == OrthancPluginErrorCode_Success) | |
1775 { | |
1776 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); | |
1777 return (status == 200); | |
1778 } | |
1779 else | |
1780 { | |
1781 return false; | |
1782 } | |
1783 } | |
1784 | |
1785 | |
1786 bool OrthancPeers::DoDelete(const std::string& name, | |
1787 const std::string& uri) const | |
1788 { | |
1789 size_t index; | |
1790 return (LookupName(index, name) && | |
1791 DoDelete(index, uri)); | |
1792 } | |
1793 #endif | |
1794 | |
1795 | |
1796 | |
1797 #if HAS_ORTHANC_PLUGIN_JOB == 1 | |
1798 void OrthancJob::CallbackFinalize(void* job) | |
1799 { | |
1800 if (job != NULL) | |
1801 { | |
1802 delete reinterpret_cast<OrthancJob*>(job); | |
1803 } | |
1804 } | |
1805 | |
1806 | |
1807 float OrthancJob::CallbackGetProgress(void* job) | |
1808 { | |
1809 assert(job != NULL); | |
1810 | |
1811 try | |
1812 { | |
1813 return reinterpret_cast<OrthancJob*>(job)->progress_; | |
1814 } | |
1815 catch (...) | |
1816 { | |
1817 return 0; | |
1818 } | |
1819 } | |
1820 | |
1821 | |
1822 const char* OrthancJob::CallbackGetContent(void* job) | |
1823 { | |
1824 assert(job != NULL); | |
1825 | |
1826 try | |
1827 { | |
1828 return reinterpret_cast<OrthancJob*>(job)->content_.c_str(); | |
1829 } | |
1830 catch (...) | |
1831 { | |
1832 return 0; | |
1833 } | |
1834 } | |
1835 | |
1836 | |
1837 const char* OrthancJob::CallbackGetSerialized(void* job) | |
1838 { | |
1839 assert(job != NULL); | |
1840 | |
1841 try | |
1842 { | |
1843 const OrthancJob& tmp = *reinterpret_cast<OrthancJob*>(job); | |
1844 | |
1845 if (tmp.hasSerialized_) | |
128 { | 1846 { |
129 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_); | 1847 return tmp.serialized_.c_str(); |
130 buffer_.data = NULL; | |
131 buffer_.size = 0; | |
132 } | |
133 } | |
134 | |
135 | |
136 void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other) | |
137 { | |
138 Clear(); | |
139 | |
140 buffer_.data = other.data; | |
141 buffer_.size = other.size; | |
142 | |
143 other.data = NULL; | |
144 other.size = 0; | |
145 } | |
146 | |
147 | |
148 OrthancPluginMemoryBuffer MemoryBuffer::Release() | |
149 { | |
150 OrthancPluginMemoryBuffer result = buffer_; | |
151 | |
152 buffer_.data = NULL; | |
153 buffer_.size = 0; | |
154 | |
155 return result; | |
156 } | |
157 | |
158 | |
159 void MemoryBuffer::ToString(std::string& target) const | |
160 { | |
161 if (buffer_.size == 0) | |
162 { | |
163 target.clear(); | |
164 } | 1848 } |
165 else | 1849 else |
166 { | 1850 { |
167 target.assign(reinterpret_cast<const char*>(buffer_.data), buffer_.size); | 1851 return NULL; |
168 } | 1852 } |
169 } | 1853 } |
170 | 1854 catch (...) |
171 | 1855 { |
172 void MemoryBuffer::ToJson(Json::Value& target) const | 1856 return 0; |
173 { | 1857 } |
174 if (buffer_.data == NULL || | 1858 } |
175 buffer_.size == 0) | 1859 |
176 { | 1860 |
177 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | 1861 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) |
178 } | 1862 { |
179 | 1863 assert(job != NULL); |
180 const char* tmp = reinterpret_cast<const char*>(buffer_.data); | 1864 |
181 | 1865 try |
182 Json::Reader reader; | 1866 { |
183 if (!reader.parse(tmp, tmp + buffer_.size, target)) | 1867 return reinterpret_cast<OrthancJob*>(job)->Step(); |
184 { | 1868 } |
185 LogError("Cannot convert some memory buffer to JSON"); | 1869 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&) |
186 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | 1870 { |
187 } | 1871 return OrthancPluginJobStepStatus_Failure; |
188 } | 1872 } |
189 | 1873 catch (...) |
190 | 1874 { |
191 bool MemoryBuffer::RestApiGet(const std::string& uri, | 1875 return OrthancPluginJobStepStatus_Failure; |
192 bool applyPlugins) | 1876 } |
193 { | 1877 } |
194 Clear(); | 1878 |
195 | 1879 |
196 if (applyPlugins) | 1880 OrthancPluginErrorCode OrthancJob::CallbackStop(void* job, |
197 { | 1881 OrthancPluginJobStopReason reason) |
198 return CheckHttp(OrthancPluginRestApiGetAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str())); | 1882 { |
199 } | 1883 assert(job != NULL); |
200 else | 1884 |
201 { | 1885 try |
202 return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); | 1886 { |
203 } | 1887 reinterpret_cast<OrthancJob*>(job)->Stop(reason); |
204 } | 1888 return OrthancPluginErrorCode_Success; |
205 | 1889 } |
206 | 1890 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) |
207 bool MemoryBuffer::RestApiPost(const std::string& uri, | 1891 { |
208 const char* body, | 1892 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); |
209 size_t bodySize, | 1893 } |
210 bool applyPlugins) | 1894 catch (...) |
211 { | 1895 { |
212 Clear(); | 1896 return OrthancPluginErrorCode_Plugin; |
213 | 1897 } |
214 if (applyPlugins) | 1898 } |
215 { | 1899 |
216 return CheckHttp(OrthancPluginRestApiPostAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | 1900 |
217 } | 1901 OrthancPluginErrorCode OrthancJob::CallbackReset(void* job) |
218 else | 1902 { |
219 { | 1903 assert(job != NULL); |
220 return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | 1904 |
221 } | 1905 try |
222 } | 1906 { |
223 | 1907 reinterpret_cast<OrthancJob*>(job)->Reset(); |
224 | 1908 return OrthancPluginErrorCode_Success; |
225 bool MemoryBuffer::RestApiPut(const std::string& uri, | 1909 } |
226 const char* body, | 1910 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) |
227 size_t bodySize, | 1911 { |
228 bool applyPlugins) | 1912 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); |
229 { | 1913 } |
230 Clear(); | 1914 catch (...) |
231 | 1915 { |
232 if (applyPlugins) | 1916 return OrthancPluginErrorCode_Plugin; |
233 { | 1917 } |
234 return CheckHttp(OrthancPluginRestApiPutAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | 1918 } |
235 } | 1919 |
236 else | 1920 |
237 { | 1921 void OrthancJob::ClearContent() |
238 return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); | 1922 { |
239 } | 1923 Json::Value empty = Json::objectValue; |
240 } | 1924 UpdateContent(empty); |
241 | 1925 } |
242 | 1926 |
243 bool MemoryBuffer::RestApiPost(const std::string& uri, | 1927 |
244 const Json::Value& body, | 1928 void OrthancJob::UpdateContent(const Json::Value& content) |
245 bool applyPlugins) | 1929 { |
1930 if (content.type() != Json::objectValue) | |
1931 { | |
1932 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); | |
1933 } | |
1934 else | |
246 { | 1935 { |
247 Json::FastWriter writer; | 1936 Json::FastWriter writer; |
248 return RestApiPost(uri, writer.write(body), applyPlugins); | 1937 content_ = writer.write(content); |
249 } | 1938 } |
250 | 1939 } |
251 | 1940 |
252 bool MemoryBuffer::RestApiPut(const std::string& uri, | 1941 |
253 const Json::Value& body, | 1942 void OrthancJob::ClearSerialized() |
254 bool applyPlugins) | 1943 { |
1944 hasSerialized_ = false; | |
1945 serialized_.clear(); | |
1946 } | |
1947 | |
1948 | |
1949 void OrthancJob::UpdateSerialized(const Json::Value& serialized) | |
1950 { | |
1951 if (serialized.type() != Json::objectValue) | |
1952 { | |
1953 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); | |
1954 } | |
1955 else | |
255 { | 1956 { |
256 Json::FastWriter writer; | 1957 Json::FastWriter writer; |
257 return RestApiPut(uri, writer.write(body), applyPlugins); | 1958 serialized_ = writer.write(serialized); |
258 } | 1959 hasSerialized_ = true; |
259 | 1960 } |
260 | 1961 } |
261 void MemoryBuffer::CreateDicom(const Json::Value& tags, | 1962 |
262 OrthancPluginCreateDicomFlags flags) | 1963 |
263 { | 1964 void OrthancJob::UpdateProgress(float progress) |
264 Clear(); | 1965 { |
265 | 1966 if (progress < 0 || |
266 Json::FastWriter writer; | 1967 progress > 1) |
267 std::string s = writer.write(tags); | 1968 { |
268 | 1969 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); |
269 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); | 1970 } |
270 } | 1971 |
271 | 1972 progress_ = progress; |
272 void MemoryBuffer::CreateDicom(const Json::Value& tags, | 1973 } |
273 const OrthancImage& pixelData, | 1974 |
274 OrthancPluginCreateDicomFlags flags) | 1975 |
275 { | 1976 OrthancJob::OrthancJob(const std::string& jobType) : |
276 Clear(); | 1977 jobType_(jobType), |
277 | 1978 progress_(0) |
278 Json::FastWriter writer; | 1979 { |
279 std::string s = writer.write(tags); | 1980 ClearContent(); |
280 | 1981 ClearSerialized(); |
281 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags)); | 1982 } |
282 } | 1983 |
283 | 1984 |
284 | 1985 OrthancPluginJob* OrthancJob::Create(OrthancJob* job) |
285 void MemoryBuffer::ReadFile(const std::string& path) | 1986 { |
286 { | 1987 if (job == NULL) |
287 Clear(); | 1988 { |
288 Check(OrthancPluginReadFile(GetGlobalContext(), &buffer_, path.c_str())); | 1989 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); |
289 } | 1990 } |
290 | 1991 |
291 | 1992 OrthancPluginJob* orthanc = OrthancPluginCreateJob( |
292 void MemoryBuffer::GetDicomQuery(const OrthancPluginWorklistQuery* query) | 1993 GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), |
293 { | 1994 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, |
294 Clear(); | 1995 CallbackStep, CallbackStop, CallbackReset); |
295 Check(OrthancPluginWorklistGetDicomQuery(GetGlobalContext(), &buffer_, query)); | 1996 |
296 } | 1997 if (orthanc == NULL) |
297 | 1998 { |
298 | 1999 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); |
299 void OrthancString::Assign(char* str) | 2000 } |
300 { | 2001 else |
301 if (str == NULL) | 2002 { |
302 { | 2003 return orthanc; |
303 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | 2004 } |
304 } | 2005 } |
305 else | 2006 |
306 { | 2007 |
307 Clear(); | 2008 std::string OrthancJob::Submit(OrthancJob* job, |
308 str_ = str; | 2009 int priority) |
309 } | 2010 { |
310 } | 2011 OrthancPluginJob* orthanc = Create(job); |
311 | 2012 |
312 | 2013 char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority); |
313 void OrthancString::Clear() | 2014 |
314 { | 2015 if (id == NULL) |
315 if (str_ != NULL) | 2016 { |
316 { | 2017 LogError("Plugin cannot submit job"); |
317 OrthancPluginFreeString(GetGlobalContext(), str_); | 2018 OrthancPluginFreeJob(GetGlobalContext(), orthanc); |
318 str_ = NULL; | 2019 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); |
319 } | 2020 } |
320 } | 2021 else |
321 | 2022 { |
322 | 2023 std::string tmp(id); |
323 void OrthancString::ToString(std::string& target) const | 2024 tmp.assign(id); |
324 { | 2025 OrthancPluginFreeString(GetGlobalContext(), id); |
325 if (str_ == NULL) | 2026 |
326 { | 2027 return tmp; |
327 target.clear(); | 2028 } |
328 } | 2029 } |
329 else | |
330 { | |
331 target.assign(str_); | |
332 } | |
333 } | |
334 | |
335 | |
336 void OrthancString::ToJson(Json::Value& target) const | |
337 { | |
338 if (str_ == NULL) | |
339 { | |
340 LogError("Cannot convert an empty memory buffer to JSON"); | |
341 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
342 } | |
343 | |
344 Json::Reader reader; | |
345 if (!reader.parse(str_, target)) | |
346 { | |
347 LogError("Cannot convert some memory buffer to JSON"); | |
348 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
349 } | |
350 } | |
351 | |
352 | |
353 void MemoryBuffer::DicomToJson(Json::Value& target, | |
354 OrthancPluginDicomToJsonFormat format, | |
355 OrthancPluginDicomToJsonFlags flags, | |
356 uint32_t maxStringLength) | |
357 { | |
358 OrthancString str; | |
359 str.Assign(OrthancPluginDicomBufferToJson | |
360 (GetGlobalContext(), GetData(), GetSize(), format, flags, maxStringLength)); | |
361 str.ToJson(target); | |
362 } | |
363 | |
364 | |
365 bool MemoryBuffer::HttpGet(const std::string& url, | |
366 const std::string& username, | |
367 const std::string& password) | |
368 { | |
369 Clear(); | |
370 return CheckHttp(OrthancPluginHttpGet(GetGlobalContext(), &buffer_, url.c_str(), | |
371 username.empty() ? NULL : username.c_str(), | |
372 password.empty() ? NULL : password.c_str())); | |
373 } | |
374 | |
375 | |
376 bool MemoryBuffer::HttpPost(const std::string& url, | |
377 const std::string& body, | |
378 const std::string& username, | |
379 const std::string& password) | |
380 { | |
381 Clear(); | |
382 return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), | |
383 body.c_str(), body.size(), | |
384 username.empty() ? NULL : username.c_str(), | |
385 password.empty() ? NULL : password.c_str())); | |
386 } | |
387 | |
388 | |
389 bool MemoryBuffer::HttpPut(const std::string& url, | |
390 const std::string& body, | |
391 const std::string& username, | |
392 const std::string& password) | |
393 { | |
394 Clear(); | |
395 return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), | |
396 body.empty() ? NULL : body.c_str(), | |
397 body.size(), | |
398 username.empty() ? NULL : username.c_str(), | |
399 password.empty() ? NULL : password.c_str())); | |
400 } | |
401 | |
402 | |
403 void MemoryBuffer::GetDicomInstance(const std::string& instanceId) | |
404 { | |
405 Clear(); | |
406 Check(OrthancPluginGetDicomForInstance(GetGlobalContext(), &buffer_, instanceId.c_str())); | |
407 } | |
408 | |
409 | |
410 bool HttpDelete(const std::string& url, | |
411 const std::string& username, | |
412 const std::string& password) | |
413 { | |
414 OrthancPluginErrorCode error = OrthancPluginHttpDelete | |
415 (GetGlobalContext(), url.c_str(), | |
416 username.empty() ? NULL : username.c_str(), | |
417 password.empty() ? NULL : password.c_str()); | |
418 | |
419 if (error == OrthancPluginErrorCode_Success) | |
420 { | |
421 return true; | |
422 } | |
423 else if (error == OrthancPluginErrorCode_UnknownResource || | |
424 error == OrthancPluginErrorCode_InexistentItem) | |
425 { | |
426 return false; | |
427 } | |
428 else | |
429 { | |
430 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); | |
431 } | |
432 } | |
433 | |
434 | |
435 void LogError(const std::string& message) | |
436 { | |
437 if (HasGlobalContext()) | |
438 { | |
439 OrthancPluginLogError(GetGlobalContext(), message.c_str()); | |
440 } | |
441 } | |
442 | |
443 | |
444 void LogWarning(const std::string& message) | |
445 { | |
446 if (HasGlobalContext()) | |
447 { | |
448 OrthancPluginLogWarning(GetGlobalContext(), message.c_str()); | |
449 } | |
450 } | |
451 | |
452 | |
453 void LogInfo(const std::string& message) | |
454 { | |
455 if (HasGlobalContext()) | |
456 { | |
457 OrthancPluginLogInfo(GetGlobalContext(), message.c_str()); | |
458 } | |
459 } | |
460 | |
461 | |
462 OrthancConfiguration::OrthancConfiguration() | |
463 { | |
464 OrthancString str; | |
465 str.Assign(OrthancPluginGetConfiguration(GetGlobalContext())); | |
466 | |
467 if (str.GetContent() == NULL) | |
468 { | |
469 LogError("Cannot access the Orthanc configuration"); | |
470 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
471 } | |
472 | |
473 str.ToJson(configuration_); | |
474 | |
475 if (configuration_.type() != Json::objectValue) | |
476 { | |
477 LogError("Unable to read the Orthanc configuration"); | |
478 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
479 } | |
480 } | |
481 | |
482 | |
483 std::string OrthancConfiguration::GetPath(const std::string& key) const | |
484 { | |
485 if (path_.empty()) | |
486 { | |
487 return key; | |
488 } | |
489 else | |
490 { | |
491 return path_ + "." + key; | |
492 } | |
493 } | |
494 | |
495 | |
496 bool OrthancConfiguration::IsSection(const std::string& key) const | |
497 { | |
498 assert(configuration_.type() == Json::objectValue); | |
499 | |
500 return (configuration_.isMember(key) && | |
501 configuration_[key].type() == Json::objectValue); | |
502 } | |
503 | |
504 | |
505 void OrthancConfiguration::GetSection(OrthancConfiguration& target, | |
506 const std::string& key) const | |
507 { | |
508 assert(configuration_.type() == Json::objectValue); | |
509 | |
510 target.path_ = GetPath(key); | |
511 | |
512 if (!configuration_.isMember(key)) | |
513 { | |
514 target.configuration_ = Json::objectValue; | |
515 } | |
516 else | |
517 { | |
518 if (configuration_[key].type() != Json::objectValue) | |
519 { | |
520 LogError("The configuration section \"" + target.path_ + | |
521 "\" is not an associative array as expected"); | |
522 | |
523 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
524 } | |
525 | |
526 target.configuration_ = configuration_[key]; | |
527 } | |
528 } | |
529 | |
530 | |
531 bool OrthancConfiguration::LookupStringValue(std::string& target, | |
532 const std::string& key) const | |
533 { | |
534 assert(configuration_.type() == Json::objectValue); | |
535 | |
536 if (!configuration_.isMember(key)) | |
537 { | |
538 return false; | |
539 } | |
540 | |
541 if (configuration_[key].type() != Json::stringValue) | |
542 { | |
543 LogError("The configuration option \"" + GetPath(key) + | |
544 "\" is not a string as expected"); | |
545 | |
546 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
547 } | |
548 | |
549 target = configuration_[key].asString(); | |
550 return true; | |
551 } | |
552 | |
553 | |
554 bool OrthancConfiguration::LookupIntegerValue(int& target, | |
555 const std::string& key) const | |
556 { | |
557 assert(configuration_.type() == Json::objectValue); | |
558 | |
559 if (!configuration_.isMember(key)) | |
560 { | |
561 return false; | |
562 } | |
563 | |
564 switch (configuration_[key].type()) | |
565 { | |
566 case Json::intValue: | |
567 target = configuration_[key].asInt(); | |
568 return true; | |
569 | |
570 case Json::uintValue: | |
571 target = configuration_[key].asUInt(); | |
572 return true; | |
573 | |
574 default: | |
575 LogError("The configuration option \"" + GetPath(key) + | |
576 "\" is not an integer as expected"); | |
577 | |
578 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
579 } | |
580 } | |
581 | |
582 | |
583 bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target, | |
584 const std::string& key) const | |
585 { | |
586 int tmp; | |
587 if (!LookupIntegerValue(tmp, key)) | |
588 { | |
589 return false; | |
590 } | |
591 | |
592 if (tmp < 0) | |
593 { | |
594 LogError("The configuration option \"" + GetPath(key) + | |
595 "\" is not a positive integer as expected"); | |
596 | |
597 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
598 } | |
599 else | |
600 { | |
601 target = static_cast<unsigned int>(tmp); | |
602 return true; | |
603 } | |
604 } | |
605 | |
606 | |
607 bool OrthancConfiguration::LookupBooleanValue(bool& target, | |
608 const std::string& key) const | |
609 { | |
610 assert(configuration_.type() == Json::objectValue); | |
611 | |
612 if (!configuration_.isMember(key)) | |
613 { | |
614 return false; | |
615 } | |
616 | |
617 if (configuration_[key].type() != Json::booleanValue) | |
618 { | |
619 LogError("The configuration option \"" + GetPath(key) + | |
620 "\" is not a Boolean as expected"); | |
621 | |
622 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
623 } | |
624 | |
625 target = configuration_[key].asBool(); | |
626 return true; | |
627 } | |
628 | |
629 | |
630 bool OrthancConfiguration::LookupFloatValue(float& target, | |
631 const std::string& key) const | |
632 { | |
633 assert(configuration_.type() == Json::objectValue); | |
634 | |
635 if (!configuration_.isMember(key)) | |
636 { | |
637 return false; | |
638 } | |
639 | |
640 switch (configuration_[key].type()) | |
641 { | |
642 case Json::realValue: | |
643 target = configuration_[key].asFloat(); | |
644 return true; | |
645 | |
646 case Json::intValue: | |
647 target = static_cast<float>(configuration_[key].asInt()); | |
648 return true; | |
649 | |
650 case Json::uintValue: | |
651 target = static_cast<float>(configuration_[key].asUInt()); | |
652 return true; | |
653 | |
654 default: | |
655 LogError("The configuration option \"" + GetPath(key) + | |
656 "\" is not an integer as expected"); | |
657 | |
658 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
659 } | |
660 } | |
661 | |
662 | |
663 bool OrthancConfiguration::LookupListOfStrings(std::list<std::string>& target, | |
664 const std::string& key, | |
665 bool allowSingleString) const | |
666 { | |
667 assert(configuration_.type() == Json::objectValue); | |
668 | |
669 target.clear(); | |
670 | |
671 if (!configuration_.isMember(key)) | |
672 { | |
673 return false; | |
674 } | |
675 | |
676 switch (configuration_[key].type()) | |
677 { | |
678 case Json::arrayValue: | |
679 { | |
680 bool ok = true; | |
681 | |
682 for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++) | |
683 { | |
684 if (configuration_[key][i].type() == Json::stringValue) | |
685 { | |
686 target.push_back(configuration_[key][i].asString()); | |
687 } | |
688 else | |
689 { | |
690 ok = false; | |
691 } | |
692 } | |
693 | |
694 if (ok) | |
695 { | |
696 return true; | |
697 } | |
698 | |
699 break; | |
700 } | |
701 | |
702 case Json::stringValue: | |
703 if (allowSingleString) | |
704 { | |
705 target.push_back(configuration_[key].asString()); | |
706 return true; | |
707 } | |
708 | |
709 break; | |
710 | |
711 default: | |
712 break; | |
713 } | |
714 | |
715 LogError("The configuration option \"" + GetPath(key) + | |
716 "\" is not a list of strings as expected"); | |
717 | |
718 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
719 } | |
720 | |
721 | |
722 bool OrthancConfiguration::LookupSetOfStrings(std::set<std::string>& target, | |
723 const std::string& key, | |
724 bool allowSingleString) const | |
725 { | |
726 std::list<std::string> lst; | |
727 | |
728 if (LookupListOfStrings(lst, key, allowSingleString)) | |
729 { | |
730 target.clear(); | |
731 | |
732 for (std::list<std::string>::const_iterator | |
733 it = lst.begin(); it != lst.end(); ++it) | |
734 { | |
735 target.insert(*it); | |
736 } | |
737 | |
738 return true; | |
739 } | |
740 else | |
741 { | |
742 return false; | |
743 } | |
744 } | |
745 | |
746 | |
747 std::string OrthancConfiguration::GetStringValue(const std::string& key, | |
748 const std::string& defaultValue) const | |
749 { | |
750 std::string tmp; | |
751 if (LookupStringValue(tmp, key)) | |
752 { | |
753 return tmp; | |
754 } | |
755 else | |
756 { | |
757 return defaultValue; | |
758 } | |
759 } | |
760 | |
761 | |
762 int OrthancConfiguration::GetIntegerValue(const std::string& key, | |
763 int defaultValue) const | |
764 { | |
765 int tmp; | |
766 if (LookupIntegerValue(tmp, key)) | |
767 { | |
768 return tmp; | |
769 } | |
770 else | |
771 { | |
772 return defaultValue; | |
773 } | |
774 } | |
775 | |
776 | |
777 unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key, | |
778 unsigned int defaultValue) const | |
779 { | |
780 unsigned int tmp; | |
781 if (LookupUnsignedIntegerValue(tmp, key)) | |
782 { | |
783 return tmp; | |
784 } | |
785 else | |
786 { | |
787 return defaultValue; | |
788 } | |
789 } | |
790 | |
791 | |
792 bool OrthancConfiguration::GetBooleanValue(const std::string& key, | |
793 bool defaultValue) const | |
794 { | |
795 bool tmp; | |
796 if (LookupBooleanValue(tmp, key)) | |
797 { | |
798 return tmp; | |
799 } | |
800 else | |
801 { | |
802 return defaultValue; | |
803 } | |
804 } | |
805 | |
806 | |
807 float OrthancConfiguration::GetFloatValue(const std::string& key, | |
808 float defaultValue) const | |
809 { | |
810 float tmp; | |
811 if (LookupFloatValue(tmp, key)) | |
812 { | |
813 return tmp; | |
814 } | |
815 else | |
816 { | |
817 return defaultValue; | |
818 } | |
819 } | |
820 | |
821 | |
822 void OrthancConfiguration::GetDictionary(std::map<std::string, std::string>& target, | |
823 const std::string& key) const | |
824 { | |
825 assert(configuration_.type() == Json::objectValue); | |
826 | |
827 target.clear(); | |
828 | |
829 if (!configuration_.isMember(key)) | |
830 { | |
831 return; | |
832 } | |
833 | |
834 if (configuration_[key].type() != Json::objectValue) | |
835 { | |
836 LogError("The configuration option \"" + GetPath(key) + | |
837 "\" is not a string as expected"); | |
838 | |
839 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
840 } | |
841 | |
842 Json::Value::Members members = configuration_[key].getMemberNames(); | |
843 | |
844 for (size_t i = 0; i < members.size(); i++) | |
845 { | |
846 const Json::Value& value = configuration_[key][members[i]]; | |
847 | |
848 if (value.type() == Json::stringValue) | |
849 { | |
850 target[members[i]] = value.asString(); | |
851 } | |
852 else | |
853 { | |
854 LogError("The configuration option \"" + GetPath(key) + | |
855 "\" is not a dictionary mapping strings to strings"); | |
856 | |
857 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
858 } | |
859 } | |
860 } | |
861 | |
862 | |
863 void OrthancImage::Clear() | |
864 { | |
865 if (image_ != NULL) | |
866 { | |
867 OrthancPluginFreeImage(GetGlobalContext(), image_); | |
868 image_ = NULL; | |
869 } | |
870 } | |
871 | |
872 | |
873 void OrthancImage::CheckImageAvailable() | |
874 { | |
875 if (image_ == NULL) | |
876 { | |
877 LogError("Trying to access a NULL image"); | |
878 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
879 } | |
880 } | |
881 | |
882 | |
883 OrthancImage::OrthancImage() : | |
884 image_(NULL) | |
885 { | |
886 } | |
887 | |
888 | |
889 OrthancImage::OrthancImage(OrthancPluginImage* image) : | |
890 image_(image) | |
891 { | |
892 } | |
893 | |
894 | |
895 OrthancImage::OrthancImage(OrthancPluginPixelFormat format, | |
896 uint32_t width, | |
897 uint32_t height) | |
898 { | |
899 image_ = OrthancPluginCreateImage(GetGlobalContext(), format, width, height); | |
900 | |
901 if (image_ == NULL) | |
902 { | |
903 LogError("Cannot create an image"); | |
904 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
905 } | |
906 } | |
907 | |
908 | |
909 OrthancImage::OrthancImage(OrthancPluginPixelFormat format, | |
910 uint32_t width, | |
911 uint32_t height, | |
912 uint32_t pitch, | |
913 void* buffer) | |
914 { | |
915 image_ = OrthancPluginCreateImageAccessor | |
916 (GetGlobalContext(), format, width, height, pitch, buffer); | |
917 | |
918 if (image_ == NULL) | |
919 { | |
920 LogError("Cannot create an image accessor"); | |
921 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
922 } | |
923 } | |
924 | |
925 void OrthancImage::UncompressPngImage(const void* data, | |
926 size_t size) | |
927 { | |
928 Clear(); | |
929 | |
930 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Png); | |
931 | |
932 if (image_ == NULL) | |
933 { | |
934 LogError("Cannot uncompress a PNG image"); | |
935 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
936 } | |
937 } | |
938 | |
939 | |
940 void OrthancImage::UncompressJpegImage(const void* data, | |
941 size_t size) | |
942 { | |
943 Clear(); | |
944 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Jpeg); | |
945 if (image_ == NULL) | |
946 { | |
947 LogError("Cannot uncompress a JPEG image"); | |
948 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
949 } | |
950 } | |
951 | |
952 | |
953 void OrthancImage::DecodeDicomImage(const void* data, | |
954 size_t size, | |
955 unsigned int frame) | |
956 { | |
957 Clear(); | |
958 image_ = OrthancPluginDecodeDicomImage(GetGlobalContext(), data, size, frame); | |
959 if (image_ == NULL) | |
960 { | |
961 LogError("Cannot uncompress a DICOM image"); | |
962 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
963 } | |
964 } | |
965 | |
966 | |
967 OrthancPluginPixelFormat OrthancImage::GetPixelFormat() | |
968 { | |
969 CheckImageAvailable(); | |
970 return OrthancPluginGetImagePixelFormat(GetGlobalContext(), image_); | |
971 } | |
972 | |
973 | |
974 unsigned int OrthancImage::GetWidth() | |
975 { | |
976 CheckImageAvailable(); | |
977 return OrthancPluginGetImageWidth(GetGlobalContext(), image_); | |
978 } | |
979 | |
980 | |
981 unsigned int OrthancImage::GetHeight() | |
982 { | |
983 CheckImageAvailable(); | |
984 return OrthancPluginGetImageHeight(GetGlobalContext(), image_); | |
985 } | |
986 | |
987 | |
988 unsigned int OrthancImage::GetPitch() | |
989 { | |
990 CheckImageAvailable(); | |
991 return OrthancPluginGetImagePitch(GetGlobalContext(), image_); | |
992 } | |
993 | |
994 | |
995 const void* OrthancImage::GetBuffer() | |
996 { | |
997 CheckImageAvailable(); | |
998 return OrthancPluginGetImageBuffer(GetGlobalContext(), image_); | |
999 } | |
1000 | |
1001 | |
1002 void OrthancImage::CompressPngImage(MemoryBuffer& target) | |
1003 { | |
1004 CheckImageAvailable(); | |
1005 | |
1006 OrthancPluginMemoryBuffer tmp; | |
1007 OrthancPluginCompressPngImage(GetGlobalContext(), &tmp, GetPixelFormat(), | |
1008 GetWidth(), GetHeight(), GetPitch(), GetBuffer()); | |
1009 | |
1010 target.Assign(tmp); | |
1011 } | |
1012 | |
1013 | |
1014 void OrthancImage::CompressJpegImage(MemoryBuffer& target, | |
1015 uint8_t quality) | |
1016 { | |
1017 CheckImageAvailable(); | |
1018 | |
1019 OrthancPluginMemoryBuffer tmp; | |
1020 OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(), | |
1021 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); | |
1022 | |
1023 target.Assign(tmp); | |
1024 } | |
1025 | |
1026 | |
1027 void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output) | |
1028 { | |
1029 CheckImageAvailable(); | |
1030 OrthancPluginCompressAndAnswerPngImage(GetGlobalContext(), output, GetPixelFormat(), | |
1031 GetWidth(), GetHeight(), GetPitch(), GetBuffer()); | |
1032 } | |
1033 | |
1034 | |
1035 void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output, | |
1036 uint8_t quality) | |
1037 { | |
1038 CheckImageAvailable(); | |
1039 OrthancPluginCompressAndAnswerJpegImage(GetGlobalContext(), output, GetPixelFormat(), | |
1040 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality); | |
1041 } | |
1042 | |
1043 | |
1044 | |
1045 #if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 | |
1046 FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) : | |
1047 matcher_(NULL), | |
1048 worklist_(worklist) | |
1049 { | |
1050 if (worklist_ == NULL) | |
1051 { | |
1052 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
1053 } | |
1054 } | |
1055 | |
1056 | |
1057 void FindMatcher::SetupDicom(const void* query, | |
1058 uint32_t size) | |
1059 { | |
1060 worklist_ = NULL; | |
1061 | |
1062 matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size); | |
1063 if (matcher_ == NULL) | |
1064 { | |
1065 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1066 } | |
1067 } | |
1068 | |
1069 | |
1070 FindMatcher::~FindMatcher() | |
1071 { | |
1072 // The "worklist_" field | |
1073 | |
1074 if (matcher_ != NULL) | |
1075 { | |
1076 OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_); | |
1077 } | |
1078 } | |
1079 | |
1080 | |
1081 | |
1082 bool FindMatcher::IsMatch(const void* dicom, | |
1083 uint32_t size) const | |
1084 { | |
1085 int32_t result; | |
1086 | |
1087 if (matcher_ != NULL) | |
1088 { | |
1089 result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size); | |
1090 } | |
1091 else if (worklist_ != NULL) | |
1092 { | |
1093 result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size); | |
1094 } | |
1095 else | |
1096 { | |
1097 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1098 } | |
1099 | |
1100 if (result == 0) | |
1101 { | |
1102 return false; | |
1103 } | |
1104 else if (result == 1) | |
1105 { | |
1106 return true; | |
1107 } | |
1108 else | |
1109 { | |
1110 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1111 } | |
1112 } | |
1113 | |
1114 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ | |
1115 | |
1116 void AnswerJson(const Json::Value& value, | |
1117 OrthancPluginRestOutput* output | |
1118 ) | |
1119 { | |
1120 Json::StyledWriter writer; | |
1121 std::string bodyString = writer.write(value); | |
1122 | |
1123 OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); | |
1124 } | |
1125 | |
1126 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) | |
1127 { | |
1128 OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError); | |
1129 } | |
1130 | |
1131 void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods) | |
1132 { | |
1133 OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods); | |
1134 } | |
1135 | |
1136 bool RestApiGetString(std::string& result, | |
1137 const std::string& uri, | |
1138 bool applyPlugins) | |
1139 { | |
1140 MemoryBuffer answer; | |
1141 if (!answer.RestApiGet(uri, applyPlugins)) | |
1142 { | |
1143 return false; | |
1144 } | |
1145 else | |
1146 { | |
1147 answer.ToString(result); | |
1148 return true; | |
1149 } | |
1150 } | |
1151 | |
1152 | |
1153 bool RestApiGet(Json::Value& result, | |
1154 const std::string& uri, | |
1155 bool applyPlugins) | |
1156 { | |
1157 MemoryBuffer answer; | |
1158 | |
1159 if (!answer.RestApiGet(uri, applyPlugins)) | |
1160 { | |
1161 return false; | |
1162 } | |
1163 else | |
1164 { | |
1165 if (!answer.IsEmpty()) | |
1166 { | |
1167 answer.ToJson(result); | |
1168 } | |
1169 return true; | |
1170 } | |
1171 } | |
1172 | |
1173 | |
1174 bool RestApiPost(Json::Value& result, | |
1175 const std::string& uri, | |
1176 const char* body, | |
1177 size_t bodySize, | |
1178 bool applyPlugins) | |
1179 { | |
1180 MemoryBuffer answer; | |
1181 | |
1182 if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) | |
1183 { | |
1184 return false; | |
1185 } | |
1186 else | |
1187 { | |
1188 if (!answer.IsEmpty()) | |
1189 { | |
1190 answer.ToJson(result); | |
1191 } | |
1192 return true; | |
1193 } | |
1194 } | |
1195 | |
1196 | |
1197 bool RestApiPost(Json::Value& result, | |
1198 const std::string& uri, | |
1199 const Json::Value& body, | |
1200 bool applyPlugins) | |
1201 { | |
1202 Json::FastWriter writer; | |
1203 return RestApiPost(result, uri, writer.write(body), applyPlugins); | |
1204 } | |
1205 | |
1206 | |
1207 bool RestApiPut(Json::Value& result, | |
1208 const std::string& uri, | |
1209 const char* body, | |
1210 size_t bodySize, | |
1211 bool applyPlugins) | |
1212 { | |
1213 MemoryBuffer answer; | |
1214 | |
1215 if (!answer.RestApiPut(uri, body, bodySize, applyPlugins)) | |
1216 { | |
1217 return false; | |
1218 } | |
1219 else | |
1220 { | |
1221 if (!answer.IsEmpty()) // i.e, on a PUT to metadata/..., orthand returns an empty response | |
1222 { | |
1223 answer.ToJson(result); | |
1224 } | |
1225 return true; | |
1226 } | |
1227 } | |
1228 | |
1229 | |
1230 bool RestApiPut(Json::Value& result, | |
1231 const std::string& uri, | |
1232 const Json::Value& body, | |
1233 bool applyPlugins) | |
1234 { | |
1235 Json::FastWriter writer; | |
1236 return RestApiPut(result, uri, writer.write(body), applyPlugins); | |
1237 } | |
1238 | |
1239 | |
1240 bool RestApiDelete(const std::string& uri, | |
1241 bool applyPlugins) | |
1242 { | |
1243 OrthancPluginErrorCode error; | |
1244 | |
1245 if (applyPlugins) | |
1246 { | |
1247 error = OrthancPluginRestApiDeleteAfterPlugins(GetGlobalContext(), uri.c_str()); | |
1248 } | |
1249 else | |
1250 { | |
1251 error = OrthancPluginRestApiDelete(GetGlobalContext(), uri.c_str()); | |
1252 } | |
1253 | |
1254 if (error == OrthancPluginErrorCode_Success) | |
1255 { | |
1256 return true; | |
1257 } | |
1258 else if (error == OrthancPluginErrorCode_UnknownResource || | |
1259 error == OrthancPluginErrorCode_InexistentItem) | |
1260 { | |
1261 return false; | |
1262 } | |
1263 else | |
1264 { | |
1265 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); | |
1266 } | |
1267 } | |
1268 | |
1269 | |
1270 void ReportMinimalOrthancVersion(unsigned int major, | |
1271 unsigned int minor, | |
1272 unsigned int revision) | |
1273 { | |
1274 LogError("Your version of the Orthanc core (" + | |
1275 std::string(GetGlobalContext()->orthancVersion) + | |
1276 ") is too old to run this plugin (version " + | |
1277 boost::lexical_cast<std::string>(major) + "." + | |
1278 boost::lexical_cast<std::string>(minor) + "." + | |
1279 boost::lexical_cast<std::string>(revision) + | |
1280 " is required)"); | |
1281 } | |
1282 | |
1283 | |
1284 bool CheckMinimalOrthancVersion(unsigned int major, | |
1285 unsigned int minor, | |
1286 unsigned int revision) | |
1287 { | |
1288 if (!HasGlobalContext()) | |
1289 { | |
1290 LogError("Bad Orthanc context in the plugin"); | |
1291 return false; | |
1292 } | |
1293 | |
1294 if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) | |
1295 { | |
1296 // Assume compatibility with the mainline | |
1297 return true; | |
1298 } | |
1299 | |
1300 // Parse the version of the Orthanc core | |
1301 int aa, bb, cc; | |
1302 if ( | |
1303 #ifdef _MSC_VER | |
1304 sscanf_s | |
1305 #else | |
1306 sscanf | |
1307 #endif | |
1308 (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || | |
1309 aa < 0 || | |
1310 bb < 0 || | |
1311 cc < 0) | |
1312 { | |
1313 return false; | |
1314 } | |
1315 | |
1316 unsigned int a = static_cast<unsigned int>(aa); | |
1317 unsigned int b = static_cast<unsigned int>(bb); | |
1318 unsigned int c = static_cast<unsigned int>(cc); | |
1319 | |
1320 // Check the major version number | |
1321 | |
1322 if (a > major) | |
1323 { | |
1324 return true; | |
1325 } | |
1326 | |
1327 if (a < major) | |
1328 { | |
1329 return false; | |
1330 } | |
1331 | |
1332 | |
1333 // Check the minor version number | |
1334 assert(a == major); | |
1335 | |
1336 if (b > minor) | |
1337 { | |
1338 return true; | |
1339 } | |
1340 | |
1341 if (b < minor) | |
1342 { | |
1343 return false; | |
1344 } | |
1345 | |
1346 // Check the patch level version number | |
1347 assert(a == major && b == minor); | |
1348 | |
1349 if (c >= revision) | |
1350 { | |
1351 return true; | |
1352 } | |
1353 else | |
1354 { | |
1355 return false; | |
1356 } | |
1357 } | |
1358 | |
1359 | |
1360 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) | |
1361 const char* AutodetectMimeType(const std::string& path) | |
1362 { | |
1363 const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str()); | |
1364 | |
1365 if (mime == NULL) | |
1366 { | |
1367 // Should never happen, just for safety | |
1368 return "application/octet-stream"; | |
1369 } | |
1370 else | |
1371 { | |
1372 return mime; | |
1373 } | |
1374 } | |
1375 #endif | 2030 #endif |
1376 | 2031 } |
1377 | |
1378 #if HAS_ORTHANC_PLUGIN_PEERS == 1 | |
1379 size_t OrthancPeers::GetPeerIndex(const std::string& name) const | |
1380 { | |
1381 size_t index; | |
1382 if (LookupName(index, name)) | |
1383 { | |
1384 return index; | |
1385 } | |
1386 else | |
1387 { | |
1388 LogError("Inexistent peer: " + name); | |
1389 ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); | |
1390 } | |
1391 } | |
1392 | |
1393 | |
1394 OrthancPeers::OrthancPeers() : | |
1395 peers_(NULL), | |
1396 timeout_(0) | |
1397 { | |
1398 peers_ = OrthancPluginGetPeers(GetGlobalContext()); | |
1399 | |
1400 if (peers_ == NULL) | |
1401 { | |
1402 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1403 } | |
1404 | |
1405 uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_); | |
1406 | |
1407 for (uint32_t i = 0; i < count; i++) | |
1408 { | |
1409 const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i); | |
1410 if (name == NULL) | |
1411 { | |
1412 OrthancPluginFreePeers(GetGlobalContext(), peers_); | |
1413 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1414 } | |
1415 | |
1416 index_[name] = i; | |
1417 } | |
1418 } | |
1419 | |
1420 | |
1421 OrthancPeers::~OrthancPeers() | |
1422 { | |
1423 if (peers_ != NULL) | |
1424 { | |
1425 OrthancPluginFreePeers(GetGlobalContext(), peers_); | |
1426 } | |
1427 } | |
1428 | |
1429 | |
1430 bool OrthancPeers::LookupName(size_t& target, | |
1431 const std::string& name) const | |
1432 { | |
1433 Index::const_iterator found = index_.find(name); | |
1434 | |
1435 if (found == index_.end()) | |
1436 { | |
1437 return false; | |
1438 } | |
1439 else | |
1440 { | |
1441 target = found->second; | |
1442 return true; | |
1443 } | |
1444 } | |
1445 | |
1446 | |
1447 std::string OrthancPeers::GetPeerName(size_t index) const | |
1448 { | |
1449 if (index >= index_.size()) | |
1450 { | |
1451 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1452 } | |
1453 else | |
1454 { | |
1455 const char* s = OrthancPluginGetPeerName(GetGlobalContext(), peers_, static_cast<uint32_t>(index)); | |
1456 if (s == NULL) | |
1457 { | |
1458 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1459 } | |
1460 else | |
1461 { | |
1462 return s; | |
1463 } | |
1464 } | |
1465 } | |
1466 | |
1467 | |
1468 std::string OrthancPeers::GetPeerUrl(size_t index) const | |
1469 { | |
1470 if (index >= index_.size()) | |
1471 { | |
1472 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1473 } | |
1474 else | |
1475 { | |
1476 const char* s = OrthancPluginGetPeerUrl(GetGlobalContext(), peers_, static_cast<uint32_t>(index)); | |
1477 if (s == NULL) | |
1478 { | |
1479 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1480 } | |
1481 else | |
1482 { | |
1483 return s; | |
1484 } | |
1485 } | |
1486 } | |
1487 | |
1488 | |
1489 std::string OrthancPeers::GetPeerUrl(const std::string& name) const | |
1490 { | |
1491 return GetPeerUrl(GetPeerIndex(name)); | |
1492 } | |
1493 | |
1494 | |
1495 bool OrthancPeers::LookupUserProperty(std::string& value, | |
1496 size_t index, | |
1497 const std::string& key) const | |
1498 { | |
1499 if (index >= index_.size()) | |
1500 { | |
1501 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1502 } | |
1503 else | |
1504 { | |
1505 const char* s = OrthancPluginGetPeerUserProperty(GetGlobalContext(), peers_, static_cast<uint32_t>(index), key.c_str()); | |
1506 if (s == NULL) | |
1507 { | |
1508 return false; | |
1509 } | |
1510 else | |
1511 { | |
1512 value.assign(s); | |
1513 return true; | |
1514 } | |
1515 } | |
1516 } | |
1517 | |
1518 | |
1519 bool OrthancPeers::LookupUserProperty(std::string& value, | |
1520 const std::string& peer, | |
1521 const std::string& key) const | |
1522 { | |
1523 return LookupUserProperty(value, GetPeerIndex(peer), key); | |
1524 } | |
1525 | |
1526 | |
1527 bool OrthancPeers::DoGet(MemoryBuffer& target, | |
1528 size_t index, | |
1529 const std::string& uri) const | |
1530 { | |
1531 if (index >= index_.size()) | |
1532 { | |
1533 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1534 } | |
1535 | |
1536 OrthancPluginMemoryBuffer answer; | |
1537 uint16_t status; | |
1538 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1539 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1540 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Get, uri.c_str(), | |
1541 0, NULL, NULL, NULL, 0, timeout_); | |
1542 | |
1543 if (code == OrthancPluginErrorCode_Success) | |
1544 { | |
1545 target.Assign(answer); | |
1546 return (status == 200); | |
1547 } | |
1548 else | |
1549 { | |
1550 return false; | |
1551 } | |
1552 } | |
1553 | |
1554 | |
1555 bool OrthancPeers::DoGet(MemoryBuffer& target, | |
1556 const std::string& name, | |
1557 const std::string& uri) const | |
1558 { | |
1559 size_t index; | |
1560 return (LookupName(index, name) && | |
1561 DoGet(target, index, uri)); | |
1562 } | |
1563 | |
1564 | |
1565 bool OrthancPeers::DoGet(Json::Value& target, | |
1566 size_t index, | |
1567 const std::string& uri) const | |
1568 { | |
1569 MemoryBuffer buffer; | |
1570 | |
1571 if (DoGet(buffer, index, uri)) | |
1572 { | |
1573 buffer.ToJson(target); | |
1574 return true; | |
1575 } | |
1576 else | |
1577 { | |
1578 return false; | |
1579 } | |
1580 } | |
1581 | |
1582 | |
1583 bool OrthancPeers::DoGet(Json::Value& target, | |
1584 const std::string& name, | |
1585 const std::string& uri) const | |
1586 { | |
1587 MemoryBuffer buffer; | |
1588 | |
1589 if (DoGet(buffer, name, uri)) | |
1590 { | |
1591 buffer.ToJson(target); | |
1592 return true; | |
1593 } | |
1594 else | |
1595 { | |
1596 return false; | |
1597 } | |
1598 } | |
1599 | |
1600 | |
1601 bool OrthancPeers::DoPost(MemoryBuffer& target, | |
1602 const std::string& name, | |
1603 const std::string& uri, | |
1604 const std::string& body) const | |
1605 { | |
1606 size_t index; | |
1607 return (LookupName(index, name) && | |
1608 DoPost(target, index, uri, body)); | |
1609 } | |
1610 | |
1611 | |
1612 bool OrthancPeers::DoPost(Json::Value& target, | |
1613 size_t index, | |
1614 const std::string& uri, | |
1615 const std::string& body) const | |
1616 { | |
1617 MemoryBuffer buffer; | |
1618 | |
1619 if (DoPost(buffer, index, uri, body)) | |
1620 { | |
1621 buffer.ToJson(target); | |
1622 return true; | |
1623 } | |
1624 else | |
1625 { | |
1626 return false; | |
1627 } | |
1628 } | |
1629 | |
1630 | |
1631 bool OrthancPeers::DoPost(Json::Value& target, | |
1632 const std::string& name, | |
1633 const std::string& uri, | |
1634 const std::string& body) const | |
1635 { | |
1636 MemoryBuffer buffer; | |
1637 | |
1638 if (DoPost(buffer, name, uri, body)) | |
1639 { | |
1640 buffer.ToJson(target); | |
1641 return true; | |
1642 } | |
1643 else | |
1644 { | |
1645 return false; | |
1646 } | |
1647 } | |
1648 | |
1649 | |
1650 bool OrthancPeers::DoPost(MemoryBuffer& target, | |
1651 size_t index, | |
1652 const std::string& uri, | |
1653 const std::string& body) const | |
1654 { | |
1655 if (index >= index_.size()) | |
1656 { | |
1657 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1658 } | |
1659 | |
1660 OrthancPluginMemoryBuffer answer; | |
1661 uint16_t status; | |
1662 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1663 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1664 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), | |
1665 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | |
1666 | |
1667 if (code == OrthancPluginErrorCode_Success) | |
1668 { | |
1669 target.Assign(answer); | |
1670 return (status == 200); | |
1671 } | |
1672 else | |
1673 { | |
1674 return false; | |
1675 } | |
1676 } | |
1677 | |
1678 | |
1679 bool OrthancPeers::DoPut(size_t index, | |
1680 const std::string& uri, | |
1681 const std::string& body) const | |
1682 { | |
1683 if (index >= index_.size()) | |
1684 { | |
1685 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1686 } | |
1687 | |
1688 OrthancPluginMemoryBuffer answer; | |
1689 uint16_t status; | |
1690 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1691 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1692 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), | |
1693 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | |
1694 | |
1695 if (code == OrthancPluginErrorCode_Success) | |
1696 { | |
1697 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); | |
1698 return (status == 200); | |
1699 } | |
1700 else | |
1701 { | |
1702 return false; | |
1703 } | |
1704 } | |
1705 | |
1706 | |
1707 bool OrthancPeers::DoPut(const std::string& name, | |
1708 const std::string& uri, | |
1709 const std::string& body) const | |
1710 { | |
1711 size_t index; | |
1712 return (LookupName(index, name) && | |
1713 DoPut(index, uri, body)); | |
1714 } | |
1715 | |
1716 | |
1717 bool OrthancPeers::DoDelete(size_t index, | |
1718 const std::string& uri) const | |
1719 { | |
1720 if (index >= index_.size()) | |
1721 { | |
1722 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1723 } | |
1724 | |
1725 OrthancPluginMemoryBuffer answer; | |
1726 uint16_t status; | |
1727 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | |
1728 (GetGlobalContext(), &answer, NULL, &status, peers_, | |
1729 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), | |
1730 0, NULL, NULL, NULL, 0, timeout_); | |
1731 | |
1732 if (code == OrthancPluginErrorCode_Success) | |
1733 { | |
1734 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &answer); | |
1735 return (status == 200); | |
1736 } | |
1737 else | |
1738 { | |
1739 return false; | |
1740 } | |
1741 } | |
1742 | |
1743 | |
1744 bool OrthancPeers::DoDelete(const std::string& name, | |
1745 const std::string& uri) const | |
1746 { | |
1747 size_t index; | |
1748 return (LookupName(index, name) && | |
1749 DoDelete(index, uri)); | |
1750 } | |
1751 #endif | |
1752 | |
1753 | |
1754 | |
1755 #if HAS_ORTHANC_PLUGIN_JOB == 1 | |
1756 void OrthancJob::CallbackFinalize(void* job) | |
1757 { | |
1758 if (job != NULL) | |
1759 { | |
1760 delete reinterpret_cast<OrthancJob*>(job); | |
1761 } | |
1762 } | |
1763 | |
1764 | |
1765 float OrthancJob::CallbackGetProgress(void* job) | |
1766 { | |
1767 assert(job != NULL); | |
1768 | |
1769 try | |
1770 { | |
1771 return reinterpret_cast<OrthancJob*>(job)->progress_; | |
1772 } | |
1773 catch (...) | |
1774 { | |
1775 return 0; | |
1776 } | |
1777 } | |
1778 | |
1779 | |
1780 const char* OrthancJob::CallbackGetContent(void* job) | |
1781 { | |
1782 assert(job != NULL); | |
1783 | |
1784 try | |
1785 { | |
1786 return reinterpret_cast<OrthancJob*>(job)->content_.c_str(); | |
1787 } | |
1788 catch (...) | |
1789 { | |
1790 return 0; | |
1791 } | |
1792 } | |
1793 | |
1794 | |
1795 const char* OrthancJob::CallbackGetSerialized(void* job) | |
1796 { | |
1797 assert(job != NULL); | |
1798 | |
1799 try | |
1800 { | |
1801 const OrthancJob& tmp = *reinterpret_cast<OrthancJob*>(job); | |
1802 | |
1803 if (tmp.hasSerialized_) | |
1804 { | |
1805 return tmp.serialized_.c_str(); | |
1806 } | |
1807 else | |
1808 { | |
1809 return NULL; | |
1810 } | |
1811 } | |
1812 catch (...) | |
1813 { | |
1814 return 0; | |
1815 } | |
1816 } | |
1817 | |
1818 | |
1819 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) | |
1820 { | |
1821 assert(job != NULL); | |
1822 | |
1823 try | |
1824 { | |
1825 return reinterpret_cast<OrthancJob*>(job)->Step(); | |
1826 } | |
1827 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&) | |
1828 { | |
1829 return OrthancPluginJobStepStatus_Failure; | |
1830 } | |
1831 catch (...) | |
1832 { | |
1833 return OrthancPluginJobStepStatus_Failure; | |
1834 } | |
1835 } | |
1836 | |
1837 | |
1838 OrthancPluginErrorCode OrthancJob::CallbackStop(void* job, | |
1839 OrthancPluginJobStopReason reason) | |
1840 { | |
1841 assert(job != NULL); | |
1842 | |
1843 try | |
1844 { | |
1845 reinterpret_cast<OrthancJob*>(job)->Stop(reason); | |
1846 return OrthancPluginErrorCode_Success; | |
1847 } | |
1848 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
1849 { | |
1850 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1851 } | |
1852 catch (...) | |
1853 { | |
1854 return OrthancPluginErrorCode_Plugin; | |
1855 } | |
1856 } | |
1857 | |
1858 | |
1859 OrthancPluginErrorCode OrthancJob::CallbackReset(void* job) | |
1860 { | |
1861 assert(job != NULL); | |
1862 | |
1863 try | |
1864 { | |
1865 reinterpret_cast<OrthancJob*>(job)->Reset(); | |
1866 return OrthancPluginErrorCode_Success; | |
1867 } | |
1868 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
1869 { | |
1870 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
1871 } | |
1872 catch (...) | |
1873 { | |
1874 return OrthancPluginErrorCode_Plugin; | |
1875 } | |
1876 } | |
1877 | |
1878 | |
1879 void OrthancJob::ClearContent() | |
1880 { | |
1881 Json::Value empty = Json::objectValue; | |
1882 UpdateContent(empty); | |
1883 } | |
1884 | |
1885 | |
1886 void OrthancJob::UpdateContent(const Json::Value& content) | |
1887 { | |
1888 if (content.type() != Json::objectValue) | |
1889 { | |
1890 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); | |
1891 } | |
1892 else | |
1893 { | |
1894 Json::FastWriter writer; | |
1895 content_ = writer.write(content); | |
1896 } | |
1897 } | |
1898 | |
1899 | |
1900 void OrthancJob::ClearSerialized() | |
1901 { | |
1902 hasSerialized_ = false; | |
1903 serialized_.clear(); | |
1904 } | |
1905 | |
1906 | |
1907 void OrthancJob::UpdateSerialized(const Json::Value& serialized) | |
1908 { | |
1909 if (serialized.type() != Json::objectValue) | |
1910 { | |
1911 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); | |
1912 } | |
1913 else | |
1914 { | |
1915 Json::FastWriter writer; | |
1916 serialized_ = writer.write(serialized); | |
1917 hasSerialized_ = true; | |
1918 } | |
1919 } | |
1920 | |
1921 | |
1922 void OrthancJob::UpdateProgress(float progress) | |
1923 { | |
1924 if (progress < 0 || | |
1925 progress > 1) | |
1926 { | |
1927 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | |
1928 } | |
1929 | |
1930 progress_ = progress; | |
1931 } | |
1932 | |
1933 | |
1934 OrthancJob::OrthancJob(const std::string& jobType) : | |
1935 jobType_(jobType), | |
1936 progress_(0) | |
1937 { | |
1938 ClearContent(); | |
1939 ClearSerialized(); | |
1940 } | |
1941 | |
1942 | |
1943 OrthancPluginJob* OrthancJob::Create(OrthancJob* job) | |
1944 { | |
1945 if (job == NULL) | |
1946 { | |
1947 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); | |
1948 } | |
1949 | |
1950 OrthancPluginJob* orthanc = OrthancPluginCreateJob( | |
1951 GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), | |
1952 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, | |
1953 CallbackStep, CallbackStop, CallbackReset); | |
1954 | |
1955 if (orthanc == NULL) | |
1956 { | |
1957 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1958 } | |
1959 else | |
1960 { | |
1961 return orthanc; | |
1962 } | |
1963 } | |
1964 | |
1965 | |
1966 std::string OrthancJob::Submit(OrthancJob* job, | |
1967 int priority) | |
1968 { | |
1969 OrthancPluginJob* orthanc = Create(job); | |
1970 | |
1971 char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority); | |
1972 | |
1973 if (id == NULL) | |
1974 { | |
1975 LogError("Plugin cannot submit job"); | |
1976 OrthancPluginFreeJob(GetGlobalContext(), orthanc); | |
1977 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | |
1978 } | |
1979 else | |
1980 { | |
1981 std::string tmp(id); | |
1982 tmp.assign(id); | |
1983 OrthancPluginFreeString(GetGlobalContext(), id); | |
1984 | |
1985 return tmp; | |
1986 } | |
1987 } | |
1988 #endif | |
1989 } |