comparison Plugins/Samples/Common/OrthancPluginCppWrapper.cpp @ 3028:ff65c925f57a

fix indentation
author am@osimis.io
date Tue, 18 Dec 2018 14:37:53 +0100
parents c358bdb37c13
children 0293cb3d8a37
comparison
equal deleted inserted replaced
3026:c358bdb37c13 3028:ff65c925f57a
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 { 48 {
49 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); 49 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer);
50 } 50 }
51 else if (globalContext_ == NULL) 51 else if (globalContext_ == NULL)
52 { 52 {
53 globalContext_ = context; 53 globalContext_ = context;
54 } 54 }
55 else 55 else
56 { 56 {
57 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); 57 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls);
58 } 58 }
59 } 59 }
60 60
61 61
62 bool HasGlobalContext() 62 bool HasGlobalContext()
63 { 63 {
64 return globalContext_ != NULL; 64 return globalContext_ != NULL;
65 } 65 }
66 66
67 67
68 OrthancPluginContext* GetGlobalContext() 68 OrthancPluginContext* GetGlobalContext()
69 { 69 {
70 if (globalContext_ == NULL) 70 if (globalContext_ == NULL)
71 { 71 {
72 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); 72 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls);
73 } 73 }
74 else 74 else
75 { 75 {
76 return globalContext_; 76 return globalContext_;
77 } 77 }
78 } 78 }
79 79
80 80
81 void MemoryBuffer::Check(OrthancPluginErrorCode code) 81 void MemoryBuffer::Check(OrthancPluginErrorCode code)
82 { 82 {
83 if (code != OrthancPluginErrorCode_Success) 83 if (code != OrthancPluginErrorCode_Success)
84 { 84 {
85 // Prevent using garbage information 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 {
86 buffer_.data = NULL; 120 buffer_.data = NULL;
87 buffer_.size = 0; 121 buffer_.size = 0;
88 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); 122 }
89 } 123
90 } 124
91 125 void MemoryBuffer::Clear()
92 126 {
93 bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code) 127 if (buffer_.data != NULL)
94 { 128 {
95 if (code != OrthancPluginErrorCode_Success) 129 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_);
96 { 130 buffer_.data = NULL;
97 // Prevent using garbage information 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
98 buffer_.data = NULL; 152 buffer_.data = NULL;
99 buffer_.size = 0; 153 buffer_.size = 0;
100 } 154
101 155 return result;
102 if (code == OrthancPluginErrorCode_Success) 156 }
103 { 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)
535 {
536 LogError("The configuration section \"" + target.path_ +
537 "\" is not an associative array as expected");
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();
104 return true; 566 return true;
105 } 567 }
106 else if (code == OrthancPluginErrorCode_UnknownResource || 568
107 code == OrthancPluginErrorCode_InexistentItem) 569
108 { 570 bool OrthancConfiguration::LookupIntegerValue(int& target,
109 return false; 571 const std::string& key) const
110 } 572 {
111 else 573 assert(configuration_.type() == Json::objectValue);
112 { 574
113 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); 575 if (!configuration_.isMember(key))
114 } 576 {
115 } 577 return false;
116 578 }
117 579
118 MemoryBuffer::MemoryBuffer() 580 switch (configuration_[key].type())
119 { 581 {
120 buffer_.data = NULL; 582 case Json::intValue:
121 buffer_.size = 0; 583 target = configuration_[key].asInt();
122 } 584 return true;
123 585
124 586 case Json::uintValue:
125 void MemoryBuffer::Clear() 587 target = configuration_[key].asUInt();
126 { 588 return true;
127 if (buffer_.data != NULL) 589
128 { 590 default:
129 OrthancPluginFreeMemoryBuffer(GetGlobalContext(), &buffer_); 591 LogError("The configuration option \"" + GetPath(key) +
130 buffer_.data = NULL; 592 "\" is not an integer as expected");
131 buffer_.size = 0; 593
132 } 594 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
133 } 595 }
134 596 }
135 597
136 void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other) 598
137 { 599 bool OrthancConfiguration::LookupUnsignedIntegerValue(unsigned int& target,
138 Clear(); 600 const std::string& key) const
139 601 {
140 buffer_.data = other.data; 602 int tmp;
141 buffer_.size = other.size; 603 if (!LookupIntegerValue(tmp, key))
142 604 {
143 other.data = NULL; 605 return false;
144 other.size = 0; 606 }
145 } 607
146 608 if (tmp < 0)
147 609 {
148 OrthancPluginMemoryBuffer MemoryBuffer::Release() 610 LogError("The configuration option \"" + GetPath(key) +
149 { 611 "\" is not a positive integer as expected");
150 OrthancPluginMemoryBuffer result = buffer_; 612
151 613 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
152 buffer_.data = NULL; 614 }
153 buffer_.size = 0; 615 else
154 616 {
155 return result; 617 target = static_cast<unsigned int>(tmp);
156 } 618 return true;
157 619 }
158 620 }
159 void MemoryBuffer::ToString(std::string& target) const 621
160 { 622
161 if (buffer_.size == 0) 623 bool OrthancConfiguration::LookupBooleanValue(bool& target,
162 { 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
163 target.clear(); 685 target.clear();
164 } 686
165 else 687 if (!configuration_.isMember(key))
166 { 688 {
167 target.assign(reinterpret_cast<const char*>(buffer_.data), buffer_.size); 689 return false;
168 } 690 }
169 } 691
170 692 switch (configuration_[key].type())
171 693 {
172 void MemoryBuffer::ToJson(Json::Value& target) const 694 case Json::arrayValue:
173 { 695 {
174 if (buffer_.data == NULL || 696 bool ok = true;
175 buffer_.size == 0) 697
176 { 698 for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++)
177 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 699 {
178 } 700 if (configuration_[key][i].type() == Json::stringValue)
179 701 {
180 const char* tmp = reinterpret_cast<const char*>(buffer_.data); 702 target.push_back(configuration_[key][i].asString());
181 703 }
182 Json::Reader reader; 704 else
183 if (!reader.parse(tmp, tmp + buffer_.size, target)) 705 {
184 { 706 ok = false;
185 LogError("Cannot convert some memory buffer to JSON"); 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
186 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 734 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
187 } 735 }
188 } 736
189 737
190 738 bool OrthancConfiguration::LookupSetOfStrings(std::set<std::string>& target,
191 bool MemoryBuffer::RestApiGet(const std::string& uri, 739 const std::string& key,
192 bool applyPlugins) 740 bool allowSingleString) const
193 { 741 {
194 Clear(); 742 std::list<std::string> lst;
195 743
196 if (applyPlugins) 744 if (LookupListOfStrings(lst, key, allowSingleString))
197 { 745 {
198 return CheckHttp(OrthancPluginRestApiGetAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str())); 746 target.clear();
199 } 747
200 else 748 for (std::list<std::string>::const_iterator
201 { 749 it = lst.begin(); it != lst.end(); ++it)
202 return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); 750 {
203 } 751 target.insert(*it);
204 } 752 }
205 753
206 bool MemoryBuffer::RestApiGet(const std::string& uri, 754 return true;
207 const std::map<std::string, std::string>& httpHeaders, 755 }
208 bool applyPlugins) 756 else
209 { 757 {
210 Clear(); 758 return false;
211 759 }
212 std::vector<const char*> headersKeys; 760 }
213 std::vector<const char*> headersValues; 761
214 for (std::map<std::string, std::string>::const_iterator it = httpHeaders.begin(); it != httpHeaders.end(); it++) 762
215 { 763 std::string OrthancConfiguration::GetStringValue(const std::string& key,
216 headersKeys.push_back(it->first.c_str()); 764 const std::string& defaultValue) const
217 headersValues.push_back(it->second.c_str()); 765 {
218 } 766 std::string tmp;
219 767 if (LookupStringValue(tmp, key))
220 return CheckHttp(OrthancPluginRestApiGet2(GetGlobalContext(), &buffer_, uri.c_str(), httpHeaders.size(), headersKeys.data(), headersValues.data(), applyPlugins)); 768 {
221 } 769 return tmp;
222 770 }
223 bool MemoryBuffer::RestApiPost(const std::string& uri, 771 else
224 const char* body, 772 {
225 size_t bodySize, 773 return defaultValue;
226 bool applyPlugins) 774 }
227 { 775 }
228 Clear(); 776
229 777
230 if (applyPlugins) 778 int OrthancConfiguration::GetIntegerValue(const std::string& key,
231 { 779 int defaultValue) const
232 return CheckHttp(OrthancPluginRestApiPostAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); 780 {
233 } 781 int tmp;
234 else 782 if (LookupIntegerValue(tmp, key))
235 { 783 {
236 return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); 784 return tmp;
237 } 785 }
238 } 786 else
239 787 {
240 788 return defaultValue;
241 bool MemoryBuffer::RestApiPut(const std::string& uri, 789 }
242 const char* body, 790 }
243 size_t bodySize, 791
244 bool applyPlugins) 792
245 { 793 unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key,
246 Clear(); 794 unsigned int defaultValue) const
247 795 {
248 if (applyPlugins) 796 unsigned int tmp;
249 { 797 if (LookupUnsignedIntegerValue(tmp, key))
250 return CheckHttp(OrthancPluginRestApiPutAfterPlugins(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); 798 {
251 } 799 return tmp;
252 else 800 }
253 { 801 else
254 return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), body, bodySize)); 802 {
255 } 803 return defaultValue;
256 } 804 }
257 805 }
258 806
259 bool MemoryBuffer::RestApiPost(const std::string& uri, 807
260 const Json::Value& body, 808 bool OrthancConfiguration::GetBooleanValue(const std::string& key,
261 bool applyPlugins) 809 bool defaultValue) const
262 { 810 {
263 Json::FastWriter writer; 811 bool tmp;
264 return RestApiPost(uri, writer.write(body), applyPlugins); 812 if (LookupBooleanValue(tmp, key))
265 } 813 {
266 814 return tmp;
267 815 }
268 bool MemoryBuffer::RestApiPut(const std::string& uri, 816 else
269 const Json::Value& body, 817 {
270 bool applyPlugins) 818 return defaultValue;
271 { 819 }
272 Json::FastWriter writer; 820 }
273 return RestApiPut(uri, writer.write(body), applyPlugins); 821
274 } 822
275 823 float OrthancConfiguration::GetFloatValue(const std::string& key,
276 824 float defaultValue) const
277 void MemoryBuffer::CreateDicom(const Json::Value& tags, 825 {
278 OrthancPluginCreateDicomFlags flags) 826 float tmp;
279 { 827 if (LookupFloatValue(tmp, key))
280 Clear(); 828 {
281 829 return tmp;
282 Json::FastWriter writer; 830 }
283 std::string s = writer.write(tags); 831 else
284 832 {
285 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); 833 return defaultValue;
286 } 834 }
287 835 }
288 void MemoryBuffer::CreateDicom(const Json::Value& tags, 836
289 const OrthancImage& pixelData, 837
290 OrthancPluginCreateDicomFlags flags) 838 void OrthancConfiguration::GetDictionary(std::map<std::string, std::string>& target,
291 { 839 const std::string& key) const
292 Clear(); 840 {
293 841 assert(configuration_.type() == Json::objectValue);
294 Json::FastWriter writer; 842
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(); 843 target.clear();
344 } 844
345 else 845 if (!configuration_.isMember(key))
346 { 846 {
347 target.assign(str_); 847 return;
348 } 848 }
349 } 849
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) 850 if (configuration_[key].type() != Json::objectValue)
535 { 851 {
536 LogError("The configuration section \"" + target.path_ + 852 LogError("The configuration option \"" + GetPath(key) +
537 "\" is not an associative array as expected"); 853 "\" is not a string as expected");
538 854
539 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 855 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
540 } 856 }
541 857
542 target.configuration_ = configuration_[key]; 858 Json::Value::Members members = configuration_[key].getMemberNames();
543 } 859
544 } 860 for (size_t i = 0; i < members.size(); i++)
545 861 {
546 862 const Json::Value& value = configuration_[key][members[i]];
547 bool OrthancConfiguration::LookupStringValue(std::string& target, 863
548 const std::string& key) const 864 if (value.type() == Json::stringValue)
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++)
699 {
700 if (configuration_[key][i].type() == Json::stringValue)
701 { 865 {
702 target.push_back(configuration_[key][i].asString()); 866 target[members[i]] = value.asString();
703 } 867 }
704 else 868 else
705 { 869 {
706 ok = false; 870 LogError("The configuration option \"" + GetPath(key) +
871 "\" is not a dictionary mapping strings to strings");
872
873 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
707 } 874 }
708 } 875 }
709 876 }
710 if (ok) 877
711 { 878
712 return true; 879 void OrthancImage::Clear()
713 } 880 {
714 881 if (image_ != NULL)
715 break; 882 {
716 } 883 OrthancPluginFreeImage(GetGlobalContext(), image_);
717 884 image_ = NULL;
718 case Json::stringValue: 885 }
719 if (allowSingleString) 886 }
720 { 887
721 target.push_back(configuration_[key].asString()); 888
722 return true; 889 void OrthancImage::CheckImageAvailable()
723 } 890 {
724 891 if (image_ == NULL)
725 break; 892 {
726 893 LogError("Trying to access a NULL image");
727 default: 894 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
728 break; 895 }
729 } 896 }
730 897
731 LogError("The configuration option \"" + GetPath(key) + 898
732 "\" is not a list of strings as expected"); 899 OrthancImage::OrthancImage() :
733 900 image_(NULL)
734 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 901 {
735 } 902 }
736 903
737 904
738 bool OrthancConfiguration::LookupSetOfStrings(std::set<std::string>& target, 905 OrthancImage::OrthancImage(OrthancPluginImage* image) :
739 const std::string& key, 906 image_(image)
740 bool allowSingleString) const 907 {
741 { 908 }
742 std::list<std::string> lst; 909
743 910
744 if (LookupListOfStrings(lst, key, allowSingleString)) 911 OrthancImage::OrthancImage(OrthancPluginPixelFormat format,
745 { 912 uint32_t width,
746 target.clear(); 913 uint32_t height)
747 914 {
748 for (std::list<std::string>::const_iterator 915 image_ = OrthancPluginCreateImage(GetGlobalContext(), format, width, height);
749 it = lst.begin(); it != lst.end(); ++it) 916
750 { 917 if (image_ == NULL)
751 target.insert(*it); 918 {
752 } 919 LogError("Cannot create an image");
753 920 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
754 return true; 921 }
755 } 922 }
756 else 923
757 { 924
758 return false; 925 OrthancImage::OrthancImage(OrthancPluginPixelFormat format,
759 } 926 uint32_t width,
760 } 927 uint32_t height,
761 928 uint32_t pitch,
762 929 void* buffer)
763 std::string OrthancConfiguration::GetStringValue(const std::string& key, 930 {
764 const std::string& defaultValue) const 931 image_ = OrthancPluginCreateImageAccessor
765 { 932 (GetGlobalContext(), format, width, height, pitch, buffer);
766 std::string tmp; 933
767 if (LookupStringValue(tmp, key)) 934 if (image_ == NULL)
768 { 935 {
769 return tmp; 936 LogError("Cannot create an image accessor");
770 } 937 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
771 else 938 }
772 { 939 }
773 return defaultValue; 940
774 } 941 void OrthancImage::UncompressPngImage(const void* data,
775 } 942 size_t size)
776 943 {
777 944 Clear();
778 int OrthancConfiguration::GetIntegerValue(const std::string& key, 945
779 int defaultValue) const 946 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Png);
780 { 947
781 int tmp; 948 if (image_ == NULL)
782 if (LookupIntegerValue(tmp, key)) 949 {
783 { 950 LogError("Cannot uncompress a PNG image");
784 return tmp; 951 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
785 } 952 }
786 else 953 }
787 { 954
788 return defaultValue; 955
789 } 956 void OrthancImage::UncompressJpegImage(const void* data,
790 } 957 size_t size)
791 958 {
792 959 Clear();
793 unsigned int OrthancConfiguration::GetUnsignedIntegerValue(const std::string& key, 960 image_ = OrthancPluginUncompressImage(GetGlobalContext(), data, size, OrthancPluginImageFormat_Jpeg);
794 unsigned int defaultValue) const 961 if (image_ == NULL)
795 { 962 {
796 unsigned int tmp; 963 LogError("Cannot uncompress a JPEG image");
797 if (LookupUnsignedIntegerValue(tmp, key)) 964 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
798 { 965 }
799 return tmp; 966 }
800 } 967
801 else 968
802 { 969 void OrthancImage::DecodeDicomImage(const void* data,
803 return defaultValue; 970 size_t size,
804 } 971 unsigned int frame)
805 } 972 {
806 973 Clear();
807 974 image_ = OrthancPluginDecodeDicomImage(GetGlobalContext(), data, size, frame);
808 bool OrthancConfiguration::GetBooleanValue(const std::string& key, 975 if (image_ == NULL)
809 bool defaultValue) const 976 {
810 { 977 LogError("Cannot uncompress a DICOM image");
811 bool tmp; 978 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
812 if (LookupBooleanValue(tmp, key)) 979 }
813 { 980 }
814 return tmp; 981
815 } 982
816 else 983 OrthancPluginPixelFormat OrthancImage::GetPixelFormat()
817 { 984 {
818 return defaultValue; 985 CheckImageAvailable();
819 } 986 return OrthancPluginGetImagePixelFormat(GetGlobalContext(), image_);
820 } 987 }
821 988
822 989
823 float OrthancConfiguration::GetFloatValue(const std::string& key, 990 unsigned int OrthancImage::GetWidth()
824 float defaultValue) const 991 {
825 { 992 CheckImageAvailable();
826 float tmp; 993 return OrthancPluginGetImageWidth(GetGlobalContext(), image_);
827 if (LookupFloatValue(tmp, key)) 994 }
828 { 995
829 return tmp; 996
830 } 997 unsigned int OrthancImage::GetHeight()
831 else 998 {
832 { 999 CheckImageAvailable();
833 return defaultValue; 1000 return OrthancPluginGetImageHeight(GetGlobalContext(), image_);
834 } 1001 }
835 } 1002
836 1003
837 1004 unsigned int OrthancImage::GetPitch()
838 void OrthancConfiguration::GetDictionary(std::map<std::string, std::string>& target, 1005 {
839 const std::string& key) const 1006 CheckImageAvailable();
840 { 1007 return OrthancPluginGetImagePitch(GetGlobalContext(), image_);
841 assert(configuration_.type() == Json::objectValue); 1008 }
842 1009
843 target.clear(); 1010
844 1011 const void* OrthancImage::GetBuffer()
845 if (!configuration_.isMember(key)) 1012 {
846 { 1013 CheckImageAvailable();
847 return; 1014 return OrthancPluginGetImageBuffer(GetGlobalContext(), image_);
848 } 1015 }
849 1016
850 if (configuration_[key].type() != Json::objectValue) 1017
851 { 1018 void OrthancImage::CompressPngImage(MemoryBuffer& target)
852 LogError("The configuration option \"" + GetPath(key) + 1019 {
853 "\" is not a string as expected"); 1020 CheckImageAvailable();
854 1021
855 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 1022 OrthancPluginMemoryBuffer tmp;
856 } 1023 OrthancPluginCompressPngImage(GetGlobalContext(), &tmp, GetPixelFormat(),
857 1024 GetWidth(), GetHeight(), GetPitch(), GetBuffer());
858 Json::Value::Members members = configuration_[key].getMemberNames(); 1025
859 1026 target.Assign(tmp);
860 for (size_t i = 0; i < members.size(); i++) 1027 }
861 { 1028
862 const Json::Value& value = configuration_[key][members[i]]; 1029
863 1030 void OrthancImage::CompressJpegImage(MemoryBuffer& target,
864 if (value.type() == Json::stringValue) 1031 uint8_t quality)
865 { 1032 {
866 target[members[i]] = value.asString(); 1033 CheckImageAvailable();
867 } 1034
868 else 1035 OrthancPluginMemoryBuffer tmp;
869 { 1036 OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(),
870 LogError("The configuration option \"" + GetPath(key) + 1037 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality);
871 "\" is not a dictionary mapping strings to strings"); 1038
872 1039 target.Assign(tmp);
873 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 1040 }
874 } 1041
875 } 1042
876 } 1043 void OrthancImage::AnswerPngImage(OrthancPluginRestOutput* output)
877 1044 {
878 1045 CheckImageAvailable();
879 void OrthancImage::Clear() 1046 OrthancPluginCompressAndAnswerPngImage(GetGlobalContext(), output, GetPixelFormat(),
880 { 1047 GetWidth(), GetHeight(), GetPitch(), GetBuffer());
881 if (image_ != NULL) 1048 }
882 { 1049
883 OrthancPluginFreeImage(GetGlobalContext(), image_); 1050
884 image_ = NULL; 1051 void OrthancImage::AnswerJpegImage(OrthancPluginRestOutput* output,
885 }
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) 1052 uint8_t quality)
1032 { 1053 {
1033 CheckImageAvailable(); 1054 CheckImageAvailable();
1034 1055 OrthancPluginCompressAndAnswerJpegImage(GetGlobalContext(), output, GetPixelFormat(),
1035 OrthancPluginMemoryBuffer tmp; 1056 GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality);
1036 OrthancPluginCompressJpegImage(GetGlobalContext(), &tmp, GetPixelFormat(), 1057 }
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 1058
1059 1059
1060 1060
1061 #if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 1061 #if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1
1062 FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) : 1062 FindMatcher::FindMatcher(const OrthancPluginWorklistQuery* worklist) :
1063 matcher_(NULL), 1063 matcher_(NULL),
1064 worklist_(worklist) 1064 worklist_(worklist)
1065 { 1065 {
1066 if (worklist_ == NULL) 1066 if (worklist_ == NULL)
1067 { 1067 {
1068 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); 1068 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
1069 } 1069 }
1070 } 1070 }
1071 1071
1072 1072
1073 void FindMatcher::SetupDicom(const void* query, 1073 void FindMatcher::SetupDicom(const void* query,
1074 uint32_t size) 1074 uint32_t size)
1075 { 1075 {
1076 worklist_ = NULL; 1076 worklist_ = NULL;
1077 1077
1078 matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size); 1078 matcher_ = OrthancPluginCreateFindMatcher(GetGlobalContext(), query, size);
1079 if (matcher_ == NULL) 1079 if (matcher_ == NULL)
1080 { 1080 {
1081 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 1081 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
1082 } 1082 }
1083 } 1083 }
1084 1084
1085 1085
1086 FindMatcher::~FindMatcher() 1086 FindMatcher::~FindMatcher()
1087 { 1087 {
1088 // The "worklist_" field 1088 // The "worklist_" field
1089 1089
1090 if (matcher_ != NULL) 1090 if (matcher_ != NULL)
1091 { 1091 {
1092 OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_); 1092 OrthancPluginFreeFindMatcher(GetGlobalContext(), matcher_);
1093 } 1093 }
1094 } 1094 }
1095 1095
1096 1096
1097 1097
1098 bool FindMatcher::IsMatch(const void* dicom, 1098 bool FindMatcher::IsMatch(const void* dicom,
1099 uint32_t size) const 1099 uint32_t size) const
1100 { 1100 {
1101 int32_t result; 1101 int32_t result;
1102 1102
1103 if (matcher_ != NULL) 1103 if (matcher_ != NULL)
1104 { 1104 {
1105 result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size); 1105 result = OrthancPluginFindMatcherIsMatch(GetGlobalContext(), matcher_, dicom, size);
1106 } 1106 }
1107 else if (worklist_ != NULL) 1107 else if (worklist_ != NULL)
1108 { 1108 {
1109 result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size); 1109 result = OrthancPluginWorklistIsMatch(GetGlobalContext(), worklist_, dicom, size);
1110 } 1110 }
1111 else 1111 else
1112 { 1112 {
1113 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 1113 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
1114 } 1114 }
1115 1115
1116 if (result == 0) 1116 if (result == 0)
1117 { 1117 {
1118 return false; 1118 return false;
1119 } 1119 }
1120 else if (result == 1) 1120 else if (result == 1)
1121 { 1121 {
1122 return true; 1122 return true;
1123 } 1123 }
1124 else 1124 else
1125 { 1125 {
1126 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 1126 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
1127 } 1127 }
1128 } 1128 }
1129 1129
1130 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ 1130 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */
1131 1131
1132 void AnswerJson(const Json::Value& value, 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 1133 OrthancPluginRestOutput* output
1145 ) 1134 )
1146 { 1135 {
1147 OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType); 1136 Json::StyledWriter writer;
1148 } 1137 std::string bodyString = writer.write(value);
1149 1138
1150 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) 1139 OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json");
1151 { 1140 }
1152 OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError); 1141
1153 } 1142 void AnswerString(const std::string& answer,
1154 1143 const char* mimeType,
1155 void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods) 1144 OrthancPluginRestOutput* output
1156 { 1145 )
1157 OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods); 1146 {
1158 } 1147 OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType);
1159 1148 }
1160 bool RestApiGetString(std::string& result, 1149
1161 const std::string& uri, 1150 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output)
1162 bool applyPlugins) 1151 {
1163 { 1152 OrthancPluginSendHttpStatusCode(GetGlobalContext(), output, httpError);
1164 MemoryBuffer answer; 1153 }
1165 if (!answer.RestApiGet(uri, applyPlugins)) 1154
1166 { 1155 void AnswerMethodNotAllowed(OrthancPluginRestOutput *output, const char* allowedMethods)
1167 return false; 1156 {
1168 } 1157 OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowedMethods);
1169 else 1158 }
1170 { 1159
1171 answer.ToString(result); 1160 bool RestApiGetString(std::string& result,
1172 return true; 1161 const std::string& uri,
1173 } 1162 bool applyPlugins)
1174 } 1163 {
1175 1164 MemoryBuffer answer;
1176 bool RestApiGetString(std::string& result, 1165 if (!answer.RestApiGet(uri, applyPlugins))
1177 const std::string& uri, 1166 {
1178 const std::map<std::string, std::string>& httpHeaders, 1167 return false;
1179 bool applyPlugins) 1168 }
1180 { 1169 else
1181 MemoryBuffer answer; 1170 {
1182 if (!answer.RestApiGet(uri, httpHeaders, applyPlugins)) 1171 answer.ToString(result);
1183 { 1172 return true;
1184 return false; 1173 }
1185 } 1174 }
1186 else 1175
1187 { 1176 bool RestApiGetString(std::string& result,
1188 answer.ToString(result); 1177 const std::string& uri,
1189 return true; 1178 const std::map<std::string, std::string>& httpHeaders,
1190 } 1179 bool applyPlugins)
1191 } 1180 {
1192 1181 MemoryBuffer answer;
1193 1182 if (!answer.RestApiGet(uri, httpHeaders, applyPlugins))
1194 1183 {
1195 bool RestApiGet(Json::Value& result, 1184 return false;
1196 const std::string& uri, 1185 }
1197 bool applyPlugins) 1186 else
1198 { 1187 {
1199 MemoryBuffer answer; 1188 answer.ToString(result);
1200 1189 return true;
1201 if (!answer.RestApiGet(uri, applyPlugins)) 1190 }
1202 { 1191 }
1203 return false; 1192
1204 } 1193
1205 else 1194
1206 { 1195 bool RestApiGet(Json::Value& result,
1207 if (!answer.IsEmpty()) 1196 const std::string& uri,
1208 { 1197 bool applyPlugins)
1209 answer.ToJson(result); 1198 {
1210 } 1199 MemoryBuffer answer;
1211 return true; 1200
1212 } 1201 if (!answer.RestApiGet(uri, applyPlugins))
1213 } 1202 {
1214 1203 return false;
1215 1204 }
1216 bool RestApiPost(Json::Value& result, 1205 else
1217 const std::string& uri, 1206 {
1218 const char* body, 1207 if (!answer.IsEmpty())
1219 size_t bodySize, 1208 {
1220 bool applyPlugins) 1209 answer.ToJson(result);
1221 { 1210 }
1222 MemoryBuffer answer; 1211 return true;
1223 1212 }
1224 if (!answer.RestApiPost(uri, body, bodySize, applyPlugins)) 1213 }
1225 { 1214
1226 return false; 1215
1227 } 1216 bool RestApiPost(Json::Value& result,
1228 else 1217 const std::string& uri,
1229 { 1218 const char* body,
1230 if (!answer.IsEmpty()) 1219 size_t bodySize,
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) 1220 bool applyPlugins)
1284 { 1221 {
1285 OrthancPluginErrorCode error; 1222 MemoryBuffer answer;
1286 1223
1287 if (applyPlugins) 1224 if (!answer.RestApiPost(uri, body, bodySize, applyPlugins))
1288 { 1225 {
1289 error = OrthancPluginRestApiDeleteAfterPlugins(GetGlobalContext(), uri.c_str()); 1226 return false;
1290 } 1227 }
1291 else 1228 else
1292 { 1229 {
1293 error = OrthancPluginRestApiDelete(GetGlobalContext(), uri.c_str()); 1230 if (!answer.IsEmpty())
1294 } 1231 {
1295 1232 answer.ToJson(result);
1296 if (error == OrthancPluginErrorCode_Success) 1233 }
1297 { 1234 return true;
1298 return true; 1235 }
1299 } 1236 }
1300 else if (error == OrthancPluginErrorCode_UnknownResource || 1237
1301 error == OrthancPluginErrorCode_InexistentItem) 1238
1302 { 1239 bool RestApiPost(Json::Value& result,
1303 return false; 1240 const std::string& uri,
1304 } 1241 const Json::Value& body,
1305 else 1242 bool applyPlugins)
1306 { 1243 {
1307 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error); 1244 Json::FastWriter writer;
1308 } 1245 return RestApiPost(result, uri, writer.write(body), applyPlugins);
1309 } 1246 }
1310 1247
1311 1248
1312 void ReportMinimalOrthancVersion(unsigned int major, 1249 bool RestApiPut(Json::Value& result,
1313 unsigned int minor, 1250 const std::string& uri,
1314 unsigned int revision) 1251 const char* body,
1315 { 1252 size_t bodySize,
1316 LogError("Your version of the Orthanc core (" + 1253 bool applyPlugins)
1317 std::string(GetGlobalContext()->orthancVersion) + 1254 {
1318 ") is too old to run this plugin (version " + 1255 MemoryBuffer answer;
1319 boost::lexical_cast<std::string>(major) + "." + 1256
1320 boost::lexical_cast<std::string>(minor) + "." + 1257 if (!answer.RestApiPut(uri, body, bodySize, applyPlugins))
1321 boost::lexical_cast<std::string>(revision) + 1258 {
1322 " is required)"); 1259 return false;
1323 } 1260 }
1324 1261 else
1325 1262 {
1326 bool CheckMinimalOrthancVersion(unsigned int major, 1263 if (!answer.IsEmpty()) // i.e, on a PUT to metadata/..., orthand returns an empty response
1327 unsigned int minor, 1264 {
1328 unsigned int revision) 1265 answer.ToJson(result);
1329 { 1266 }
1330 if (!HasGlobalContext()) 1267 return true;
1331 { 1268 }
1332 LogError("Bad Orthanc context in the plugin"); 1269 }
1333 return false; 1270
1334 } 1271
1335 1272 bool RestApiPut(Json::Value& result,
1336 if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) 1273 const std::string& uri,
1337 { 1274 const Json::Value& body,
1338 // Assume compatibility with the mainline 1275 bool applyPlugins)
1339 return true; 1276 {
1340 } 1277 Json::FastWriter writer;
1341 1278 return RestApiPut(result, uri, writer.write(body), applyPlugins);
1342 // Parse the version of the Orthanc core 1279 }
1343 int aa, bb, cc; 1280
1344 if ( 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 1345 #ifdef _MSC_VER
1346 sscanf_s 1346 sscanf_s
1347 #else 1347 #else
1348 sscanf 1348 sscanf
1349 #endif 1349 #endif
1350 (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || 1350 (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 ||
1351 aa < 0 || 1351 aa < 0 ||
1352 bb < 0 || 1352 bb < 0 ||
1353 cc < 0) 1353 cc < 0)
1354 { 1354 {
1355 return false; 1355 return false;
1356 } 1356 }
1357 1357
1358 unsigned int a = static_cast<unsigned int>(aa); 1358 unsigned int a = static_cast<unsigned int>(aa);
1359 unsigned int b = static_cast<unsigned int>(bb); 1359 unsigned int b = static_cast<unsigned int>(bb);
1360 unsigned int c = static_cast<unsigned int>(cc); 1360 unsigned int c = static_cast<unsigned int>(cc);
1361 1361
1362 // Check the major version number 1362 // Check the major version number
1363 1363
1364 if (a > major) 1364 if (a > major)
1365 { 1365 {
1366 return true; 1366 return true;
1367 } 1367 }
1368 1368
1369 if (a < major) 1369 if (a < major)
1370 { 1370 {
1371 return false; 1371 return false;
1372 } 1372 }
1373 1373
1374 1374
1375 // Check the minor version number 1375 // Check the minor version number
1376 assert(a == major); 1376 assert(a == major);
1377 1377
1378 if (b > minor) 1378 if (b > minor)
1379 { 1379 {
1380 return true; 1380 return true;
1381 } 1381 }
1382 1382
1383 if (b < minor) 1383 if (b < minor)
1384 { 1384 {
1385 return false; 1385 return false;
1386 } 1386 }
1387 1387
1388 // Check the patch level version number 1388 // Check the patch level version number
1389 assert(a == major && b == minor); 1389 assert(a == major && b == minor);
1390 1390
1391 if (c >= revision) 1391 if (c >= revision)
1392 { 1392 {
1393 return true; 1393 return true;
1394 } 1394 }
1395 else 1395 else
1396 { 1396 {
1397 return false; 1397 return false;
1398 } 1398 }
1399 } 1399 }
1400 1400
1401 1401
1402 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) 1402 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0)
1403 const char* AutodetectMimeType(const std::string& path) 1403 const char* AutodetectMimeType(const std::string& path)
1404 { 1404 {
1405 const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str()); 1405 const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str());
1406 1406
1407 if (mime == NULL) 1407 if (mime == NULL)
1408 { 1408 {
1409 // Should never happen, just for safety 1409 // Should never happen, just for safety
1410 return "application/octet-stream"; 1410 return "application/octet-stream";
1411 } 1411 }
1412 else 1412 else
1413 { 1413 {
1414 return mime; 1414 return mime;
1415 } 1415 }
1416 } 1416 }
1417 #endif 1417 #endif
1418 1418
1419 1419
1420 #if HAS_ORTHANC_PLUGIN_PEERS == 1 1420 #if HAS_ORTHANC_PLUGIN_PEERS == 1
1421 size_t OrthancPeers::GetPeerIndex(const std::string& name) const 1421 size_t OrthancPeers::GetPeerIndex(const std::string& name) const
1422 { 1422 {
1423 size_t index; 1423 size_t index;
1424 if (LookupName(index, name)) 1424 if (LookupName(index, name))
1425 { 1425 {
1426 return index; 1426 return index;
1427 } 1427 }
1428 else 1428 else
1429 { 1429 {
1430 LogError("Inexistent peer: " + name); 1430 LogError("Inexistent peer: " + name);
1431 ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource); 1431 ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource);
1432 } 1432 }
1433 } 1433 }
1434 1434
1435 1435
1436 OrthancPeers::OrthancPeers() : 1436 OrthancPeers::OrthancPeers() :
1437 peers_(NULL), 1437 peers_(NULL),
1438 timeout_(0) 1438 timeout_(0)
1439 { 1439 {
1440 peers_ = OrthancPluginGetPeers(GetGlobalContext()); 1440 peers_ = OrthancPluginGetPeers(GetGlobalContext());
1441 1441
1442 if (peers_ == NULL) 1442 if (peers_ == NULL)
1443 { 1443 {
1444 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); 1444 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
1445 } 1445 }
1446 1446
1447 uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_); 1447 uint32_t count = OrthancPluginGetPeersCount(GetGlobalContext(), peers_);
1448 1448
1449 for (uint32_t i = 0; i < count; i++) 1449 for (uint32_t i = 0; i < count; i++)
1450 { 1450 {
1451 const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i); 1451 const char* name = OrthancPluginGetPeerName(GetGlobalContext(), peers_, i);
1452 if (name == NULL) 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)
1453 { 1466 {
1454 OrthancPluginFreePeers(GetGlobalContext(), peers_); 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);
1501 }
1502 else
1503 {
1504 return s;
1505 }
1506 }
1507 }
1508
1509
1510 std::string OrthancPeers::GetPeerUrl(size_t index) const
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)
1520 {
1521 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
1522 }
1523 else
1524 {
1525 return s;
1526 }
1527 }
1528 }
1529
1530
1531 std::string OrthancPeers::GetPeerUrl(const std::string& name) const
1532 {
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)
1549 {
1550 return false;
1551 }
1552 else
1553 {
1554 value.assign(s);
1555 return true;
1556 }
1557 }
1558 }
1559
1560
1561 bool OrthancPeers::LookupUserProperty(std::string& value,
1562 const std::string& peer,
1563 const std::string& key) const
1564 {
1565 return LookupUserProperty(value, GetPeerIndex(peer), key);
1566 }
1567
1568
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_)
1846 {
1847 return tmp.serialized_.c_str();
1848 }
1849 else
1850 {
1851 return NULL;
1852 }
1853 }
1854 catch (...)
1855 {
1856 return 0;
1857 }
1858 }
1859
1860
1861 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job)
1862 {
1863 assert(job != NULL);
1864
1865 try
1866 {
1867 return reinterpret_cast<OrthancJob*>(job)->Step();
1868 }
1869 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
1870 {
1871 return OrthancPluginJobStepStatus_Failure;
1872 }
1873 catch (...)
1874 {
1875 return OrthancPluginJobStepStatus_Failure;
1876 }
1877 }
1878
1879
1880 OrthancPluginErrorCode OrthancJob::CallbackStop(void* job,
1881 OrthancPluginJobStopReason reason)
1882 {
1883 assert(job != NULL);
1884
1885 try
1886 {
1887 reinterpret_cast<OrthancJob*>(job)->Stop(reason);
1888 return OrthancPluginErrorCode_Success;
1889 }
1890 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
1891 {
1892 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
1893 }
1894 catch (...)
1895 {
1896 return OrthancPluginErrorCode_Plugin;
1897 }
1898 }
1899
1900
1901 OrthancPluginErrorCode OrthancJob::CallbackReset(void* job)
1902 {
1903 assert(job != NULL);
1904
1905 try
1906 {
1907 reinterpret_cast<OrthancJob*>(job)->Reset();
1908 return OrthancPluginErrorCode_Success;
1909 }
1910 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
1911 {
1912 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
1913 }
1914 catch (...)
1915 {
1916 return OrthancPluginErrorCode_Plugin;
1917 }
1918 }
1919
1920
1921 void OrthancJob::ClearContent()
1922 {
1923 Json::Value empty = Json::objectValue;
1924 UpdateContent(empty);
1925 }
1926
1927
1928 void OrthancJob::UpdateContent(const Json::Value& content)
1929 {
1930 if (content.type() != Json::objectValue)
1931 {
1932 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat);
1933 }
1934 else
1935 {
1936 Json::FastWriter writer;
1937 content_ = writer.write(content);
1938 }
1939 }
1940
1941
1942 void OrthancJob::ClearSerialized()
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
1956 {
1957 Json::FastWriter writer;
1958 serialized_ = writer.write(serialized);
1959 hasSerialized_ = true;
1960 }
1961 }
1962
1963
1964 void OrthancJob::UpdateProgress(float progress)
1965 {
1966 if (progress < 0 ||
1967 progress > 1)
1968 {
1969 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange);
1970 }
1971
1972 progress_ = progress;
1973 }
1974
1975
1976 OrthancJob::OrthancJob(const std::string& jobType) :
1977 jobType_(jobType),
1978 progress_(0)
1979 {
1980 ClearContent();
1981 ClearSerialized();
1982 }
1983
1984
1985 OrthancPluginJob* OrthancJob::Create(OrthancJob* job)
1986 {
1987 if (job == NULL)
1988 {
1989 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer);
1990 }
1991
1992 OrthancPluginJob* orthanc = OrthancPluginCreateJob(
1993 GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(),
1994 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized,
1995 CallbackStep, CallbackStop, CallbackReset);
1996
1997 if (orthanc == NULL)
1998 {
1455 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); 1999 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
1456 } 2000 }
1457 2001 else
1458 index_[name] = i; 2002 {
1459 } 2003 return orthanc;
1460 } 2004 }
1461 2005 }
1462 2006
1463 OrthancPeers::~OrthancPeers() 2007
1464 { 2008 std::string OrthancJob::Submit(OrthancJob* job,
1465 if (peers_ != NULL) 2009 int priority)
1466 { 2010 {
1467 OrthancPluginFreePeers(GetGlobalContext(), peers_); 2011 OrthancPluginJob* orthanc = Create(job);
1468 } 2012
1469 } 2013 char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority);
1470 2014
1471 2015 if (id == NULL)
1472 bool OrthancPeers::LookupName(size_t& target, 2016 {
1473 const std::string& name) const 2017 LogError("Plugin cannot submit job");
1474 { 2018 OrthancPluginFreeJob(GetGlobalContext(), orthanc);
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); 2019 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
1501 } 2020 }
1502 else 2021 else
1503 { 2022 {
1504 return s; 2023 std::string tmp(id);
1505 } 2024 tmp.assign(id);
1506 } 2025 OrthancPluginFreeString(GetGlobalContext(), id);
1507 } 2026
1508 2027 return tmp;
1509 2028 }
1510 std::string OrthancPeers::GetPeerUrl(size_t index) const 2029 }
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)
1520 {
1521 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
1522 }
1523 else
1524 {
1525 return s;
1526 }
1527 }
1528 }
1529
1530
1531 std::string OrthancPeers::GetPeerUrl(const std::string& name) const
1532 {
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)
1549 {
1550 return false;
1551 }
1552 else
1553 {
1554 value.assign(s);
1555 return true;
1556 }
1557 }
1558 }
1559
1560
1561 bool OrthancPeers::LookupUserProperty(std::string& value,
1562 const std::string& peer,
1563 const std::string& key) const
1564 {
1565 return LookupUserProperty(value, GetPeerIndex(peer), key);
1566 }
1567
1568
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_)
1846 {
1847 return tmp.serialized_.c_str();
1848 }
1849 else
1850 {
1851 return NULL;
1852 }
1853 }
1854 catch (...)
1855 {
1856 return 0;
1857 }
1858 }
1859
1860
1861 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job)
1862 {
1863 assert(job != NULL);
1864
1865 try
1866 {
1867 return reinterpret_cast<OrthancJob*>(job)->Step();
1868 }
1869 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
1870 {
1871 return OrthancPluginJobStepStatus_Failure;
1872 }
1873 catch (...)
1874 {
1875 return OrthancPluginJobStepStatus_Failure;
1876 }
1877 }
1878
1879
1880 OrthancPluginErrorCode OrthancJob::CallbackStop(void* job,
1881 OrthancPluginJobStopReason reason)
1882 {
1883 assert(job != NULL);
1884
1885 try
1886 {
1887 reinterpret_cast<OrthancJob*>(job)->Stop(reason);
1888 return OrthancPluginErrorCode_Success;
1889 }
1890 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
1891 {
1892 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
1893 }
1894 catch (...)
1895 {
1896 return OrthancPluginErrorCode_Plugin;
1897 }
1898 }
1899
1900
1901 OrthancPluginErrorCode OrthancJob::CallbackReset(void* job)
1902 {
1903 assert(job != NULL);
1904
1905 try
1906 {
1907 reinterpret_cast<OrthancJob*>(job)->Reset();
1908 return OrthancPluginErrorCode_Success;
1909 }
1910 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
1911 {
1912 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
1913 }
1914 catch (...)
1915 {
1916 return OrthancPluginErrorCode_Plugin;
1917 }
1918 }
1919
1920
1921 void OrthancJob::ClearContent()
1922 {
1923 Json::Value empty = Json::objectValue;
1924 UpdateContent(empty);
1925 }
1926
1927
1928 void OrthancJob::UpdateContent(const Json::Value& content)
1929 {
1930 if (content.type() != Json::objectValue)
1931 {
1932 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat);
1933 }
1934 else
1935 {
1936 Json::FastWriter writer;
1937 content_ = writer.write(content);
1938 }
1939 }
1940
1941
1942 void OrthancJob::ClearSerialized()
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
1956 {
1957 Json::FastWriter writer;
1958 serialized_ = writer.write(serialized);
1959 hasSerialized_ = true;
1960 }
1961 }
1962
1963
1964 void OrthancJob::UpdateProgress(float progress)
1965 {
1966 if (progress < 0 ||
1967 progress > 1)
1968 {
1969 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange);
1970 }
1971
1972 progress_ = progress;
1973 }
1974
1975
1976 OrthancJob::OrthancJob(const std::string& jobType) :
1977 jobType_(jobType),
1978 progress_(0)
1979 {
1980 ClearContent();
1981 ClearSerialized();
1982 }
1983
1984
1985 OrthancPluginJob* OrthancJob::Create(OrthancJob* job)
1986 {
1987 if (job == NULL)
1988 {
1989 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer);
1990 }
1991
1992 OrthancPluginJob* orthanc = OrthancPluginCreateJob(
1993 GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(),
1994 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized,
1995 CallbackStep, CallbackStop, CallbackReset);
1996
1997 if (orthanc == NULL)
1998 {
1999 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
2000 }
2001 else
2002 {
2003 return orthanc;
2004 }
2005 }
2006
2007
2008 std::string OrthancJob::Submit(OrthancJob* job,
2009 int priority)
2010 {
2011 OrthancPluginJob* orthanc = Create(job);
2012
2013 char* id = OrthancPluginSubmitJob(GetGlobalContext(), orthanc, priority);
2014
2015 if (id == NULL)
2016 {
2017 LogError("Plugin cannot submit job");
2018 OrthancPluginFreeJob(GetGlobalContext(), orthanc);
2019 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin);
2020 }
2021 else
2022 {
2023 std::string tmp(id);
2024 tmp.assign(id);
2025 OrthancPluginFreeString(GetGlobalContext(), id);
2026
2027 return tmp;
2028 }
2029 }
2030 #endif 2030 #endif
2031 } 2031 }